# Deployment AzioneLab should deploy with a simple Docker Compose topology: - `nginx`: public reverse proxy and static frontend server; - `frontend`: Angular build source or build stage for static assets; - `backend`: Django 5.2 LTS application served by gunicorn; - `postgres`: PostgreSQL database. Only nginx should expose public ports. The backend and database should stay on the internal Compose network. The initial Compose setup is located at `infra/docker/compose.yml`. ## Services ### nginx Responsibilities: - listen on public HTTP and HTTPS ports; - serve built Angular files; - proxy `/api/` and `/admin/` requests to the backend; - serve static and media files according to the selected storage layout; - apply request size and timeout limits appropriate for booking and admin usage. Public ports: - `80` for HTTP; - `443` for HTTPS in production. ### frontend The frontend is an Angular application using Angular Material. Deployment options: - build the Angular app in a Docker build stage and copy static files into the nginx image; - or run a one-shot build container that writes static files to a shared volume consumed by nginx. The first option is preferred for a simple production deployment because nginx can serve immutable built assets without a long-running Node process. At the infrastructure placeholder stage, the `frontend` service serves a static placeholder page with nginx. The Angular build will replace this placeholder later. ### backend The backend is a Django application served by gunicorn. Responsibilities: - REST API; - Django admin; - booking, confirmation, QR generation, and check-in logic; - transactional capacity validation; - email sending. The backend should run database migrations before or during deployment through an explicit operational command, not as hidden startup magic unless that choice is documented later. The `backend` service runs gunicorn against the Django WSGI application. The current backend is an initial skeleton with Django admin, Django REST Framework, CORS configuration, the `shows`, `bookings`, and `checkins` apps, and a health endpoint. ### postgres PostgreSQL is the only database service. Responsibilities: - persistent application data; - reservation and check-in state; - transactional capacity enforcement. Use a named Docker volume for database data. ## Networks Recommended Compose networks: - `public`: nginx-facing network when needed; - `internal`: private network for nginx, backend, and db communication. The database should not be published to the host in production. ## Volumes Recommended volumes: - `postgres_data`: PostgreSQL data directory; - `media`: uploaded media and generated QR assets if stored on disk; - `static`: collected Django static files if served by nginx from a shared volume. Generated QR codes may also be generated on demand instead of stored as files. If stored, they must not reveal personal data and access must remain controlled. ## Configuration Copy `.env.example` to `.env` and replace all placeholder values before running or deploying the stack. Required backend configuration: - `DJANGO_SECRET_KEY`; - `DJANGO_ALLOWED_HOSTS`; - `DJANGO_CSRF_TRUSTED_ORIGINS`; - `CORS_ALLOWED_ORIGINS`; - `TIME_ZONE`; - `DATABASE_URL` or equivalent database settings; - email host, port, username, password, TLS settings, and sender address; - public site URL used to build confirmation and QR verification links. Local Docker convention: - use nginx as the public entrypoint at `http://localhost`; - set `SITE_BASE_URL=http://localhost`; - keep `DJANGO_CSRF_TRUSTED_ORIGINS` and browser-facing `CORS_ALLOWED_ORIGINS` aligned with that public URL; - if you publish nginx on a different port, update `SITE_BASE_URL` and trusted origins to the same host and port. Required database configuration: - database name; - database user; - database password; - data volume path. Required nginx configuration: - upstream backend service name and port; - static frontend root; - proxy rules for `/api/` and `/admin/`; - TLS certificate paths for production. Secrets must be provided through deployment-managed environment variables, Docker secrets, or another secret manager. Do not commit real secret values. ## Example Request Routing ```text Visitor browser -> nginx -> Angular static files -> /api/ requests proxied to backend:gunicorn -> /admin/ requests proxied to backend:gunicorn Backend -> PostgreSQL -> SMTP provider ``` ## Deployment Commands The exact commands will be finalized when application code and Compose files are added. Expected production-style flow: ```bash docker compose --env-file .env -f infra/docker/compose.yml build docker compose --env-file .env -f infra/docker/compose.yml run --rm backend python manage.py migrate docker compose --env-file .env -f infra/docker/compose.yml run --rm backend python manage.py collectstatic --noinput docker compose --env-file .env -f infra/docker/compose.yml up -d ``` Expected validation commands: ```bash docker compose --env-file .env.example -f infra/docker/compose.yml config docker compose --env-file .env.example -f infra/docker/compose.yml run --rm --build backend python manage.py test docker compose --env-file .env -f infra/docker/compose.yml run --rm backend python manage.py check --deploy docker compose --env-file .env -f infra/docker/compose.yml run --rm backend python manage.py test ``` The canonical repository check for the current stage is: ```bash docker compose --env-file .env.example -f infra/docker/compose.yml config docker compose --env-file .env.example -f infra/docker/compose.yml run --rm --build backend python manage.py test ``` ## Rollback Rollback should be designed around immutable images and database backups. Basic rollback steps: 1. identify the previous known-good image tags or Git commit; 2. stop the current Compose stack; 3. deploy the previous image tags or commit; 4. restore the database from backup only if a migration or data change requires it; 5. run smoke checks for public pages, booking creation, confirmation, and check-in. Database rollback needs special care once migrations exist. Down migrations or backup restore procedures should be documented before production use. ## Operational Notes - Configure database backups before accepting real bookings. - Monitor backend errors, email delivery failures, and check-in failures. - Keep container images explicitly versioned; do not use `latest` tags. - Keep the system small until operational needs justify additional services.