# ============================================================================== # Changemaker Lite v2 — Environment Variables # Copy this file to .env and fill in the values # Generate secrets with: openssl rand -hex 32 # ============================================================================== # # SECURITY WARNING: # - All passwords marked REQUIRED_STRONG_PASSWORD_CHANGE_THIS MUST be changed # - Use strong, unique passwords (20+ characters recommended) # - Generate secrets with: openssl rand -hex 32 # - NEVER commit .env to version control # ============================================================================== # --- General --- NODE_ENV=development # Root domain serves MkDocs documentation site only # All application routes (admin + public) accessible at app.${DOMAIN} DOMAIN=cmlite.org USER_ID=1000 GROUP_ID=1000 DOCKER_GROUP_ID=984 # --- V2 PostgreSQL --- V2_POSTGRES_USER=changemaker V2_POSTGRES_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS V2_POSTGRES_DB=changemaker_v2 V2_POSTGRES_PORT=5433 # --- JWT Auth --- JWT_ACCESS_SECRET=GENERATE_WITH_openssl_rand_hex_32 JWT_REFRESH_SECRET=GENERATE_WITH_openssl_rand_hex_32 JWT_ACCESS_EXPIRY=15m JWT_REFRESH_EXPIRY=7d # Encryption key for DB-stored secrets (SMTP password, etc.) # REQUIRED in production — must NOT reuse JWT_ACCESS_SECRET # Generate with: openssl rand -hex 32 ENCRYPTION_KEY=GENERATE_WITH_openssl_rand_hex_32 # --- Initial Super Admin User (auto-created during database seeding) --- # These credentials are used to create the initial super admin account # Change these before running the seed script in production INITIAL_ADMIN_EMAIL=admin@cmlite.org INITIAL_ADMIN_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS # --- API --- API_PORT=4000 API_URL=http://localhost:4000 # Include docs/root domain for inline payment widgets on MkDocs pages CORS_ORIGINS=http://localhost:3000,http://localhost,http://localhost:4003 # --- Admin GUI --- ADMIN_PORT=3000 ADMIN_URL=http://localhost:3000 # --- Nginx --- NGINX_HTTP_PORT=80 NGINX_HTTPS_PORT=443 # --- SMTP / Email --- SMTP_HOST=mailhog-changemaker SMTP_PORT=1025 SMTP_USER= SMTP_PASS= SMTP_FROM=noreply@cmlite.org SMTP_FROM_NAME=Changemaker Lite EMAIL_TEST_MODE=true TEST_EMAIL_RECIPIENT=admin@cmlite.org # --- Listmonk --- LISTMONK_PORT=9001 LISTMONK_DB_PORT=5432 LISTMONK_DB_USER=listmonk LISTMONK_DB_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS LISTMONK_DB_NAME=listmonk # Web admin login (for the Listmonk dashboard at :9001) LISTMONK_WEB_ADMIN_USER=admin LISTMONK_WEB_ADMIN_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS # API user (auto-created by listmonk-init container, used by V2 API for sync) # Generate token: openssl rand -hex 16 LISTMONK_API_USER=v2-api LISTMONK_API_TOKEN=GENERATE_WITH_openssl_rand_hex_16 LISTMONK_ADMIN_USER=v2-api LISTMONK_ADMIN_PASSWORD=SAME_AS_LISTMONK_API_TOKEN LISTMONK_SYNC_ENABLED=false LISTMONK_PROXY_PORT=9002 # Listmonk SMTP — MailHog for development (production SMTP added as second provider if credentials set) LISTMONK_SMTP_HOST=mailhog-changemaker LISTMONK_SMTP_PORT=1025 LISTMONK_SMTP_USER= LISTMONK_SMTP_PASSWORD= LISTMONK_SMTP_TLS_TYPE=none LISTMONK_SMTP_FROM=Changemaker Lite # Production SMTP (uncomment and set for real email delivery): # LISTMONK_SMTP_HOST=smtp.protonmail.ch # LISTMONK_SMTP_PORT=587 # LISTMONK_SMTP_USER=your@email.com # LISTMONK_SMTP_PASSWORD=your-password # LISTMONK_SMTP_TLS_TYPE=STARTTLS # --- Represent API (Canadian electoral data) --- REPRESENT_API_URL=https://represent.opennorth.ca # --- NocoDB v2 (read-only data browser) --- # NocoDB uses its own database (nocodb_meta) to avoid conflicts with Prisma # The database is auto-created by init-nocodb-db.sh on first PostgreSQL startup NOCODB_V2_PORT=8091 NOCODB_URL=http://changemaker-v2-nocodb:8080 NOCODB_PORT=8091 NC_ADMIN_EMAIL=admin@cmlite.org NC_ADMIN_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS # --- Redis --- # Shared Redis (v2 uses authenticated connection) REDIS_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS REDIS_URL=redis://:${REDIS_PASSWORD}@redis-changemaker:6379 # --- Payments (Stripe) --- # Enable payments feature (memberships, products, donations) # Stripe API keys are stored encrypted in DB via admin settings page ENABLE_PAYMENTS=false # --- Media Management --- ENABLE_MEDIA_FEATURES=false MEDIA_API_PORT=4100 MEDIA_API_PUBLIC_URL=http://media-api:4100 MEDIA_ROOT=/media/library MEDIA_UPLOADS=/media/uploads MAX_UPLOAD_SIZE_GB=10 VIDEO_PLAYER_DEBUG=false # Video Analytics (Feb 2026) VIDEO_ANALYTICS_RETENTION_DAYS=90 VIDEO_ANALYTICS_IP_HASHING_ENABLED=true # Video Scheduling (Feb 2026) VIDEO_SCHEDULE_DEFAULT_TIMEZONE=UTC VIDEO_SCHEDULE_NOTIFICATION_ENABLED=true # Preview Links (Feb 2026) VIDEO_PREVIEW_LINK_EXPIRY_HOURS=24 # --- Gitea --- GITEA_URL=http://gitea-changemaker:3000 GITEA_PORT=3030 GITEA_WEB_PORT=3030 GITEA_SSH_PORT=2222 GITEA_DB_TYPE=mysql GITEA_DB_HOST=gitea-db:3306 GITEA_DB_NAME=gitea GITEA_DB_USER=gitea GITEA_DB_PASSWD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS GITEA_DB_ROOT_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS GITEA_ROOT_URL=https://git.cmlite.org GITEA_DOMAIN=git.cmlite.org # --- n8n --- N8N_URL=http://n8n-changemaker:5678 N8N_PORT=5678 N8N_HOST=n8n.cmlite.org N8N_ENCRYPTION_KEY=REQUIRED_STRONG_PASSWORD_CHANGE_THIS N8N_USER_EMAIL=admin@example.com N8N_USER_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS GENERIC_TIMEZONE=UTC # --- MkDocs --- # Port mapping for MkDocs container (host:container) # This also controls the Vite dev proxy in local development # Change this port to use a different local port, and the admin dev server will automatically use it MKDOCS_PORT=4003 MKDOCS_SITE_SERVER_PORT=4001 BASE_DOMAIN=https://cmlite.org MKDOCS_PREVIEW_URL=http://mkdocs:8000 MKDOCS_DOCS_PATH=/mkdocs/docs # --- Code Server --- CODE_SERVER_PORT=8888 CODE_SERVER_URL=http://code-server:8080 USER_NAME=coder # --- Homepage --- HOMEPAGE_PORT=3010 HOMEPAGE_EMBED_PORT=8887 HOMEPAGE_VAR_BASE_URL=http://localhost # --- Mini QR --- MINI_QR_PORT=8089 MINI_QR_URL=http://mini-qr:8080 MINI_QR_EMBED_PORT=8885 # --- Excalidraw (Collaborative Whiteboard) --- EXCALIDRAW_PORT=8090 EXCALIDRAW_URL=http://excalidraw-changemaker:80 EXCALIDRAW_EMBED_PORT=8886 EXCALIDRAW_WS_URL=wss://draw.cmlite.org # --- MailHog --- MAILHOG_SMTP_PORT=1025 MAILHOG_WEB_PORT=8025 # --- NAR (National Address Register) --- # Path to extracted NAR data (contains YYYYMM/Addresses/ and YYYYMM/Locations/) # Download from: https://www150.statcan.gc.ca/n1/pub/46-26-0002/462600022022001-eng.htm NAR_DATA_DIR=/data # --- Overpass / Area Import --- # OpenStreetMap Overpass API endpoint (use a private instance for heavy usage) OVERPASS_API_URL=https://overpass-api.de/api/interpreter # Minimum delay between Overpass requests (ms) — public API requires 30s OVERPASS_MIN_DELAY_MS=30000 # Maximum reverse geocode grid points for area import fill-in AREA_IMPORT_MAX_GRID_POINTS=500 # --- Geocoding --- # Optional Mapbox API key for improved geocoding accuracy # Free tier: 100,000 requests/month # Sign up: https://www.mapbox.com/pricing MAPBOX_API_KEY= # Rate limit delay between provider requests (milliseconds) GEOCODING_RATE_LIMIT_MS=1100 # Redis-backed persistent cache settings GEOCODING_CACHE_ENABLED=true GEOCODING_CACHE_TTL_HOURS=24 # Phase 2: Performance & Accuracy # Google Maps API (optional, most accurate but costs $0.005/request after 100k/month) GOOGLE_MAPS_API_KEY= GOOGLE_MAPS_ENABLED=false # Parallel geocoding for bulk imports (10x speedup) GEOCODING_PARALLEL_ENABLED=true GEOCODING_BATCH_SIZE=10 # Bulk Re-Geocoding (Phase 3) BULK_GEOCODE_ENABLED=true BULK_GEOCODE_MAX_BATCH=5000 # --- Pangolin Tunnel --- # Server: self-hosted Pangolin instance PANGOLIN_API_URL=https://api.bnkserve.org/v1 PANGOLIN_API_KEY= PANGOLIN_ORG_ID= # Populated after setup (via admin GUI or API) PANGOLIN_SITE_ID= PANGOLIN_ENDPOINT=https://pangolin.bnkserve.org PANGOLIN_NEWT_ID= PANGOLIN_NEWT_SECRET= # --- Monitoring (only used with --profile monitoring) --- PROMETHEUS_PORT=9090 GRAFANA_PORT=3001 GRAFANA_ADMIN_PASSWORD=admin GRAFANA_ROOT_URL=http://localhost:3001 CADVISOR_PORT=8080 NODE_EXPORTER_PORT=9100 REDIS_EXPORTER_PORT=9121 ALERTMANAGER_PORT=9093 GOTIFY_PORT=8889 GOTIFY_ADMIN_USER=admin GOTIFY_ADMIN_PASSWORD=admin