HyperSaaS
BackendDeployment

Docker

Docker Compose setup for local development and production.

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

Production

Build & Deploy

# Build production images
docker compose -f docker-compose.production.yml build

# Start all services
docker compose -f docker-compose.production.yml up -d

# View logs
docker compose -f docker-compose.production.yml logs -f django
docker compose -f docker-compose.production.yml logs -f celeryworker

Django Startup (Production)

The production Django container runs:

python /app/manage.py collectstatic --noinput
gunicorn config.wsgi --bind 0.0.0.0:5000 --chdir=/app

Static files are collected to S3 via django-storages.

Entrypoint

The production entrypoint waits for PostgreSQL before starting:

# Waits up to 30 seconds for PostgreSQL
# Constructs DATABASE_URL from environment variables
# Exits with error if database is unavailable

Traefik (Reverse Proxy)

Traefik handles:

  • HTTP → HTTPS redirect (port 80 → 443)
  • Let's Encrypt SSL certificates (ACME)
  • CSRF header forwarding (X-CSRFToken)
  • Routing: /* → Django (port 5000)
  • Routing: Flower on port 5555

Database Backups

# Create backup
docker compose -f docker-compose.production.yml exec postgres /usr/local/bin/backup

# List backups
docker compose -f docker-compose.production.yml exec postgres /usr/local/bin/backups

# Restore from backup
docker compose -f docker-compose.production.yml exec postgres /usr/local/bin/restore <filename>

# Upload backup to S3
docker compose -f docker-compose.production.yml run --rm awscli upload

# Download backup from S3
docker compose -f docker-compose.production.yml run --rm awscli download <filename>

Dockerfile Details

Multi-Stage Build

The Django Dockerfile uses a multi-stage build:

# Stage 1: Build wheels
FROM python:3.12-slim-bookworm AS python-build-stage
RUN pip install --upgrade pip
COPY requirements/ /requirements/
RUN pip wheel --wheel-dir /wheels -r /requirements/production.txt

# Stage 2: Runtime
FROM python:3.12-slim-bookworm AS python-run-stage
COPY --from=python-build-stage /wheels /wheels
RUN pip install --no-index --find-links=/wheels /wheels/*
COPY . /app

Build dependencies (installed in build stage only): cmake, g++ (needed for Docling native compilation).

Image size: ~7 GB due to Docling + PyTorch dependencies.

Security

The production image:

  • Creates a non-root django user
  • Strips development tools
  • Uses minimal runtime dependencies
  • Compiles translation messages during build

Environment Files

Local (.envs/.local/)

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

Production (.envs/.production/)

.envs/.production/.django    # Django, AWS, Stripe, Sentry, email
.envs/.production/.postgres  # PostgreSQL credentials
.envs/.production/.traefik   # Domain, email for Let's Encrypt

Health Checks

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

# Check Django is responding
curl http://localhost:8000/api/schema/

# 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