Skip to main content

Production Deployment

Configuration

The API loads configuration from layered TOML files and environment variables:

config/default.toml # Base defaults (always loaded)
config/{APP_ENV}.toml # Environment overlay (optional)
config/local.toml # Local overrides (optional, gitignored)
Environment variables # Highest priority (APOLLON__ prefix)

Set APP_ENV=production to load config/production.toml.

Production Config Overrides

Override these settings for production via environment variables:

Server

VariableProduction ValueDescription
APOLLON__SERVER__HOST0.0.0.0Bind address
APOLLON__SERVER__PORT3000Port (or match your reverse proxy)
APOLLON__SERVER__TRUST_PROXYtrueTrust X-Forwarded-For behind reverse proxy

Database

VariableDescription
APOLLON__DATABASE__URLPostgreSQL connection string with production credentials
APOLLON__TIMESCALE__URLTimescaleDB connection string with production credentials
APOLLON__TIMESCALE__MAX_CONNECTIONSIncrease for higher throughput (default: 5)
APOLLON__TIMESCALE__MIN_CONNECTIONSIncrease for faster cold starts (default: 1)
VariableDescription
APOLLON__PEPLINK__ROUTER_IPActual Peplink router IP (not the default 192.168.50.1)
APOLLON__PEPLINK__USERNAMERouter admin username
APOLLON__PEPLINK__PASSWORDRouter admin password

Security

VariableProduction ValueDescription
APOLLON__CORS__ALLOWED_ORIGINShttps://your-domain.comRestrict to your domain (comma-separated)
APOLLON__AUTH__API_KEYSkey1,key2,...Enable API key authentication
APOLLON__DOCS__SWAGGER_UIfalseDisable Swagger UI
APOLLON__DOCS__OPENAPI_JSONfalseDisable OpenAPI JSON endpoint
APOLLON__DOCS__GRAPHIQLfalseDisable GraphiQL playground

Optional Services

VariableDescription
APOLLON__SENTRY__DSNSentry error tracking DSN
APOLLON__RATE_LIMIT__WINDOW_MSRate limiting window (e.g., 900000 for 15 min)
APOLLON__RATE_LIMIT__MAX_REQUESTSMax requests per window (e.g., 100)
APOLLON__FORWARDING__URLGPS forwarding destination URL
APOLLON__FORWARDING__TOKENGPS forwarding API token

Logging

VariableProduction ValueDescription
RUST_LOGinfo or warnLog level (avoid debug/trace in production)
APOLLON__LOGGING__LEVELinfoApplication log level

Health Monitoring

Health Endpoint

GET /health

The health endpoint checks both database connections:

StatusHTTP CodeMeaning
Healthy200 OKBoth PostgreSQL and TimescaleDB are reachable
Unhealthy503 Service UnavailableOne or both databases are unreachable

The health check executes SELECT 1 against each pool. The /health endpoint is exempt from rate limiting and API key authentication.

Docker Health Check

The container has a built-in health check:

HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1

Monitoring Recommendations

  • Point your uptime monitor (e.g., UptimeRobot, Pingdom) at /health
  • Alert on HTTP 503 responses
  • Monitor container health status via Docker/orchestrator
  • Use Sentry (APOLLON__SENTRY__DSN) for error tracking

Security Checklist

Before deploying to production, verify the following:

Authentication & Authorization

  • API keys configured -- Set APOLLON__AUTH__API_KEYS with strong, unique keys
  • No default credentials -- Change all default apollon/apollon database passwords
  • Peplink credentials -- Use non-default router credentials

Network

  • CORS restricted -- Set APOLLON__CORS__ALLOWED_ORIGINS to your specific domain(s)
  • TLS termination -- Run behind a reverse proxy (nginx, Caddy) with TLS
  • Trust proxy enabled -- Set APOLLON__SERVER__TRUST_PROXY=true when behind a reverse proxy
  • Database not exposed -- PostgreSQL and TimescaleDB ports not accessible from the internet

Developer Tools

  • Swagger UI disabled -- APOLLON__DOCS__SWAGGER_UI=false
  • OpenAPI JSON disabled -- APOLLON__DOCS__OPENAPI_JSON=false
  • GraphiQL disabled -- APOLLON__DOCS__GRAPHIQL=false

Rate Limiting

  • Rate limiting enabled -- Configure APOLLON__RATE_LIMIT__WINDOW_MS and APOLLON__RATE_LIMIT__MAX_REQUESTS

Container Security

  • Non-root user -- Container runs as apollon (UID 1001) by default
  • Read-only filesystem -- Mount with --read-only and writable tmpfs for /app/cache and /app/logs
  • No new privileges -- Run with --security-opt=no-new-privileges
  • Resource limits -- Set memory and CPU limits

Data Protection

  • Database backups -- Regular PostgreSQL and TimescaleDB backups
  • Secrets management -- Database passwords, API keys, and tokens via environment variables or secrets manager (never in config files)
  • Sentry configured -- Set APOLLON__SENTRY__DSN for production error tracking

Monitoring

  • Health check configured -- External uptime monitor on /health
  • Log aggregation -- Collect container logs (stdout/stderr)
  • Security audit -- Nightly cargo audit and pnpm audit via CI (see CI/CD)

Example Docker Run

docker run -d \
--name apollon-api \
--restart unless-stopped \
--read-only \
--tmpfs /app/cache \
--tmpfs /app/logs \
--security-opt no-new-privileges \
--memory 512m \
--cpus 1.0 \
-p 3000:3000 \
-e APP_ENV=production \
-e APOLLON__DATABASE__URL=postgresql://user:pass@db:5432/apollon \
-e APOLLON__TIMESCALE__URL=postgresql://user:pass@tsdb:5433/apollon_tsdb \
-e APOLLON__PEPLINK__ROUTER_IP=10.0.1.1 \
-e APOLLON__PEPLINK__USERNAME=admin \
-e APOLLON__PEPLINK__PASSWORD=secure-password \
-e APOLLON__CORS__ALLOWED_ORIGINS=https://tracking.example.com \
-e APOLLON__AUTH__API_KEYS=key-abc123,key-def456 \
-e APOLLON__DOCS__SWAGGER_UI=false \
-e APOLLON__DOCS__OPENAPI_JSON=false \
-e APOLLON__DOCS__GRAPHIQL=false \
-e APOLLON__SENTRY__DSN=https://examplePublicKey@sentry.io/1 \
-e RUST_LOG=info \
ghcr.io/your-org/apollon/api:latest