shareyourthoughtswith.me

Deployment

The reference deployment target for Share Your Thoughts With Me is Azure Container Apps with a managed Postgres Flexible Server alongside. The ACA ingress is the only reverse proxy in the stack: it terminates TLS, manages the custom-domain certificates for shareyourthoughtswith.me and sytw.me, and forwards plain HTTP to the app container on port 8000. No additional nginx/Caddy container is required.

High-level topology

Provisioning

Infrastructure lives in infra/terraform/. Apply it once per environment:

cd infra/terraform
terraform init \
  -backend-config="subscription_id=<state-storage-sub>" \
  -backend-config="resource_group_name=<state-rg>" \
  -backend-config="storage_account_name=<state-sa>"
terraform apply -var-file=env/prod.tfvars -var-file=env/prod.secrets.tfvars

Subsequent app deploys are CI-driven via the Jenkinsfile in the repo root and do not run Terraform.

Operator handoff steps after first apply

  1. Bind shareyourthoughtswith.me and sytw.me to the Container App's managed certificate (Terraform issues the binding; the cert is provisioned asynchronously by ACA — verify with az containerapp hostname list).
  2. Confirm the Container App's environment variables (SYTWM_*) are wired to the corresponding Key Vault secrets.
  3. Run the first deploy via Jenkins or manually: az containerapp update --name sytwm-app --image <acr>.azurecr.io/sytwm:<tag>
  4. Verify health at https://shareyourthoughtswith.me/health.

Local development

docker compose up spins up a local Postgres and the app:

cp .env.example .env
docker compose up --build
# App at http://localhost:8000

Run tests outside Docker:

uv sync --all-extras
uv run pytest

CI/CD

The Jenkinsfile follows the gold-standard pattern: it infers DEPLOY_ENV from the job name, reads Azure IDs from infra/terraform/env/<env>.json, builds and pushes to ACR via scripts/build.sh, runs migrations via scripts/run-migrations.sh, deploys via scripts/deploy.sh, and verifies via the Health Check stage.