Skip to main content

Overview

LatentGEO supports two canonical Docker deployment modes:
  1. Standard Mode (docker-compose.yml) - Production-ready containerized deployment
  2. Development Mode (docker-compose.dev.yml) - Hot reload for active development
Both modes use Supabase for PostgreSQL and Storage, with Redis for caching and SSE (Server-Sent Events).

Standard Mode (Production)

Configuration

The standard mode uses docker-compose.yml with the following characteristics:
  • Backend and worker containers without code mounts
  • Frontend in production mode (optimized build)
  • Server-side API URL: http://backend:8000
  • Browser-side API URL: http://localhost:8000

Quick Start

1

Prepare environment file

Copy .env.example to .env and configure your environment variables:
cp .env.example .env
Key variables:
  • DATABASE_URL - Your Supabase PostgreSQL connection string
  • REDIS_URL - Redis connection URL (default: redis://redis:6379/0)
  • SSE_SOURCE - SSE source (redis or db, default: redis)
  • SUPABASE_URL - Your Supabase project URL
  • SUPABASE_KEY - Your Supabase anon key
  • SUPABASE_SERVICE_ROLE_KEY - Your Supabase service role key
2

Start services

Build and start all containers:
docker compose up --build -d
3

Verify deployment

Check container status:
docker compose ps
Test the backend health endpoint:
curl http://localhost:8000/health

Services

Backend

  • Image: Built from Dockerfile.backend
  • Port: 8000
  • Command: uvicorn app.main:app --host 0.0.0.0 --port 8000
  • Health Check: GET /health/live every 30s

Frontend

  • Image: Built from Dockerfile.frontend
  • Port: 3000
  • Mode: Production (optimized build)
  • Environment:
    • API_URL=http://backend:8000 (server-side)
    • NEXT_PUBLIC_API_URL=http://localhost:8000 (browser)

Worker (Celery)

  • Image: Built from Dockerfile.backend
  • Command: celery -A app.workers.tasks worker --loglevel=info --concurrency=2 --prefetch-multiplier=1 --max-tasks-per-child=20
  • Resources: 2GB memory limit, 512MB reservation

Redis

  • Image: redis:7-alpine
  • Port: 6379 (internal)
  • Purpose: Caching, Celery broker, SSE events
The local PostgreSQL service uses the legacy-local-db profile and is disabled by default. Use Supabase for database hosting.

Development Mode

Configuration

The development mode uses docker-compose.dev.yml with:
  • Hot reload for backend (FastAPI with --reload)
  • Hot reload for frontend (Next.js dev server)
  • Code mounted as volumes for instant changes
  • Optimized for fast iteration

Quick Start

1

Prepare environment

Ensure .env is configured with development settings:
DEBUG=True
ENVIRONMENT=development
SSE_SOURCE=redis
2

Start in development mode

docker compose -f docker-compose.dev.yml up --build
Omit the -d flag to see logs in real-time during development.
3

Access services

Development Features

Backend Hot Reload

command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload --reload-dir /app
volumes:
  - ./backend:/app:cached
  - ./logs:/app/logs:cached

Frontend Hot Reload

environment:
  WATCHPACK_POLLING: "true"
  CHOKIDAR_USEPOLLING: "true"
volumes:
  - ./frontend:/app:delegated
  - frontend_node_modules:/app/node_modules

Resource Limits

  • Backend: 2 CPU / 1GB memory
  • Frontend: 2 CPU / 2GB memory
  • Worker: 1 CPU / 512MB memory
  • Redis: 0.5 CPU / 256MB memory

Environment Variables

Database & Cache

DATABASE_URL=postgresql+psycopg2://user:pass@host:5432/db
DB_POOL_SIZE=5
DB_MAX_OVERFLOW=5
DB_POOL_TIMEOUT=15
DB_POOL_RECYCLE=900
DB_CONNECT_TIMEOUT_SECONDS=5
DB_POOL_PRE_PING=false
REDIS_URL=redis://redis:6379/0
CELERY_BROKER_URL=redis://redis:6379/0
CELERY_RESULT_BACKEND=redis://redis:6379/1

SSE Configuration

SSE_SOURCE=redis
SSE_FALLBACK_DB_INTERVAL_SECONDS=10
SSE_HEARTBEAT_SECONDS=30
SSE_RETRY_MS=5000
SSE (Server-Sent Events) provides real-time progress updates for audits. Redis is the primary source with automatic database fallback.

Supabase

SUPABASE_URL=https://your-project.supabase.co
SUPABASE_KEY=your-anon-key
SUPABASE_SERVICE_ROLE_KEY=your-service-role-key
SUPABASE_JWT_SECRET=your-jwt-secret
SUPABASE_STORAGE_BUCKET=audit-reports

Auth0

AUTH0_DOMAIN=your-domain.auth0.com
AUTH0_ISSUER_BASE_URL=https://your-domain.auth0.com
AUTH0_API_AUDIENCE=your-api-audience
AUTH0_API_SCOPES=read:app
AUTH0_EXPECTED_CLIENT_ID=your-client-id

API Keys

GOOGLE_API_KEY=your-google-api-key
CSE_ID=your-cse-id
SERPER_API_KEY=your-serper-key
NVIDIA_API_KEY=your-nvidia-key
GOOGLE_PAGESPEED_API_KEY=your-pagespeed-key

Troubleshooting

Container Issues

1

Check container logs

# All services
docker compose logs -f

# Specific service
docker compose logs -f backend
docker compose logs -f frontend
docker compose logs -f worker
2

Verify container health

docker compose ps
Look for “healthy” status on backend container.
3

Restart services

docker compose restart backend
docker compose restart worker

Redis Connection Issues

# Check Redis logs
docker compose logs -f redis

# Test Redis connection
docker compose exec redis redis-cli ping
# Expected output: PONG

SSE Not Working

1

Verify Redis is running

docker compose logs -f redis
2

Check SSE configuration

Ensure these variables are set:
SSE_SOURCE=redis
SSE_FALLBACK_DB_INTERVAL_SECONDS=10
SSE_HEARTBEAT_SECONDS=30
SSE_RETRY_MS=5000
3

Monitor backend SSE logs

docker compose logs -f backend | grep SSE
4

Test SSE endpoint

curl http://localhost:8000/api/v1/sse/audits/test-id/progress

Database Connection Issues

If using Supabase Pooler, ensure DB_POOL_PRE_PING=false is set to avoid connection issues.
# Test database connectivity
docker compose exec backend python -c "
import os
from sqlalchemy import create_engine
engine = create_engine(os.getenv('DATABASE_URL'))
with engine.connect() as conn:
    print('Database connected successfully')
"

Frontend Build Failures

# Clear Next.js cache
rm -rf frontend/.next
rm -rf frontend/node_modules

# Rebuild frontend
docker compose up --build frontend

Worker Not Processing Tasks

# Check worker logs
docker compose logs -f worker

# Verify Celery is connected to Redis
docker compose exec worker celery -A app.workers.tasks inspect ping

# Check active tasks
docker compose exec worker celery -A app.workers.tasks inspect active

Docker Commands Reference

Starting Services

# Standard mode (detached)
docker compose up --build -d

# Development mode (foreground)
docker compose -f docker-compose.dev.yml up --build

# Start specific service
docker compose up backend

Stopping Services

# Stop all services
docker compose down

# Stop and remove volumes
docker compose down -v

# Stop specific service
docker compose stop backend

Viewing Logs

# Follow all logs
docker compose logs -f

# Follow specific service
docker compose logs -f backend

# Last 100 lines
docker compose logs --tail=100 backend

Executing Commands

# Run backend shell
docker compose exec backend bash

# Run database migrations
docker compose exec backend alembic upgrade head

# Run tests
docker compose exec backend pytest

Rebuilding

# Rebuild all images
docker compose build --no-cache

# Rebuild specific service
docker compose build --no-cache backend

Production Considerations

Do not use the development compose file in production. It includes volume mounts and debug settings that are insecure for production use.

Security

  • Generate secure secrets using python -c "import secrets; print(secrets.token_urlsafe(32))"
  • Never commit .env files to version control
  • Use environment-specific .env files (.env.production, .env.staging)
  • Rotate secrets regularly (every 90 days)

Performance

  • Set appropriate worker concurrency based on CPU cores
  • Configure database pool sizes based on connection limits
  • Use Redis for SSE primary source (better performance than DB fallback)
  • Monitor container resource usage with docker stats

Monitoring

# View resource usage
docker stats

# Check container health
docker compose ps

# Export logs
docker compose logs > logs.txt

Next Steps

AWS Deployment

Deploy to AWS ECS with RDS and ElastiCache

Supabase Migration

Migrate between Supabase regions

Build docs developers (and LLMs) love