Skip to content

01 - Run Locally with Docker

Before deploying to Azure Container Apps, validate your Python app in a container locally. This catches image, dependency, and port issues early.

Infrastructure Context

Service: Container Apps (Consumption) | Network: VNet integrated | VNet: ✅

This tutorial assumes a production-ready Container Apps deployment with a custom VNet, ACR with managed identity pull, and private endpoints for backend services.

flowchart TD
    INET[Internet] -->|HTTPS| CA["Container App\nConsumption\nLinux Python 3.11"]

    subgraph VNET["VNet 10.0.0.0/16"]
        subgraph ENV_SUB["Environment Subnet 10.0.0.0/23\nDelegation: Microsoft.App/environments"]
            CAE[Container Apps Environment]
            CA
        end
        subgraph PE_SUB["Private Endpoint Subnet 10.0.2.0/24"]
            PE_ACR[PE: ACR]
            PE_KV[PE: Key Vault]
            PE_ST[PE: Storage]
        end
    end

    PE_ACR --> ACR[Azure Container Registry]
    PE_KV --> KV[Key Vault]
    PE_ST --> ST[Storage Account]

    subgraph DNS[Private DNS Zones]
        DNS_ACR[privatelink.azurecr.io]
        DNS_KV[privatelink.vaultcore.azure.net]
        DNS_ST[privatelink.blob.core.windows.net]
    end

    PE_ACR -.-> DNS_ACR
    PE_KV -.-> DNS_KV
    PE_ST -.-> DNS_ST

    CA -.->|System-Assigned MI| ENTRA[Microsoft Entra ID]
    CAE --> LOG[Log Analytics]
    CA --> AI[Application Insights]

    style CA fill:#107c10,color:#fff
    style VNET fill:#E8F5E9,stroke:#4CAF50
    style DNS fill:#E3F2FD

Local Development Workflow

graph TD
    CODE[Source Code] --> BUILD[Docker Build]
    BUILD --> CONT[Container]
    CONT --> LOCAL[localhost:8000]
    LOCAL --> HEALTH[Health Check]

Prerequisites

  • Docker Engine or Docker Desktop
  • Source code with a Dockerfile

Aim for local-cloud parity

Keep local container port mapping and environment variable names aligned with your Azure deployment settings. This reduces revision failures caused by mismatched runtime assumptions.

Step-by-step

  1. Build the container image
cd app
docker build --tag aca-python-guide .

???+ example "Expected output"

[1/6] FROM docker.io/library/python:3.11-slim
[2/6] WORKDIR /app
[3/6] COPY requirements.txt .
[4/6] RUN pip install --no-cache-dir -r requirements.txt
[5/6] COPY . .
[6/6] CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "--chdir", "src", "app:app"]
Successfully tagged aca-python-guide:latest

  1. Run the container locally
# Copy and customize the environment file
cp .env.example .env

docker run --publish 8000:8000 --env-file .env aca-python-guide

???+ example "Expected output"

[2026-04-04 11:30:54 +0000] [1] [INFO] Starting gunicorn 25.3.0
[2026-04-04 11:30:54 +0000] [1] [INFO] Listening at: http://0.0.0.0:8000 (1)
[2026-04-04 11:30:54 +0000] [8] [INFO] Booting worker with pid: 8

  1. Verify health endpoint
curl http://localhost:8000/health

???+ example "Expected output"

{"status":"healthy","timestamp":"2026-04-04T11:32:37.322216+00:00"}

You can also verify runtime metadata:

curl http://localhost:8000/info

???+ example "Expected output"

{"containerApp":"<your-app-name>","environment":"development","name":"azure-container-apps-practical-guide","python":"3.11.15","revision":"<your-app-name>--xxxxxxx","telemetryMode":"basic","version":"1.0.0"}

  1. Inspect application logs
docker logs <container-id>

???+ example "Expected output"

Starting application...
PORT=8000
[INFO] Starting gunicorn 25.3.0

To find the container ID: docker ps

Local parity checklist

  • Application listens on port 8000 (or your configured container port)
  • Required environment variables are present
  • /health returns HTTP 200
  • No startup exceptions in container logs

Do not commit local secret files

If you create a local .env file for testing, keep sensitive values out of source control and use placeholder values in shared examples.

Advanced Topics

  • Add local Redis or PostgreSQL via docker network and separate containers to mimic service dependencies.
  • Use OpenTelemetry locally to validate logs and traces before cloud deployment.
  • Add a Dapr sidecar for local service invocation testing.

Review Matrix

Review area Page-specific check
Scope Confirm the guidance applies to 01 - Run Locally with Docker.
Source basis Validate the recommendation against the Microsoft Learn sources in this page.
Evidence Capture command output, portal state, metrics, logs, or screenshots before treating the result as proven.

See Also

Sources