Python Cloud Advocate at Microsoft
Formerly: UC Berkeley, Coursera, Khan Academy, Google
Find Pamela online at:
Mastodon | @pamelafox@fosstodon.org |
@pamelafox | |
GitHub | www.github.com/pamelafox |
Website | pamelafox.org |
To follow along with the live coding, your options are:
The Docker engine runs multiple Docker containers, where each container is an isolated environment.
Each container can be a very different environment, with binaries and libraries dependent on the application.
A container image is a software package that includes
everything needed to run an application.
A container is a running instance of a container image.
Multiple containers can be run from the same image.
A registry is a place to store and share images.
Commonly used image registries:
A container image often starts off with a base image, and then adds layers on top of it.
For example:
Docker can cache each layer, which improves performance.
A Dockerfile includes:
The base or parent image* | FROM python:3.12
|
Additional software | RUN pip3 install Flask gunicorn
|
Application code | WORKDIR /code COPY . .
|
Services to expose (storage/network) | EXPOSE 50505
|
Command to run upon launching container | ENTRYPOINT ["gunicorn", "-c", "gunicorn.conf.py", "app:app"]
|
*Find existing images in registries, like DockerHub.
From this repo:
github.com/pamelafox/simple-flask-server-container
aka.ms/flask-container
A complete file:
FROM python:3.12
WORKDIR /code
COPY requirements.txt .
RUN pip3 install -r requirements.txt
COPY . .
EXPOSE 50505
ENTRYPOINT ["gunicorn", "-c", "gunicorn.conf.py", "app:app"]
📖 Learn more: Docker images layer and cache
Prevent unnecessary files from being copied to the image:
.git*
.venv/
**/*.pyc
__pycache__/
Using the docker build
command:
docker build --tag flaskapp .
Using the VS Code Docker extension
:
Using the docker run
command:
docker run --publish 50505:50505 flaskapp
Using Docker Desktop:
You can also use the VS Code Docker extension to run containers.
Starting from this repo:
github.com/pamelafox/simple-flask-server-container
From this repo:
github.com/pamelafox/flask-surveys-container-app
aka.ms/flask-db-container
@app.route('/surveys', methods=['GET'])
def surveys_list_page():
surveys = Survey.query.all()
return render_template('surveys_list.html', surveys=surveys)
@app.route('/surveys/', methods=['GET'])
def survey_page(survey_id):
survey = Survey.query.where(Survey.id == survey_id).first()
answers = Survey.query.where(Answer.survey==survey_id)
return render_template('survey_details.html', survey=survey, answers=answers, already_voted='survey_id' in request.cookies)
👀 Demo: aka.ms/live-survey-app
Data can be written to a container's file system, but:
If you need to persist data, you should store it outside the container.
A volume is a directory on the host machine that is mapped to a directory in the container.
When developing with databases locally, use a volume to store the data for the database.
Create a volume:
docker volume create postgres-data
Create a network for the containers to communicate over:
docker network create postgres-net
Run a PostgreSQL container with the volume and network:
docker run --rm -d -v postgres-data:/var/lib/postgresql/data \
--network postgres-net --name db \
-e POSTGRES_USER=app_user -e POSTGRES_PASSWORD=app_password \
postgres
Inside src
folder, make .env
for the database connection:
DBHOST=db
DBNAME=postgres
DBUSER=app_user
DBPASS=app_password
Inside src
folder, build the container:
docker build --tag flasksurveyscontainerapp .
Run the app container over the same network:
docker run --rm --network postgres-net \
--name flask-db-app -p 50505:50505 \
flasksurveyscontainerapp
Docker compose is a tool for defining and running multi-container Docker apps,
and docker-compose.yaml
is a YAML file that defines the services that make up your app.
services:
db:
image: postgres
restart: always
environment:
POSTGRES_PASSWORD: ${DBPASS:?database password not set}
POSTGRES_USER: ${DBUSER:?database user not set}
POSTGRES_DB: ${DBNAME:?database name not set}
volumes:
- postgres-data:/var/lib/postgresql/data
networks:
- postgres-net
app:
build:
context: .
ports:
- 50505:50505
networks:
- postgres-net
volumes:
postgres-data:
networks:
postgres-net:
In the root folder, copy the .env
file from src/.env
From the root folder, run the app and database containers:
docker-compose up
📖 Learn more: docker compose up reference
Using this repo:
github.com/pamelafox/flask-surveys-container-app
aka.ms/flask-db-container
entrypoint
in docker-compose.yaml
to entrypoint.sh
instead, and re-run docker compose up
.
It should no longer reload when Python files change.
Cloud | Azure | |||
---|---|---|---|---|
Environment | Containers | PaaS | ||
Azure Kubernetes Service | Container Management | Azure App Service | Serverless | |
Azure Container Apps | Azure Functions |
All offerings let developers bring containers!
Azure Container Apps is a recent offering that is optimized for running containers.
For temporary storage, you can write to file system or have an ephemeral volume in a container app.
For permanent storage, you can mount Azure Files but performance is too limited to be useful for a database.
These are just some of the options:
Option | Description |
---|---|
Azure CosmosDB | Distributed DB with multiple APIs, including NoSQL, MongoDB and Cassandra. |
Azure Cosmos DB for PostgreSQL | Distributed DB using PostgreSQL and Citus extension. Scales vertically and horizontally. |
Azure Database for PostgreSQL – Flexible Server | Fully managed service with vertical scaling. |
A Container Apps Environment manages a Container App which pulls its image from an Azure Container Registry.
The Container App connects with the PostgreSQL server over the internal Azure network.
Using the Azure Developer CLI:
Starting from this repo:
github.com/pamelafox/flask-surveys-container-app
aka.ms/flask-db-container
azd auth login
azd up
azd down
to un-deploy the app.
Repo | Description |
---|---|
simple-fastapi-container | FastAPI app with a single endpoint |
flask-charts-api-container-app | Container Apps + CDN |
flask-gallery-container-app | Container Apps + CDN |
Framework | PostgreSQL Flexible | CosmosDB for PostgreSQL | PostgreSQL Container Apps Addon | CosmosDB for MongoDB |
---|---|---|---|---|
Django | Repo | Repo | Repo | - |
FastAPI | Repo | Repo | Repo | - |
Flask | Repo | Repo | Repo | Repo |
All generated from Azure Python Standardized Template Generator (cookiecutter project)
Repo | Description |
---|---|
openai-chat-backend-fastapi | FastAPI + OpenAI (Backend only) |
openai-chat-app-quickstart | Quart + OpenAI (Full-stack) |
openai-chat-app-entra-auth-builtin | OpenAI + Entra (ACA Built-in auth) |
openai-chat-app-entra-auth-local | OpenAI + Entra + Azure Redis |
langfuse-on-azure | Langfuse image + PostgreSQL |