<@ULVA73B9P> how to deploy prefect-api and prefect...
# ask-marvin
k
@Marvin how to deploy prefect-api and prefect-ui in azure container apps
m
thought for 466.7 seconds
Great question. In Prefect 3.x, the API and UI run together in a single server process. You only deploy one container to Azure Container Apps (ACA); it serves: - /api/* for the REST API - / for the UI - /api/health for health checks Below is a concise, production-ready path to get you running on ACA. Assumptions - Prefect 3.x - Azure Container Apps with external ingress (managed TLS) - PostgreSQL (Azure Database for PostgreSQL Flexible Server) - Optional: Basic auth on the API - Workers will run separately and connect to your ACA endpoint High-level steps 1) Create Azure resources (RG + ACA environment) 2) Create or point to a PostgreSQL database 3) Deploy Prefect server container to ACA 4) Set the UI to point to your external /api endpoint 5) Run DB migrations once (then scale if needed) 6) Point workers at your ACA endpoint Key environment variables - Database - PREFECT_API_DATABASE_CONNECTION_URL=postgresql+asyncpg://user:pass@host:5432/dbname[?sslmode=require] - Server network - PREFECT_SERVER_API_HOST=0.0.0.0 - PREFECT_SERVER_API_PORT=4200 - UI (what the browser uses to call your API) - PREFECT_UI_API_URL=https://<your-aca-fqdn>/api - Optional Basic Auth (protect the API/UI) - PREFECT_SERVER_API_AUTH_STRING="admin:VeryStrongPassword" - Optional CORS (if your UI/API are accessed cross-origin) - PREFECT_SERVER_CORS_ALLOWED_ORIGINS="https://yourdomain.com" Quick deploy with Azure CLI Note: if you don’t have a Postgres yet, the first block shows an example. If you already have one, skip to step 3 and configure the connection URL accordingly.
Copy code
# 1) Resource group + ACA env
RG=prefect-rg
LOCATION=eastus
ENV_NAME=prefect-env
APP_NAME=prefect-server

az group create --name $RG --location $LOCATION

az containerapp env create \
  --name $ENV_NAME \
  --resource-group $RG \
  --location $LOCATION

# 2) (Optional) Create PostgreSQL Flexible Server
# Replace passwords, sizing, and version to your standards
PG_SERVER=prefect-db-$RANDOM
PG_USER=prefect
PG_PASS='UseASecurePassword123!'
PG_DB=prefect

az postgres flexible-server create \
  --name $PG_SERVER \
  --resource-group $RG \
  --location $LOCATION \
  --admin-user $PG_USER \
  --admin-password $PG_PASS \
  --sku-name Standard_B2s \
  --storage-size 32 \
  --version 15

# Connection string (Azure Postgres requires SSL by default; include sslmode if needed)
DB_URL="postgresql+asyncpg://${PG_USER}:${PG_PASS}@${PG_SERVER}.<http://postgres.database.azure.com:5432/${PG_DB}?sslmode=require|postgres.database.azure.com:5432/${PG_DB}?sslmode=require>"

# 3) Deploy Prefect server to ACA
# Explicitly start the server on 0.0.0.0:4200
az containerapp create \
  --name $APP_NAME \
  --resource-group $RG \
  --environment $ENV_NAME \
  --image prefecthq/prefect:3-latest \
  --command "prefect server start --host 0.0.0.0 --port 4200" \
  --target-port 4200 \
  --ingress external \
  --cpu 2 \
  --memory 4Gi \
  --min-replicas 1 \
  --max-replicas 3 \
  --env-vars \
    PREFECT_API_DATABASE_CONNECTION_URL="$DB_URL" \
    PREFECT_SERVER_API_HOST="0.0.0.0" \
    PREFECT_SERVER_API_PORT="4200" \
    PREFECT_SERVER_API_AUTH_STRING="admin:AdminPassword123!"

# 4) Discover your ACA FQDN and point the UI at /api
FQDN=$(az containerapp show \
  --name $APP_NAME \
  --resource-group $RG \
  --query properties.configuration.ingress.fqdn -o tsv)

# Set PREFECT_UI_API_URL so the UI JS calls the right API endpoint
az containerapp update \
  --name $APP_NAME \
  --resource-group $RG \
  --set-env-vars PREFECT_UI_API_URL="https://${FQDN}/api"

echo "Prefect UI: https://${FQDN}"
echo "API URL:    https://${FQDN}/api"

# 5) Run DB migrations once (especially before scaling beyond 1 replica)
az containerapp exec \
  --name $APP_NAME \
  --resource-group $RG \
  --command "prefect server database upgrade -y"

# 6) (Optional) If using a custom domain, add it in ACA, then set PREFECT_UI_API_URL to that domain’s /api
# e.g. PREFECT_UI_API_URL=<https://prefect.yourdomain.com/api>
Health checks and scaling - Health endpoint: /api/health (HTTP 200 when healthy)
- In ACA, you can add readiness/liveness probes via your IaC (Bicep/ARM/Terraform). Use /api/health. - Start with 2 CPU / 4Gi RAM. Scale replicas based on load once stable. - For HA (multiple replicas), run the database upgrade once, then scale. How workers connect - Workers run separately (on VMs, ACA, ACI, Kubernetes, etc.). - Point them at your ACA API:
Copy code
export PREFECT_API_URL="https://<your-aca-fqdn>/api"
# If you set Basic Auth on the server:
export PREFECT_API_AUTH_STRING="admin:AdminPassword123!"

prefect worker start --pool my-pool
Notes and best practices - Only one container is needed; Prefect serves the UI and API together on port 4200. - Do not set PREFECT_API_URL in the server container; that’s for clients/workers. - Store passwords in ACA secrets rather than plain env vars (the CLI above shows env vars for brevity). - Azure Postgres typically enforces SSL; append sslmode=require (or equivalent) to your DB URL if needed. - Use managed TLS via ACA external ingress. Set PREFECT_UI_API_URL with https://<fqdn>/api. - If you serve the UI/API under a subpath via a reverse proxy, set PREFECT_UI_API_URL accordingly and ensure the proxy routes / and /api/*. Want me to tailor this for your environment? - Do you already have a PostgreSQL server you want to use? - Single replica (dev) or multi-replica (HA) to start? - Do you want to enable HTTP Basic Auth on the API now?