HyperSaaS
BackendDeployment

Docker

Docker Compose for local development, and the production images.

Local Development

Build & Start

# Build all services
docker compose -f docker-compose.local.yml build

# Start all services
docker compose -f docker-compose.local.yml up

# Start in background
docker compose -f docker-compose.local.yml up -d

# Build without cache (after dependency changes)
docker compose -f docker-compose.local.yml build --no-cache

Django Startup

The local Django container runs:

python manage.py migrate
python manage.py runserver_plus 0.0.0.0:8000

Celery Worker (Hot Reload)

The local Celery worker uses watchfiles for automatic restart on code changes:

watchfiles --filter python celery.__main__.main \
  --args '-A config.celery_app worker -l INFO'

Management Commands

# Run any Django command
docker compose -f docker-compose.local.yml run --rm django python manage.py <command>

# Examples
docker compose -f docker-compose.local.yml run --rm django python manage.py createsuperuser
docker compose -f docker-compose.local.yml run --rm django python manage.py makemigrations
docker compose -f docker-compose.local.yml run --rm django python manage.py shell_plus

Database Access

# PostgreSQL shell
docker compose -f docker-compose.local.yml exec postgres psql -U <POSTGRES_USER> -d <POSTGRES_DB>

# Check pgvector extension
SELECT * FROM pg_extension WHERE extname = 'vector';

Service URLs

ServiceURL
Django APIhttp://localhost:8000
Flowerhttp://localhost:5555
Mailpithttp://localhost:8025

One server (Docker Compose)

docker-compose.production.yml runs everything on one server, with Traefik in front for HTTPS (Let's Encrypt), and builds the same images as AWS. It's an alternative these docs don't walk through. For production, AWS is the documented path.

The production images

compose/production/django/Dockerfile builds two images from one file, with Python 3.12:

TargetRunsSizeWhy
webDjango (gunicorn), Celery beatabout 1 GBNo Docling or PyTorch, so it starts fast and uses little memory
workerthe Celery workerabout 4.3 GBDocling, PyTorch (CPU) and the document models, for reading files
docker build -f compose/production/django/Dockerfile --target web    -t backend-web .
docker build -f compose/production/django/Dockerfile --target worker -t backend-worker .

The tasks run on x86, so on Apple Silicon add --platform linux/amd64. On AWS, GitHub Actions builds and pushes both images; the worker's build cache lives in ECR.

  • Static files are collected into the web image at build time and served by WhiteNoise, so nothing is uploaded at start-up.
  • Build tools (cmake, g++, for Docling) are only in the build stage.
  • The containers run as a non-root django user, and translation messages are compiled during the build.
  • The entrypoint waits for PostgreSQL when POSTGRES_HOST is set. Without DATABASE_URL, the settings build it from POSTGRES_*.

Environment Files

Local (.envs/.local/)

.envs/.local/.django    # Django, Redis, Celery settings
.envs/.local/.postgres  # PostgreSQL credentials

One server (.envs/.production/)

.envs/.production/.django.example    # copy to .django: Django, AWS, Stripe, Sentry, email
.envs/.production/.postgres.example  # copy to .postgres: PostgreSQL credentials

On AWS there are no env files: Terraform sets the settings, and the keys live in Secrets Manager.

Health Checks

# Check all services are running
docker compose -f docker-compose.local.yml ps

# Check Django, its database and its cache
curl http://localhost:8000/healthz/        # {"status": "ok"}

# Check database connection
docker compose exec django python manage.py check --database default

# Check Celery worker
docker compose exec django celery -A config.celery_app inspect ping

Troubleshooting

IssueSolution
Database connection refusedWait for PostgreSQL to be ready, check credentials
Celery tasks not executingCheck Redis connection, verify worker is running
S3 upload failingVerify AWS credentials and bucket permissions
Docling build failingEnsure Python 3.12 (not 3.13), check cmake/g++ installed
Out of disk spacedocker system prune -a to clean unused images
pgvector not availableEnsure using pgvector/pgvector:pg17 image

On this page