357 lines
12 KiB
Plaintext
357 lines
12 KiB
Plaintext
# ==============================================================================
|
|
# 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
|
|
# Use 5434 to avoid conflict with main PostgreSQL (5432 internal / 5433 host)
|
|
LISTMONK_DB_PORT=5434
|
|
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_WEBHOOK_SECRET=
|
|
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 <noreply@cmlite.org>
|
|
# 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
|
|
# Used during admin Docker build to set the media API endpoint for Vite
|
|
VITE_MEDIA_API_URL=http://changemaker-media-api:4100
|
|
MEDIA_ROOT=/media/library
|
|
MEDIA_UPLOADS=/media/uploads
|
|
MAX_UPLOAD_SIZE_GB=10
|
|
PUBLIC_MEDIA_PORT=3100
|
|
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
|
|
|
|
# --- Gitea Docs Comments ---
|
|
# Enable comments on MkDocs pages (backed by Gitea Issues)
|
|
GITEA_COMMENTS_ENABLED=false
|
|
# Personal access token with repo write scope (create in Gitea → Settings → Applications)
|
|
GITEA_API_TOKEN=
|
|
# Repository owner (Gitea username that will own the docs-comments repo)
|
|
GITEA_COMMENTS_REPO_OWNER=
|
|
# Repository name (auto-created via admin setup button)
|
|
GITEA_COMMENTS_REPO_NAME=docs-comments
|
|
# OAuth2 Application credentials (create in Gitea → Settings → Applications → OAuth2)
|
|
# Redirect URIs: https://{DOMAIN}/comments/callback/ and http://localhost:4003/comments/callback/
|
|
GITEA_OAUTH_CLIENT_ID=
|
|
GITEA_OAUTH_CLIENT_SECRET=
|
|
|
|
# --- 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=4004
|
|
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
|
|
|
|
# --- Vaultwarden (Password Manager) ---
|
|
VAULTWARDEN_PORT=8445
|
|
VAULTWARDEN_URL=http://vaultwarden-changemaker:80
|
|
VAULTWARDEN_EMBED_PORT=8890
|
|
# Admin panel token (access at /admin) — generate with: openssl rand -hex 32
|
|
VAULTWARDEN_ADMIN_TOKEN=
|
|
# MUST use HTTPS — Bitwarden web vault enforces HTTPS for account creation
|
|
# Set to your Pangolin tunnel URL (e.g., https://vault.yourdomain.org)
|
|
# Local access (browsing existing vault) works on HTTP, but signup/invite requires HTTPS
|
|
VAULTWARDEN_DOMAIN=https://vault.cmlite.org
|
|
VAULTWARDEN_SIGNUPS_ALLOWED=false
|
|
VAULTWARDEN_WEBSOCKET_ENABLED=true
|
|
# SMTP security: "off" for MailHog, "starttls" or "force_tls" for production
|
|
VAULTWARDEN_SMTP_SECURITY=off
|
|
|
|
# --- 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=
|
|
|
|
# --- Prisma CLI (host-side only, NOT used by Docker containers) ---
|
|
# Containers resolve the DB hostname internally via docker-compose environment
|
|
# This is used when running `npx prisma migrate dev` from the host machine
|
|
DATABASE_URL=postgresql://changemaker:YOUR_POSTGRES_PASSWORD@localhost:5433/changemaker_v2
|
|
|
|
# --- Rocket.Chat (Team Chat) ---
|
|
# ENABLE_CHAT is the initial default; once saved in admin Settings, the DB value is authoritative
|
|
ENABLE_CHAT=false
|
|
ROCKETCHAT_ADMIN_USER=rcadmin
|
|
ROCKETCHAT_ADMIN_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS
|
|
ROCKETCHAT_URL=http://rocketchat-changemaker:3000
|
|
ROCKETCHAT_EMBED_PORT=8891
|
|
|
|
# --- Gancio (Event Management) ---
|
|
# Uses shared PostgreSQL (database: gancio, auto-created by init-gancio-db.sh)
|
|
GANCIO_PORT=8092
|
|
GANCIO_URL=http://gancio-changemaker:13120
|
|
GANCIO_EMBED_PORT=8892
|
|
GANCIO_BASE_URL=https://events.cmlite.org
|
|
# Gancio admin credentials for shift-to-event sync (OAuth login)
|
|
GANCIO_ADMIN_USER=admin
|
|
GANCIO_ADMIN_PASSWORD=REQUIRED_STRONG_PASSWORD_CHANGE_THIS
|
|
# Enable automatic shift → Gancio event sync
|
|
GANCIO_SYNC_ENABLED=false
|
|
|
|
# --- Jitsi Meet (Video Conferencing) ---
|
|
# Self-hosted Jitsi with JWT auth — integrates with Rocket.Chat for channel video calls
|
|
# ENABLE_MEET is the initial default; once saved in admin Settings, the DB value is authoritative
|
|
ENABLE_MEET=false
|
|
# JWT authentication (shared between Jitsi Prosody, Rocket.Chat, and the API)
|
|
# Generate with: openssl rand -hex 32
|
|
JITSI_APP_ID=changemaker
|
|
JITSI_APP_SECRET=GENERATE_WITH_openssl_rand_hex_32
|
|
# Internal XMPP passwords (used between Jitsi containers, not exposed externally)
|
|
# Generate each with: openssl rand -hex 16
|
|
JITSI_JICOFO_AUTH_PASSWORD=GENERATE_WITH_openssl_rand_hex_16
|
|
JITSI_JVB_AUTH_PASSWORD=GENERATE_WITH_openssl_rand_hex_16
|
|
# Embed port for admin iframe
|
|
JITSI_EMBED_PORT=8893
|
|
JITSI_URL=http://jitsi-web-changemaker:80
|
|
# JVB public IP (required for NAT traversal — set to server's public IP in production)
|
|
JVB_ADVERTISE_IP=
|
|
# JVB UDP port for media traffic (must be open in firewall)
|
|
JVB_PORT=10000
|
|
|
|
# --- Monitoring Embed Ports (iframe embedding) ---
|
|
GRAFANA_EMBED_PORT=8894
|
|
ALERTMANAGER_EMBED_PORT=8895
|
|
|
|
# --- SMS Campaigns (Termux Android Bridge) ---
|
|
# ENABLE_SMS is the initial default; once saved in admin Settings, the DB value is authoritative
|
|
ENABLE_SMS=false
|
|
TERMUX_API_URL=http://10.0.0.193:5001
|
|
TERMUX_API_KEY=
|
|
SMS_DELAY_BETWEEN_MS=3000
|
|
SMS_MAX_RETRIES=3
|
|
SMS_RESPONSE_SYNC_INTERVAL_MS=30000
|
|
SMS_DEVICE_MONITOR_INTERVAL_MS=30000
|
|
|
|
# --- Monitoring (only used with --profile monitoring) ---
|
|
PROMETHEUS_PORT=9090
|
|
GRAFANA_PORT=3005
|
|
GRAFANA_ADMIN_PASSWORD=admin
|
|
GRAFANA_ROOT_URL=http://localhost:3005
|
|
CADVISOR_PORT=8086
|
|
NODE_EXPORTER_PORT=9100
|
|
REDIS_EXPORTER_PORT=9121
|
|
ALERTMANAGER_PORT=9093
|
|
GOTIFY_PORT=8889
|
|
GOTIFY_ADMIN_USER=admin
|
|
GOTIFY_ADMIN_PASSWORD=admin
|
|
|
|
# --- Bunker Ops (Fleet Management) ---
|
|
INSTANCE_LABEL= # Unique label for this instance (defaults to DOMAIN)
|
|
BUNKER_OPS_ENABLED=false # Enable remote metrics push to central server
|
|
BUNKER_OPS_REMOTE_WRITE_URL= # VictoriaMetrics remote_write endpoint (e.g., https://ops.example.com/api/v1/write)
|