This guide covers deploying Snaapi to production, including Docker-based deployments and observability setup.
Before deploying, ensure you have:
- A PostgreSQL database accessible from your production environment
- All required environment variables configured (see Configuration)
APP_ENVset toproduction
Key production settings:
APP_ENV="production"
DATABASE_URL="postgres://user:password@db-host:5432/snaapi"
BETTER_AUTH_SECRET="<strong-random-secret>"
BETTER_AUTH_URL="https://your-domain.com"
SNAAPI_SESSION_SECRET="<strong-random-secret>"
SNAAPI_LOG_LEVEL="info"
SNAAPI_AUTO_MIGRATE=falseWhy
SNAAPI_AUTO_MIGRATE=false? In production you typically want to control exactly when database migrations run, rather than having them execute automatically every time the application restarts. This prevents unexpected schema changes during routine deployments or container restarts. Run migrations explicitly by settingSNAAPI_AUTO_MIGRATE=truefor a single controlled startup, then switching it back tofalse.
Deploy Snaapi with Docker Compose for a self-contained setup:
# docker-compose.yml
services:
snaapi:
image: ghcr.io/snaapi/snaapi:latest
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://user:password@db:5432/snaapi
- BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET}
- BETTER_AUTH_URL=${BETTER_AUTH_URL}
- APP_ENV=production
depends_on:
- db
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: password
POSTGRES_DB: snaapi
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:docker compose up -dThe Snaapi Docker image uses a distroless base (gcr.io/distroless/cc-debian12)
and runs as a non-root user for security.
In production, place Snaapi behind a reverse proxy to handle TLS termination and serve on standard ports. Snaapi listens on port 8000 by default.
server {
listen 443 ssl;
server_name your-domain.com;
ssl_certificate /etc/ssl/certs/your-domain.crt;
ssl_certificate_key /etc/ssl/private/your-domain.key;
location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}your-domain.com {
reverse_proxy 127.0.0.1:8000
}
Caddy automatically provisions and renews TLS certificates via Let's Encrypt.
Snaapi includes built-in OpenTelemetry support for tracing and monitoring.
Set the following environment variables:
OTEL_DENO=true
OTEL_SERVICE_NAME="snaapi-production"Configure an OpenTelemetry collector to receive traces from Snaapi. Example with a Grafana stack:
# otel-collector-config.yml
receivers:
otlp:
protocols:
grpc:
endpoint: 0.0.0.0:4317
http:
endpoint: 0.0.0.0:4318
exporters:
otlp/tempo:
endpoint: tempo:4317
tls:
insecure: true
service:
pipelines:
traces:
receivers: [otlp]
exporters: [otlp/tempo]Snaapi instruments the following with OpenTelemetry spans:
- Middleware pipeline (authentication, authorization, field filtering)
- Database queries
- Event emission
- HTTP request handling
See the Configuration docs for all OTEL-related environment variables.
