services: app: container_name: torqvoice image: ghcr.io/torqvoice/torqvoice:latest restart: unless-stopped ports: - "3000:3000" environment: - DATABASE_URL=postgresql://torqvoice:${POSTGRES_PASSWORD:-torqvoice}@db:5432/torqvoice - BETTER_AUTH_SECRET=${BETTER_AUTH_SECRET} - NEXT_PUBLIC_APP_URL=${NEXT_PUBLIC_APP_URL:-http://localhost:3000} - RESEND_API_KEY=${RESEND_API_KEY:-} - RESEND_FROM_EMAIL=${RESEND_FROM_EMAIL:-} # Optional, see .env.example: the largest backup data file a restore reads # into memory, in MiB (128 unless set). - BACKUP_MAX_DATA_FILE_MB=${BACKUP_MAX_DATA_FILE_MB:-} volumes: - uploads:/app/data/uploads - backups:/app/data/backups depends_on: db: condition: service_healthy db: image: postgres:16-alpine container_name: torqvoice-db restart: unless-stopped volumes: - postgres-data:/var/lib/postgresql/data environment: POSTGRES_USER: torqvoice # Set POSTGRES_PASSWORD in .env before the first start. The same value # goes into the app's DATABASE_URL above as it is, with no escaping, so # keep it to letters and digits (`openssl rand -hex 24`): a `/`, `@`, `#` # or `%` in it breaks the URL. Postgres keeps the password it was # created with, so changing it later means changing it in the database # as well (ALTER USER torqvoice PASSWORD '...'). POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-torqvoice} POSTGRES_DB: torqvoice ports: # The app reaches the database as `db` on Docker's own network; this is # for psql or a GUI on the host only. Bound to loopback because Docker # publishes ports past the host firewall, and 0.0.0.0 put the database # on the internet with the password above. - "127.0.0.1:5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U torqvoice"] interval: 5s timeout: 5s retries: 5 volumes: postgres-data: uploads: backups: