mirror of
https://github.com/johannesjo/super-productivity.git
synced 2026-07-18 00:46:45 +00:00
A bare CREATE INDEX CONCURRENTLY aborted mid-build (the in-image step
timeout firing at its 1800s default when a raised MIGRATION_TIMEOUT was
not forwarded, an external stop, or OOM) leaves the migration failed and
an INVALID index of the target name, wedging the deploy. Deployed images
reported only a bare "prisma migrate deploy failed (exit 143)" with no
recovery steps, so operators had no way forward.
- deploy.sh: forward MIGRATE_STEP_TIMEOUT into the migrator so a large
MIGRATION_TIMEOUT is not silently capped at the image default (1800s)
and kill a slow CREATE INDEX CONCURRENTLY early (the root cause).
- migrate-deploy.sh: normalize BusyBox `timeout` 143 -> 124 so a step
timeout hits the timeout branch, not the generic one.
- migrate-deploy.sh: emit_interrupted_recovery_hint() prints copy-paste
recovery (drop the INVALID index, roll the record back, re-run) for an
interrupted CONCURRENTLY build, from BOTH the 124 timeout branch (where
a normalized 143 -- the incident's own signal -- lands) and the generic
non-gate branch (OOM/137), plus the existing P3009 re-run path. Every
path prints guidance only and NEVER auto-resolves a bare CREATE.
- env.example: document the now-forwarded MIGRATE_STEP_TIMEOUT knob.
- tests: cover 143 normalization, the incident's 143->124 timeout-branch
recovery, the P3009 and non-gate bare-create recovery, and the
forwarded step timeout.
The bare CREATE stays bare and fail-loud on purpose: 20260613000001
ships in v18.11.0-v18.14.0 and is applied natively on healthy deploys,
so converting it to a drop-then-create shape would change its checksum
and break every DB that already applied it.
Recovery for the current wedged deploy (20260613000001):
DROP INDEX CONCURRENTLY IF EXISTS "operations_entity_ids_gin";
prisma migrate resolve --rolled-back \
20260613000001_add_operation_entity_ids_gin_index
then re-run the deploy with the step timeout raised enough for the GIN
build (and clear any idle-in-transaction blocker first).
132 lines
5.6 KiB
Text
132 lines
5.6 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. 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
|