# Production stack: caddy (static panel + /api proxy) + server + postgres.
# Build the web panel first: npm run build -w @ltt/web
#
# Values come from .env next to this file (all optional):
# POSTGRES_PASSWORD — db password (default: ltt)
# HTTP_PORT — host port for the panel (default: 8081)
# SITE_ADDRESS — Caddy site address; set to a DNS name for
# automatic HTTPS (default: :80)
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: ltt
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-ltt}
POSTGRES_DB: ltt
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ltt"]
interval: 2s
timeout: 3s
retries: 15
server:
build: ./server
environment:
DATABASE_URL: postgresql+asyncpg://ltt:${POSTGRES_PASSWORD:-ltt}@postgres:5432/ltt
FILES_DIR: /srv/data/files
depends_on:
postgres:
condition: service_healthy
volumes:
- ./data:/srv/data
caddy:
image: caddy:2-alpine
environment:
SITE_ADDRESS: ${SITE_ADDRESS:-:80}
ports:
- "${HTTP_PORT:-8081}:80"
- "${HTTPS_PORT:-8443}:443"
volumes:
- ./deploy/Caddyfile:/etc/caddy/Caddyfile:ro
- ./packages/web/dist:/srv/web:ro
- caddy_data:/data
- caddy_config:/config
depends_on:
- server
volumes:
postgres_data:
caddy_data:
caddy_config: