Docker Install Automation — Design
Date: 2026-03-26
Problem
The Docker Compose deployment path is fully documented (Deployment.md) but entirely manual: the user clones, edits .env, runs docker compose build, docker compose up -d, and verifies health by hand. The existing bin/install.sh automates dev and prod (bare-metal) modes but has zero Docker awareness.
Goal
Extend the installation tooling so that ./bin/install.sh offers a docker mode that automates the full Docker Compose deployment — from .env setup through health-verified running containers. Docker Engine is a hard prerequisite (not installed by the script).
Design
Mode Selection (install.sh changes)
The existing mode prompt changes from dev / prod to dev / prod / docker:
Select installation mode:
1) dev — local development (DEBUG=1, eager tasks)
2) prod — bare-metal production (systemd, gunicorn)
3) docker — Docker Compose stack (requires Docker running)
When docker is selected:
- Hard-fail if Docker daemon isn’t running. Print: “Docker is required. Install it from https://docs.docker.com/get-docker/ and ensure the daemon is running.”
- Prompt
DJANGO_DEBUG(default1) - Prompt
DJANGO_SECRET_KEY(offer auto-generate) - Prompt
DJANGO_ALLOWED_HOSTS(defaultlocalhost,127.0.0.1) - Skip
CELERY_BROKER_URLprompt (Compose overrides it to internal Redis) - Skip Python/uv checks, dependency installation, migrations (all happen inside containers)
- Write
.env, delegate tobin/deploy-docker.sh
No dev/prod sub-menu within docker mode — the user’s answers to the security questions determine the posture (DEBUG=1 for local, DEBUG=0 + real ALLOWED_HOSTS for production).
New Script: bin/deploy-docker.sh
Standalone script called from install.sh or run directly.
1. Pre-flight checks:
.envexists — if not, print “Run./bin/install.shfirst” and exit- Docker daemon is running — hard fail with install link
docker compose(v2) available — fail if only legacydocker-composev1
2. Build & start:
docker compose -f deploy/docker/docker-compose.yml builddocker compose -f deploy/docker/docker-compose.yml up -d
3. Health verification (timeout 60s, poll every 5s):
- redis:
docker compose exec redis redis-cli ping— expects PONG - web: container running + not in restart loop
- celery: container running + not in restart loop
- Print pass/fail per service, exit 1 if any fail
4. Summary output:
- Print running service URLs
- Print useful commands:
docker compose logs -f,docker compose down,docker compose ps
Changes to Existing Files
bin/install.sh— Adddockeras mode 3. Reuse existing.envprompt functions (SECRET_KEY, DEBUG, ALLOWED_HOSTS). Skip Python/uv checks, dependency install, migrations, CELERY_BROKER_URL prompt. After writing.env, callbin/deploy-docker.sh.docs/Deployment.md— Add note under Docker Compose section that setup can be automated via./bin/install.sh(docker mode).- No other files change. Dockerfile, docker-compose.yml, and systemd files stay as-is.
Approach
Approach B (selected): Extract bin/deploy-docker.sh as a standalone script, called from install.sh. This keeps Docker logic isolated and install.sh manageable. The standalone script guards against missing .env with a pre-flight check.
Rejected alternatives:
- Inline in install.sh — would bloat an already 373-line script
- Shared lib refactor — over-engineered for the scope