super-productivity/packages/super-sync-server/env.example
Johannes Millan 5ed1f2c5d0
fix(supersync): prevent migrator advisory-lock leak on deploy timeout (#9126)
A timed-out `docker compose run` in deploy.sh SIGTERMs the compose CLI but
can leave the migrator container (and its DB connection) running detached,
which keeps Prisma's session-level migration advisory lock held and wedges
the next deploy with P1002.

- deploy.sh: run_migrator() names each one-off migrator container from a
  single MIGRATOR_NAME_PREFIX and force-removes it (inline + $$-scoped EXIT
  sweep) so a timed-out run can't orphan it and leak the lock; add timeout -k.
- migrate-deploy.sh: recognize P1002 advisory-lock timeouts and print
  copy-paste diagnosis + cleanup guidance instead of a generic exit 1; never
  auto-terminate a backend (an active CONCURRENTLY build legitimately holds it).
- tests: P1002 fake-npx case + non-vacuous recovery test; assert the
  name/sweep-filter prefix single-source-of-truth invariant.
- env.example: document the recommended higher MIGRATION_TIMEOUT and the new
  force-remove-on-timeout behavior.
2026-07-17 20:18:54 +02:00

139 lines
6.1 KiB
Text

# Super Sync Server - Production Environment Configuration
# Copy this file to .env and configure all required values
# =============================================================================
# REQUIRED SETTINGS
# =============================================================================
# Your domain (without https://)
# Caddy will automatically obtain SSL certificates for this domain
DOMAIN=sync.your-domain.com
# JWT secret for authentication tokens (minimum 32 characters)
# Generate with: openssl rand -base64 32
JWT_SECRET=your-secure-jwt-secret-minimum-32-characters
# PostgreSQL password for the database
# Generate with: openssl rand -base64 24
POSTGRES_PASSWORD=your-secure-postgres-password
# =============================================================================
# SERVER SETTINGS (optional - defaults provided)
# =============================================================================
# Server bind address (default: 0.0.0.0)
# Use :: for IPv6-only deployments.
HOST=0.0.0.0
# =============================================================================
# DATABASE SETTINGS (optional - defaults provided)
# =============================================================================
# PostgreSQL user (default: supersync)
# POSTGRES_USER=supersync
# PostgreSQL database name (default: supersync)
# POSTGRES_DB=supersync
# External PostgreSQL connection string. Leave unset to use the bundled compose
# postgres service. The bundled service is reachable as postgres:5432; db:5432
# is also kept as a compatibility alias for older .env files. If you point this
# at an external host, also set POSTGRES_SERVICE= below.
#
# IMPORTANT: append ?connection_limit=N&pool_timeout=20 to bound Prisma's pool.
# Prisma's DEFAULT pool size is ~(host_cpu_count * 2), read from HOST cores —
# NOT the container cpu limit. On a many-core host an unbounded pool silently
# consumes the entire postgres max_connections cap (compose: 120), leaving zero
# headroom for psql, migrations, the old-ops cleanup job, or the reconnect
# stampede after a crash recovery -> "sorry, too many clients already" and a
# fleet-wide WS reconnect storm. Keep N well below max_connections (e.g. 60).
# DATABASE_URL=postgresql://supersync:password@example.com:5432/supersync?connection_limit=60&pool_timeout=20
# =============================================================================
# CORS SETTINGS
# =============================================================================
# CORS allowed origins (comma-separated)
# Default: https://app.super-productivity.com
# Add your self-hosted frontend URL if applicable
CORS_ORIGINS=https://app.super-productivity.com
# =============================================================================
# SMTP CONFIGURATION (Required for email verification)
# =============================================================================
# SMTP server hostname
SMTP_HOST=smtp.your-email-provider.com
# SMTP port (default: 587 for TLS, 465 for SSL)
SMTP_PORT=587
# Use SSL/TLS (true for port 465, false for STARTTLS on 587)
SMTP_SECURE=false
# SMTP authentication credentials
SMTP_USER=your-smtp-username
SMTP_PASS=your-smtp-password
# From address for emails
SMTP_FROM="Super Productivity Sync" <noreply@your-domain.com>
# =============================================================================
# CONTAINER REGISTRY (for build-and-push.sh)
# =============================================================================
# GitHub username for GHCR
# GHCR_USER=your-github-username
# GitHub token with "Packages: Read and write" permission
# Create at: https://github.com/settings/tokens?type=beta
# GHCR_TOKEN=your-github-token
# =============================================================================
# ADVANCED SETTINGS (usually no changes needed)
# =============================================================================
# Log level (info, debug, warn, error)
# LOG_LEVEL=info
# Startup migrations are disabled by default. Use scripts/deploy.sh for
# production and local Docker deploys so migrations run once before the app
# container is replaced. Only set this to true for one-off/manual runs.
# RUN_MIGRATIONS_ON_STARTUP=false
# Compose service used for database readiness checks. Leave unset to use the
# bundled postgres service. Set POSTGRES_SERVICE= to an empty value only when
# DATABASE_URL points to an external database; deploy.sh will then start
# supersync/caddy without compose dependencies. Prisma migrations still run
# against the configured DATABASE_URL.
# POSTGRES_SERVICE=
# Old operation retention cleanup deletes in bounded batches so a backlog cannot
# monopolize PostgreSQL. Increase carefully on larger servers.
# OLD_OPS_CLEANUP_DELETE_BATCH_SIZE=5000
# OLD_OPS_CLEANUP_MAX_DELETED_PER_RUN=25000
# Timeout in seconds for `prisma migrate deploy` during ./scripts/deploy.sh.
# Online index builds (CREATE INDEX CONCURRENTLY) can block on long-running
# transactions; raise this for very large tables (3600 is a safe starting point
# for a large operations table — the 900 default can SIGTERM a slow index build
# part-way through). A timed-out migrator container is now force-removed, so a
# too-low value no longer wedges the NEXT deploy with a leaked advisory lock
# (P1002); the deploy fails loudly with copy-paste recovery steps instead. Note
# an interrupted CREATE INDEX CONCURRENTLY can still need a one-time INVALID-index
# drop (the failure output prints the exact steps) before the re-run succeeds.
# Exit code 124 = timed out.
# MIGRATION_TIMEOUT=900
# Per-migration-step timeout (seconds) enforced inside the image. deploy.sh
# derives it from MIGRATION_TIMEOUT (minus a small margin) and forwards it, so
# raising MIGRATION_TIMEOUT is enough for the deploy.sh path. Set this directly
# only for the image CMD / helm initContainer paths, which have no outer host
# timeout. Defaults to 1800 inside the image when unset.
# MIGRATE_STEP_TIMEOUT=
# Safety valve for custom/private images without an
# org.opencontainers.image.revision label. Leave this unset in production; the
# deploy script uses the label to prevent mixing fresh SuperSync deploy inputs
# with a stale supersync image.
# SUPERSYNC_SKIP_IMAGE_REVISION_CHECK=false