Azure Container Apps Reference

Commands, customization, environment variables, and troubleshooting for the Azure Container Apps template.

The deploy scripts put everything in one resource group, agentos by default, and the container app is named agent-os. Override the group and region with AZURE_RESOURCE_GROUP and AZURE_LOCATION (default eastus).

Manage

For a custom resource group, export AZURE_RESOURCE_GROUP before every lifecycle command, including teardown. up.sh reads it from the env file, but the other scripts resolve the shell value or default to agentos. Use the same group in diagnostic az commands.

export AZURE_RESOURCE_GROUP=my-agentos  # use your deployed resource group
TaskCommand
Deploy code changes./scripts/azure/redeploy.sh
Sync env variables./scripts/azure/env-sync.sh (defaults to .env.production; pass .env to sync that instead)
Tail logsaz containerapp logs show -g agentos -n agent-os --follow
Tear down./scripts/azure/down.sh (add --yes to skip the confirmation)

env-sync.sh turns secret-shaped keys (OPENAI_API_KEY, DB_PASS, JWT_VERIFICATION_KEY, MCP_CONNECT_SECRET, AGENTOS_MCP_SIGNING_KEY, PARALLEL_API_KEY, SLACK_*) into Container Apps secrets and everything else into plain env vars, then applies it all in one revision roll. It skips AZURE_* keys; those configure the scripts, not the app.

The app is pinned to one replica (--min-replicas 1 --max-replicas 1). Min 1 keeps the in-process scheduler and MCP streams alive; max 1 is the template’s scaling default. Postgres coordinates due-schedule claims across workers; this setting does not imply that multiple replicas inherently double every scheduled run.

Production auth

Token-Based Authorization is on by default. Production startup requires JWT_VERIFICATION_KEY or a readable JWKS file at the container path in JWT_JWKS_FILE; otherwise the process exits.

Token-Based Auth gives you three things:

  1. Protected runtime access. Protected API routes require a valid credential. Health, discovery, and API documentation remain public; Slack and MCP OAuth have their own authentication flows.
  2. Per-request identity. Middleware validates the token and exposes its user_id, optional session_id, scopes, and claims to the request.
  3. Scope-based permissions. Token scopes control access to AgentOS routes and resources.

The template already sets AuthorizationConfig(user_isolation=True). Authenticated non-admin REST access is scoped to the principal; local dev mode disables scope enforcement and is open when no credentials are configured. This does not scope Platform Manager’s direct database tools to that REST identity. See User Isolation for the boundaries and admin exceptions.

To disable JWT authentication in a private deployment with another auth layer, set authorization=False, remove JWT_VERIFICATION_KEY and JWT_JWKS_FILE from the running service, and rebuild or redeploy the app as needed. Disabling scope enforcement alone does not remove JWT validation while those credentials remain configured. MCP OAuth remains enabled while MCP_CONNECT_SECRET is set.

Customize

Format, validate, and run evals

Run evals against a dedicated local test platform with no concurrent writers. The starter’s cleanup hooks remove components and learning state created during a case; concurrent application writes can be removed too. The same prerequisite applies to scheduled evals. See eval setup and isolation.

The host scripts require uv. The setup script creates a Python 3.14 venv:

./scripts/venv_setup.sh
source .venv/bin/activate
TaskCommand
Format./scripts/format.sh
Lint and type-check./scripts/validate.sh
Run smoke evalspython -m evals --tag smoke

./scripts/mcp_check.sh runs inside the container, so it needs no venv.

Environment variables

Initial provisioning forwards a selected set of bootstrap values. After deployment, apply custom AGENTOS_MCP_SIGNING_KEY, ENABLE_DEPLOY_CHECK, and EVALS_* settings with ./scripts/azure/env-sync.sh. The table describes runtime support, not a promise that up.sh forwards every setting.

VariableRequiredDefaultDescription
OPENAI_API_KEYYes-Models and embeddings.
RUNTIME_ENVNoprddev disables scope enforcement; configured JWT credentials still enable token validation. Compose sets it for local. Keep production on prd so scope enforcement remains enabled.
JWT_VERIFICATION_KEYProduction-Public key from os.agno.com. Quote the value so the multi-line PEM parses as one variable.
JWT_JWKS_FILEProduction-Path inside the running container to a JWKS JSON file. The scripts set only this path. Add the file to the image build context, rebuild, and redeploy the image, or configure a platform mount and roll the service.
MCP_CONNECT_SECRETNogenerated by up.shOAuth consent secret (16+ chars) for connecting claude.ai and ChatGPT to /mcp. up.sh generates one on deploy and writes it to .env.production.
AGENTOS_MCP_SIGNING_KEYNogeneratedOptional high-entropy signing-key material (32+ chars) for OAuth tokens. Unset, a strong key is generated and persisted in the database. Rotating it invalidates outstanding tokens.
AGENTOS_URLNohttp://127.0.0.1:8000Scheduler base URL. up.sh sets it to your Container Apps URL. Loopback reaches the app inside this container; set the public URL for hosted MCP OAuth and the template’s deployment check. When MCP_CONNECT_SECRET is set, OAuth metadata also derives its public origin from this URL.
ENABLE_DEPLOY_CHECKNoTrueDaily deployment-check cron.
EVALS_TAGNosmokeEval tag the run-evals workflow runs.
EVALS_CASE_TIMEOUT_SECONDSNo90Fallback timeout for cases without an explicit timeout.
EVALS_SUITE_TIMEOUT_SECONDSNoderived from selected casesSum of selected case timeouts plus 30 seconds per case, with a 60-second floor. A positive integer overrides this ceiling.
PARALLEL_API_KEYNo-WebSearch uses the Parallel SDK when set, keyless MCP otherwise.
SLACK_BOT_TOKENNo-Set with the signing secret to enable Slack.
SLACK_SIGNING_SECRETNo-Set with the bot token to enable Slack.
DB_HOST / DB_PORT / DB_USER / DB_PASS / DB_DATABASENomatches composePostgres connection. up.sh wires them to the Flexible Server.
DB_DRIVERNopostgresql+psycopgSQLAlchemy driver.
AGNO_DEBUGNoFalseVerbose Agno logs. Compose sets it for dev.
WAIT_FOR_DBNoFalseIf True, the entrypoint blocks on the database before starting. Compose sets it.
AZURE_RESOURCE_GROUPNoagentosResource group every deploy script targets. Never synced to the app.
AZURE_LOCATIONNoeastusRegion for the first up.sh run. Never synced to the app.
AZURE_ACR_NAMENogenerated by up.shRegistry name. Minted once and saved to your env file so re-runs reuse it.
AZURE_PG_NAMENogenerated by up.shPostgres server name. Minted once and saved to your env file so re-runs reuse it.

up.sh also generates DB_PASS once and saves it to your env file. Don't regenerate it; the server keeps the first password, and a new one would lock the app out.

Troubleshooting