Files
EventSnap/.env.example
MechaCat02 669a191968 fix(deploy): harden prod env for bcrypt hash and media path
Two latent production pitfalls, both proven by probing Compose's env_file resolution:

- A bcrypt ADMIN_PASSWORD_HASH is full of $; Compose env_file interpolation AND
  dotenvy variable substitution both eat the $… segments (as unset vars), corrupting
  the hash so every admin login 401s. Single-quote it so both read it literally —
  verified correct for env_file (container) and dotenvy 0.15.7 strong-quote (native).
  Updated .env.example with the quotes + a warning comment.

- MEDIA_PATH: pin it to the /media mount in the app 'environment:' block so a stray
  host path in .env can't leak in and make every upload 500 with EACCES. environment
  overrides env_file, so the container is always correct.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-19 16:46:38 +02:00

59 lines
3.9 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ── Domain ────────────────────────────────────────────────────────────────────
# Public domain Caddy will serve and obtain a TLS certificate for.
DOMAIN=my-event.example.com
# ── App server ────────────────────────────────────────────────────────────────
APP_PORT=3000
# Set to `production` in real deployments. This activates the secret guard that
# refuses to boot with placeholder JWT_SECRET / ADMIN_PASSWORD_HASH values.
# (docker-compose.yml already sets APP_ENV=production for the app service.)
APP_ENV=production
# ── Database ──────────────────────────────────────────────────────────────────
# Set a strong password and keep it in sync between DATABASE_URL and
# POSTGRES_PASSWORD. Generate one with: openssl rand -hex 24
DATABASE_URL=postgres://eventsnap:CHANGE_ME_use_a_strong_password@db:5432/eventsnap
POSTGRES_USER=eventsnap
POSTGRES_PASSWORD=CHANGE_ME_use_a_strong_password
POSTGRES_DB=eventsnap
# ── Authentication ────────────────────────────────────────────────────────────
# Generate with: openssl rand -hex 64
JWT_SECRET=change_me_to_a_random_64_byte_hex_string
SESSION_EXPIRY_DAYS=30
# Admin dashboard password (bcrypt hash).
# Generate with: htpasswd -bnBC 12 "" yourpassword | tr -d ':\n'
# IMPORTANT: keep the SINGLE QUOTES. A bcrypt hash is full of `$` (e.g. $2b$12$…$…),
# and both Docker Compose's env_file interpolation and dotenvy's variable substitution
# would otherwise eat the `$…` segments (reading them as unset vars) and corrupt the
# hash — every admin login then 401s. Single quotes make both read it literally.
ADMIN_PASSWORD_HASH='$2y$12$placeholder_replace_me'
# ── Event ─────────────────────────────────────────────────────────────────────
EVENT_NAME=Max & Maria's Wedding
EVENT_SLUG=max-maria-2026
# ── Storage ───────────────────────────────────────────────────────────────────
MEDIA_PATH=/media
# Export archives (Gallery.zip / Memories.zip). MUST be outside MEDIA_PATH —
# /media is publicly served, so exports here would be downloadable without auth.
EXPORT_PATH=/exports
# ── Upload limits ─────────────────────────────────────────────────────────────
DEFAULT_MAX_IMAGE_SIZE_MB=20
DEFAULT_MAX_VIDEO_SIZE_MB=500
# ── Rate limiting ─────────────────────────────────────────────────────────────
DEFAULT_UPLOAD_RATE_PER_HOUR=10
DEFAULT_FEED_RATE_PER_MIN=60
DEFAULT_EXPORT_RATE_PER_DAY=3
# ── Capacity ──────────────────────────────────────────────────────────────────
DEFAULT_ESTIMATED_GUEST_COUNT=100
# Fraction of total storage that triggers the "low storage" warning (0.01.0)
DEFAULT_QUOTA_TOLERANCE=0.75
# ── Workers ───────────────────────────────────────────────────────────────────
COMPRESSION_WORKER_CONCURRENCY=2