Skip to main content

Quick Deploy

# Configure environment
cp .env.example .env
# Edit .env with production values

# Start production stack
make docker-prod

Production Dockerfile

The production build uses a multi-stage Dockerfile:
# Stage 1: Build Go binary
FROM golang:1.24 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o server ./cmd/server
RUN CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o healthcheck ./cmd/healthcheck

# Stage 2: Minimal runtime
FROM gcr.io/distroless/static-debian12
COPY --from=builder /app/server /server
COPY --from=builder /app/healthcheck /healthcheck
COPY --from=builder /app/migrations /migrations
ENTRYPOINT ["/server"]
Key optimizations:
  • -trimpath — removes filesystem paths from binary for reproducibility
  • -ldflags="-s -w" — strips debug symbols for smaller binary
  • Distroless base — minimal attack surface (no shell, no package manager)

Production Checklist

1

Set SESSION_SECRET

Generate a strong secret (minimum 32 bytes):
openssl rand -base64 32
2

Configure BASE_URL

Set to your public domain:
BASE_URL=https://app.tracera.io
3

Enable SSL

Set DB_SSLMODE=require for database connections. Set SESSION_COOKIE_SECURE=true (auto-derived if BASE_URL uses HTTPS).
4

Set Database Credentials

Use strong, unique passwords for TimescaleDB and Redis.
5

Configure OAuth Callbacks

Update OAuth provider callback URLs to match your production BASE_URL.
6

Configure Email

Set RESEND_API_KEY and RESEND_FROM_EMAIL with a verified domain.

Resource Limits

The production Docker Compose sets resource constraints:
ServiceCPUMemory
appLimitedLimited
webLimitedLimited
timescaledbLimitedLimited
redisLimitedLimited
Adjust these in docker-compose.yml based on your server capacity.

Monitoring

Health Checks

All services have built-in health checks:
# Check overall health
curl https://app.tracera.io/api/v1/health

Logs

# View all service logs
docker compose logs -f

# View specific service
docker compose logs -f app

Backup Strategy

TimescaleDB

# Backup
docker exec tracera-timescaledb pg_dump -U skinvestment skinvestment > backup.sql

# Restore
docker exec -i tracera-timescaledb psql -U skinvestment skinvestment < backup.sql

Redis

Redis data persistence is configured with AOF (Append Only File). Data survives container restarts via named volumes.