Files
2026-06-24 11:06:33 +02:00

4.1 KiB

Deployment

Local environment

Copy .env.example to .env, replace the development placeholders, then run:

cp .env.example .env
docker compose up --build -d
docker compose ps
docker compose exec backend python manage.py seed_demo

The backend applies migrations and collects static files before starting Gunicorn. All services have health checks; wait for healthy status before opening the site.

Add 127.0.0.1 azionelab.org to the local hosts file, then use http://azionelab.org:8080. NGINX binds to loopback port 8080 by default and routes the domain to Astro or Wagtail. Their direct loopback ports 4321 and 8000 remain available for diagnostics. PostgreSQL is available only on the Compose network. postgres_data and media_data are persistent named volumes. Local HTTPS is disabled by default; letsencrypt_data and certbot_challenges remain empty unless used.

The stack uses explicit PostgreSQL 16.9, Python 3.12.12, Node.js 22.20, and NGINX 1.30.0 image versions. Containers are not privileged and use no-new-privileges.

Required runtime variables are DATABASE_URL, DJANGO_SECRET_KEY, DJANGO_DEBUG, DJANGO_ALLOWED_HOSTS, WAGTAILADMIN_BASE_URL, PUBLIC_CMS_API_URL, NGINX_BIND_ADDRESS, NGINX_HTTP_PORT, and NGINX_HTTPS_PORT. The optional certificate variables and PostgreSQL bootstrap variables are documented in .env.example. Do not use the example credentials outside local development.

WAGTAILADMIN_BASE_URL must be browser-reachable because it is used for media URLs. PUBLIC_CMS_API_URL must be reachable by Astro; within Compose it is http://backend:8000.

The PostgreSQL Compose service is db, so new DATABASE_URL values use db:5432. The internal postgres alias is retained only for compatibility with existing local .env files and should not be used in new configuration.

TLS deployment modes

When an external load balancer terminates TLS, leave LETSENCRYPT_ENABLED=0. The certbot service then has zero replicas and NGINX serves HTTP to the trusted internal network. Configure the load balancer to set X-Forwarded-Proto: https, keep application ports private, and restrict proxy access to the load balancer network.

For direct exposure, the HTTP-01 challenge requires public DNS for LETSENCRYPT_DOMAIN to resolve to this host and inbound TCP ports 80 and 443 to reach NGINX. Use a real operator address and production-safe Django settings:

LETSENCRYPT_ENABLED=1
LETSENCRYPT_DOMAIN=azionelab.org
LETSENCRYPT_EMAIL=operator@example.org
LETSENCRYPT_STAGING=1
NGINX_BIND_ADDRESS=0.0.0.0
NGINX_HTTP_PORT=80
NGINX_HTTPS_PORT=443
WAGTAILADMIN_BASE_URL=https://azionelab.org
DJANGO_DEBUG=false
DJANGO_ALLOWED_HOSTS=azionelab.org

Then run docker compose up --build -d and inspect docker compose logs certbot proxy. NGINX serves HTTP until a certificate exists, then reloads and redirects normal HTTP requests to HTTPS. The ACME path remains available over HTTP for renewal.

Use the Let's Encrypt staging CA first. Before switching to the production CA, stop the stack and remove only the staging certificate volume after checking its exact Compose project name:

docker compose down
docker volume ls --filter label=com.docker.compose.volume=letsencrypt_data
docker volume rm PROJECT_letsencrypt_data

Set LETSENCRYPT_STAGING=0, restart, and verify the certificate issuer in a browser or TLS inspection tool. Never use docker compose down --volumes on an environment whose database, media, or certificates must be retained.

Production boundary

The Compose stack remains a minimal deployment base. A public environment still needs production static/media serving, restricted admin access, managed secrets, off-host backups, monitoring, firewall rules, and an explicit domain/allowed-host policy.

Rollback

Set LETSENCRYPT_ENABLED=0 to disable the certificate service without deleting certificates, or terminate TLS at the load balancer. Revert the application commit and rebuild images for a full rollback. Keep database, media, and certificate volumes unless deletion is intentional. Schema rollback must be evaluated per Django migration; take coordinated database and media backups first.