Environment Variables¶
Changemaker Lite uses a single .env file at the project root to configure all services. Copy the example file to get started:
Security Essentials
- Change every
REQUIRED_STRONG_PASSWORD_CHANGE_THISvalue before starting services - Generate secrets with
openssl rand -hex 32(or-hex 16where noted) - Never commit
.envto version control - Use unique values for each secret — do not reuse JWT secrets as encryption keys
Quick Reference¶
Variables are grouped by service. Each table marks whether a variable is required for a basic deployment or optional (has a sensible default or only needed for specific features).
| Symbol | Meaning |
|---|---|
| Must be set before first run | |
| Has a working default; change for production | |
| Feature flag — opt-in |
General¶
| Variable | Default | Description |
|---|---|---|
NODE_ENV |
development |
Set to production for production deployments. Controls logging, error detail, and security checks. |
DOMAIN |
cmlite.org |
Root domain. Used for nginx subdomain routing (app.DOMAIN, api.DOMAIN, etc.). The root domain serves the MkDocs documentation site; all application routes live under app.DOMAIN. |
USER_ID |
1000 |
UID for container file ownership. Match your host user's UID (id -u). |
GROUP_ID |
1000 |
GID for container file ownership. Match your host user's GID (id -g). |
DOCKER_GROUP_ID |
984 |
GID of the docker group on the host. Needed for containers that access the Docker socket. Find with getent group docker. |
PostgreSQL (Main Database) ¶
The primary database for both the Express API and the Fastify Media API (shared).
| Variable | Default | Description |
|---|---|---|
V2_POSTGRES_USER |
changemaker |
Database username. |
V2_POSTGRES_PASSWORD |
— | Must change. Database password. |
V2_POSTGRES_DB |
changemaker_v2 |
Database name. |
V2_POSTGRES_PORT |
5433 |
Host port mapping. The container listens on 5432 internally. |
Connection string
The DATABASE_URL is constructed automatically inside Docker. If running locally, set:
JWT Authentication ¶
| Variable | Default | Description |
|---|---|---|
JWT_ACCESS_SECRET |
— | Secret for signing access tokens. Generate with openssl rand -hex 32. |
JWT_REFRESH_SECRET |
— | Secret for signing refresh tokens. Must differ from the access secret. |
JWT_ACCESS_EXPIRY |
15m |
Access token lifetime. Short-lived by design. |
JWT_REFRESH_EXPIRY |
7d |
Refresh token lifetime. Tokens are rotated atomically on each refresh. |
Encryption Key ¶
| Variable | Default | Description |
|---|---|---|
ENCRYPTION_KEY |
— | AES key for encrypting secrets stored in the database (SMTP passwords, API keys, etc.). Generate with openssl rand -hex 32. Must not reuse a JWT secret. Required in production (NODE_ENV=production). |
Initial Admin Account ¶
These credentials create the first super-admin user during database seeding (npx prisma db seed).
| Variable | Default | Description |
|---|---|---|
INITIAL_ADMIN_EMAIL |
admin@cmlite.org |
Email address for the initial admin. |
INITIAL_ADMIN_PASSWORD |
— | Must change. Must be 12+ characters with uppercase, lowercase, and a digit. Change this password after first login. |
API Server¶
| Variable | Default | Description |
|---|---|---|
API_PORT |
4000 |
Host port for the Express API. |
API_URL |
http://localhost:4000 |
Public URL of the API. Used for generating links in emails and QR codes. |
CORS_ORIGINS |
http://localhost:3000,http://localhost |
Comma-separated list of allowed CORS origins. Add your production domain (e.g., https://app.yourdomain.org) for production. |
Production CORS
If you deploy behind a tunnel (Pangolin, Cloudflare) and API requests fail with CORS errors, add your production app. subdomain here:
docker compose restart api
Admin GUI¶
| Variable | Default | Description |
|---|---|---|
ADMIN_PORT |
3000 |
Host port for the React admin dashboard. |
ADMIN_URL |
http://localhost:3000 |
Public URL of the admin GUI. |
Nginx Reverse Proxy¶
| Variable | Default | Description |
|---|---|---|
NGINX_HTTP_PORT |
80 |
HTTP port. All subdomains route through nginx. |
NGINX_HTTPS_PORT |
443 |
HTTPS port. SSL is typically handled by the tunnel provider (Pangolin/Cloudflare). |
Redis ¶
Shared by rate limiting, BullMQ job queues, geocoding cache, and session data.
| Variable | Default | Description |
|---|---|---|
REDIS_PASSWORD |
— | Must change. Redis requires authentication. |
REDIS_URL |
redis://:${REDIS_PASSWORD}@redis-changemaker:6379 |
Full connection URL. Uses the password variable automatically. |
Payments (Stripe) ¶
| Variable | Default | Description |
|---|---|---|
ENABLE_PAYMENTS |
false |
Set to true to enable the payments feature (memberships, products, donations). Stripe API keys are stored encrypted in the database via the admin settings page. |
Email / SMTP ¶
| Variable | Default | Description |
|---|---|---|
SMTP_HOST |
mailhog-changemaker |
SMTP server. Default points to the MailHog dev container. |
SMTP_PORT |
1025 |
SMTP port. 1025 for MailHog, 587 for most production SMTP. |
SMTP_USER |
(empty) | SMTP username. Not needed for MailHog. |
SMTP_PASS |
(empty) | SMTP password. |
SMTP_FROM |
noreply@cmlite.org |
"From" address on outgoing emails. |
SMTP_FROM_NAME |
Changemaker Lite |
Display name for the "From" header. |
EMAIL_TEST_MODE |
true |
When true, all emails go to MailHog instead of real SMTP. Set to false in production. |
TEST_EMAIL_RECIPIENT |
admin@cmlite.org |
Catch-all recipient when test mode is on. |
Development email
With EMAIL_TEST_MODE=true, all outgoing email is captured in MailHog at http://localhost:8025. No real emails are sent.
Listmonk (Newsletters) ¶
Listmonk handles newsletter/marketing campaigns. Sync with the main platform is opt-in.
| Variable | Default | Description |
|---|---|---|
LISTMONK_PORT |
9001 |
Listmonk web UI port. |
LISTMONK_DB_PORT |
5434 |
Listmonk's own PostgreSQL port (separate from the main DB). Uses 5434 to avoid conflict with the main PostgreSQL (5432 internal / 5433 host). |
LISTMONK_DB_USER |
listmonk |
Listmonk database user. |
LISTMONK_DB_PASSWORD |
— | Listmonk database password. |
LISTMONK_DB_NAME |
listmonk |
Listmonk database name. |
LISTMONK_WEB_ADMIN_USER |
admin |
Login for the Listmonk web dashboard. |
LISTMONK_WEB_ADMIN_PASSWORD |
— | Password for the Listmonk web dashboard. |
LISTMONK_API_USER |
v2-api |
API user for programmatic access (auto-created by init container). |
LISTMONK_API_TOKEN |
— | Token for API user. Generate with openssl rand -hex 16. |
LISTMONK_ADMIN_USER |
v2-api |
Same as LISTMONK_API_USER (used by the sync service). |
LISTMONK_ADMIN_PASSWORD |
— | Same as LISTMONK_API_TOKEN. |
LISTMONK_SYNC_ENABLED |
false |
Set to true to sync participants/locations/users to Listmonk lists. |
LISTMONK_WEBHOOK_SECRET |
(empty) | Shared secret for Listmonk webhook callbacks. |
LISTMONK_PROXY_PORT |
9002 |
Nginx proxy port for Listmonk. |
Listmonk SMTP settings
Listmonk has its own SMTP configuration, separate from the main platform's:
| Variable | Default | Description |
|---|---|---|
LISTMONK_SMTP_HOST |
mailhog-changemaker |
SMTP host for Listmonk. |
LISTMONK_SMTP_PORT |
1025 |
SMTP port. |
LISTMONK_SMTP_USER |
(empty) | SMTP username. |
LISTMONK_SMTP_PASSWORD |
(empty) | SMTP password. |
LISTMONK_SMTP_TLS_TYPE |
none |
TLS mode: none, STARTTLS, or TLS. |
LISTMONK_SMTP_FROM |
Changemaker Lite <noreply@cmlite.org> |
From address for newsletters. |
Represent API (Canadian Electoral Data)¶
| Variable | Default | Description |
|---|---|---|
REPRESENT_API_URL |
https://represent.opennorth.ca |
OpenNorth Represent API endpoint. Used for postal code → representative lookups. No API key required. |
NocoDB (Data Browser) ¶
Read-only database browser. Useful for inspecting data without SQL.
| Variable | Default | Description |
|---|---|---|
NOCODB_V2_PORT / NOCODB_PORT |
8091 |
Host port for the NocoDB web UI. |
NOCODB_URL |
http://changemaker-v2-nocodb:8080 |
Internal Docker URL. |
NC_ADMIN_EMAIL |
admin@cmlite.org |
NocoDB admin email. |
NC_ADMIN_PASSWORD |
— | NocoDB admin password. |
Media Manager ¶
Video library with upload, analytics, scheduling, and a public gallery.
| Variable | Default | Description |
|---|---|---|
ENABLE_MEDIA_FEATURES |
false |
Set to true to enable the media system. |
MEDIA_API_PORT |
4100 |
Fastify media API port. |
MEDIA_API_PUBLIC_URL |
http://media-api:4100 |
Internal URL for the media API container. |
MEDIA_ROOT |
/media/library |
Path to the video library inside the container. |
MEDIA_UPLOADS |
/media/uploads |
Path for upload processing. |
MAX_UPLOAD_SIZE_GB |
10 |
Maximum single-file upload size in gigabytes. |
PUBLIC_MEDIA_PORT |
3100 |
Public media gallery server port. |
VIDEO_PLAYER_DEBUG |
false |
Enable verbose video player logging. |
Analytics & scheduling settings
| Variable | Default | Description |
|---|---|---|
VIDEO_ANALYTICS_RETENTION_DAYS |
90 |
Days to retain analytics data. GDPR-compliant with IP hashing. |
VIDEO_ANALYTICS_IP_HASHING_ENABLED |
true |
Hash viewer IPs for privacy. |
VIDEO_SCHEDULE_DEFAULT_TIMEZONE |
UTC |
Default timezone for scheduled publishing. |
VIDEO_SCHEDULE_NOTIFICATION_ENABLED |
true |
Notify on scheduled publish/unpublish. |
VIDEO_PREVIEW_LINK_EXPIRY_HOURS |
24 |
Preview link JWT expiry (hours). |
Gitea (Git Hosting) ¶
Self-hosted Git repository. Optional service.
| Variable | Default | Description |
|---|---|---|
GITEA_URL |
http://gitea-changemaker:3000 |
Internal container URL for Gitea. |
GITEA_PORT / GITEA_WEB_PORT |
3030 |
Gitea web UI port. |
GITEA_SSH_PORT |
2222 |
Gitea SSH port for git operations. |
GITEA_DB_TYPE |
mysql |
Database type (Gitea uses its own MySQL). |
GITEA_DB_HOST |
gitea-db:3306 |
Internal database host. |
GITEA_DB_NAME |
gitea |
Database name. |
GITEA_DB_USER |
gitea |
Database user. |
GITEA_DB_PASSWD |
— | Gitea database password. |
GITEA_DB_ROOT_PASSWORD |
— | MySQL root password for Gitea. |
GITEA_ROOT_URL |
https://git.cmlite.org |
Public-facing URL for Gitea. |
GITEA_DOMAIN |
git.cmlite.org |
Domain used in git clone URLs. |
Gitea Docs Comments
Enable comments on MkDocs documentation pages, backed by Gitea Issues.
| Variable | Default | Description |
|---|---|---|
GITEA_COMMENTS_ENABLED |
false |
Enable comments on MkDocs pages. |
GITEA_API_TOKEN |
(empty) | Personal access token with repo write scope. Create in Gitea → Settings → Applications. |
GITEA_COMMENTS_REPO_OWNER |
(empty) | Gitea username that owns the docs-comments repo. |
GITEA_COMMENTS_REPO_NAME |
docs-comments |
Repository name (auto-created via admin setup). |
GITEA_OAUTH_CLIENT_ID |
(empty) | OAuth2 application client ID (create in Gitea → Settings → Applications → OAuth2). |
GITEA_OAUTH_CLIENT_SECRET |
(empty) | OAuth2 application client secret. |
n8n (Workflow Automation) ¶
| Variable | Default | Description |
|---|---|---|
N8N_PORT |
5678 |
n8n web UI port. |
N8N_HOST |
n8n.cmlite.org |
Public hostname for n8n. |
N8N_ENCRYPTION_KEY |
— | Encryption key for n8n credentials storage. |
N8N_USER_EMAIL |
admin@example.com |
Initial n8n admin email. |
N8N_USER_PASSWORD |
— | Initial n8n admin password. |
GENERIC_TIMEZONE |
UTC |
Timezone for n8n cron triggers. |
MkDocs (Documentation)¶
| Variable | Default | Description |
|---|---|---|
MKDOCS_PORT |
4003 |
MkDocs dev server port (live preview). |
MKDOCS_SITE_SERVER_PORT |
4004 |
MkDocs static site server port. |
BASE_DOMAIN |
https://cmlite.org |
Base URL for generated documentation links. |
MKDOCS_PREVIEW_URL |
http://mkdocs:8000 |
Internal container URL. |
MKDOCS_DOCS_PATH |
/mkdocs/docs |
Documentation source directory inside the container. |
Code Server (Web IDE)¶
| Variable | Default | Description |
|---|---|---|
CODE_SERVER_PORT |
8888 |
Code Server web UI port. |
CODE_SERVER_URL |
http://code-server:8080 |
Internal container URL. |
USER_NAME |
coder |
User account inside the Code Server container. |
Homepage (Service Dashboard)¶
| Variable | Default | Description |
|---|---|---|
HOMEPAGE_PORT |
3010 |
Homepage web UI port. |
HOMEPAGE_EMBED_PORT |
8887 |
Port for iframe embedding in admin. |
HOMEPAGE_VAR_BASE_URL |
http://localhost |
Base URL used in Homepage service links. |
Mini QR (QR Code Generator)¶
| Variable | Default | Description |
|---|---|---|
MINI_QR_PORT |
8089 |
Mini QR direct access port. |
MINI_QR_URL |
http://mini-qr:8080 |
Internal container URL. |
MINI_QR_EMBED_PORT |
8885 |
Port for iframe embedding (walk sheets, cut exports). |
Excalidraw (Whiteboard)¶
| Variable | Default | Description |
|---|---|---|
EXCALIDRAW_PORT |
8090 |
Excalidraw web UI port. |
EXCALIDRAW_URL |
http://excalidraw-changemaker:80 |
Internal container URL. |
EXCALIDRAW_EMBED_PORT |
8886 |
Port for iframe embedding. |
EXCALIDRAW_WS_URL |
wss://draw.cmlite.org |
WebSocket URL for real-time collaboration. |
Vaultwarden (Password Manager) ¶
Self-hosted Bitwarden-compatible password manager. Optional service.
| Variable | Default | Description |
|---|---|---|
VAULTWARDEN_PORT |
8445 |
Vaultwarden web UI port. |
VAULTWARDEN_URL |
http://vaultwarden-changemaker:80 |
Internal container URL. |
VAULTWARDEN_EMBED_PORT |
8890 |
Port for iframe embedding in admin. |
VAULTWARDEN_ADMIN_TOKEN |
(empty) | Admin panel token (access at /admin). Generate with openssl rand -hex 32. |
VAULTWARDEN_DOMAIN |
https://vault.cmlite.org |
Public-facing URL. Must use HTTPS — Bitwarden web vault enforces HTTPS for account creation. Set to your Pangolin tunnel URL. |
VAULTWARDEN_SIGNUPS_ALLOWED |
false |
Allow new user self-registration. Keep false and use admin panel invites. |
VAULTWARDEN_WEBSOCKET_ENABLED |
true |
Enable WebSocket notifications for real-time sync. |
VAULTWARDEN_SMTP_SECURITY |
off |
SMTP security mode: off for MailHog, starttls or force_tls for production. Uses the main SMTP_* variables for host/credentials. |
Initial setup
The vaultwarden-init container automatically invites the INITIAL_ADMIN_EMAIL user when starting. Check MailHog (or your SMTP) for the invitation email.
Rocket.Chat (Team Chat) ¶
Self-hosted team chat for volunteer coordination. Requires MongoDB (auto-configured).
| Variable | Default | Description |
|---|---|---|
ENABLE_CHAT |
false |
Set to true to enable the Rocket.Chat integration. The initial default; once saved in admin Settings, the DB value is authoritative. |
ROCKETCHAT_ADMIN_USER |
rcadmin |
Rocket.Chat admin username. |
ROCKETCHAT_ADMIN_PASSWORD |
— | Rocket.Chat admin password. |
ROCKETCHAT_URL |
http://rocketchat-changemaker:3000 |
Internal container URL. |
ROCKETCHAT_EMBED_PORT |
8891 |
Port for iframe embedding in admin. |
Gancio (Event Management) ¶
Self-hosted event management platform. Uses the shared PostgreSQL database (auto-created by init-gancio-db.sh).
| Variable | Default | Description |
|---|---|---|
GANCIO_PORT |
8092 |
Gancio web UI port. |
GANCIO_URL |
http://gancio-changemaker:13120 |
Internal container URL. |
GANCIO_EMBED_PORT |
8892 |
Port for iframe embedding in admin. |
GANCIO_BASE_URL |
https://events.cmlite.org |
Public-facing URL for Gancio. Used in event links. |
GANCIO_ADMIN_USER |
admin |
Gancio admin username for shift-to-event sync (OAuth login). |
GANCIO_ADMIN_PASSWORD |
— | Gancio admin password. |
GANCIO_SYNC_ENABLED |
false |
Set to true to enable automatic shift → Gancio event synchronization. |
Jitsi Meet (Video Conferencing) ¶
Self-hosted video conferencing with JWT authentication. Integrates with Rocket.Chat for in-channel video calls.
| Variable | Default | Description |
|---|---|---|
ENABLE_MEET |
false |
Set to true to enable the Jitsi Meet integration. The initial default; once saved in admin Settings, the DB value is authoritative. |
JITSI_APP_ID |
changemaker |
JWT application ID. Must match across Jitsi Prosody, Rocket.Chat app settings, and JWT_ACCEPTED_ISSUERS/JWT_ACCEPTED_AUDIENCES. |
JITSI_APP_SECRET |
— | JWT secret for signing Jitsi tokens. Generate with openssl rand -hex 32. Shared between Jitsi Prosody, Rocket.Chat, and the API. |
JITSI_JICOFO_AUTH_PASSWORD |
— | Internal XMPP password for Jicofo (conference focus). Generate with openssl rand -hex 16. |
JITSI_JVB_AUTH_PASSWORD |
— | Internal XMPP password for JVB (video bridge). Generate with openssl rand -hex 16. |
JITSI_EMBED_PORT |
8893 |
Port for iframe embedding in admin. |
JITSI_URL |
http://jitsi-web-changemaker:80 |
Internal container URL. |
JVB_ADVERTISE_IP |
(empty) | Server's public IP address. Required in production for NAT traversal so remote participants can connect. |
JVB_PORT |
10000 |
UDP port for media traffic. Must be open in your firewall. |
Production requirements
JVB_ADVERTISE_IPmust be set to your server's public IP for calls to work outside the local network.- Port
10000/udpmust be open in your firewall for media traffic. - Calls must go through the production domain (not localhost) for SSL/JWT to work.
SMS Campaigns (Termux Android Bridge) ¶
Send SMS messages via an Android phone running the Termux API server. The phone acts as an SMS gateway.
| Variable | Default | Description |
|---|---|---|
ENABLE_SMS |
false |
Set to true to enable SMS campaigns. The initial default; once saved in admin Settings, the DB value is authoritative. |
TERMUX_API_URL |
http://10.0.0.193:5001 |
URL of the Termux API server running on the Android phone. |
TERMUX_API_KEY |
(empty) | API key for authenticating with the Termux server (HMAC auth via X-API-Key header). |
SMS_DELAY_BETWEEN_MS |
3000 |
Delay between sending individual SMS messages (ms). Prevents carrier throttling. |
SMS_MAX_RETRIES |
3 |
Maximum retry attempts for failed SMS sends. |
SMS_RESPONSE_SYNC_INTERVAL_MS |
30000 |
How often to poll the phone's inbox for responses (ms). |
SMS_DEVICE_MONITOR_INTERVAL_MS |
30000 |
How often to check device health — battery, connectivity (ms). |
GUI configuration
The Termux API URL and API key can also be configured from Admin → Settings → SMS. Database values override these env vars when set.
MailHog (Development Email)¶
| Variable | Default | Description |
|---|---|---|
MAILHOG_SMTP_PORT |
1025 |
SMTP port for capturing emails. |
MAILHOG_WEB_PORT |
8025 |
Web UI to view captured emails. |
NAR (National Address Register) ¶
Canadian address data import for geographic canvassing.
| Variable | Default | Description |
|---|---|---|
NAR_DATA_DIR |
/data |
Path to extracted NAR data inside the container. Expects YYYYMM/Addresses/ and YYYYMM/Locations/ subdirectories. Mount via ./data:/data:ro in Docker Compose. |
Download NAR data from Statistics Canada.
Geocoding ¶
Multi-provider geocoding for address resolution. Works out of the box with free providers; optional paid providers improve accuracy.
| Variable | Default | Description |
|---|---|---|
MAPBOX_API_KEY |
(empty) | Mapbox API key for improved geocoding accuracy. Free tier: 100k requests/month. Sign up. |
GEOCODING_RATE_LIMIT_MS |
1100 |
Delay between requests to free providers (ms). Respects rate limits. |
GEOCODING_CACHE_ENABLED |
true |
Enable Redis-backed geocoding cache. |
GEOCODING_CACHE_TTL_HOURS |
24 |
Cache lifetime in hours. |
GOOGLE_MAPS_API_KEY |
(empty) | Google Maps API key. Most accurate but $0.005/request after free tier. |
GOOGLE_MAPS_ENABLED |
false |
Enable Google Maps as a geocoding provider. |
GEOCODING_PARALLEL_ENABLED |
true |
Enable parallel geocoding for bulk imports (~10x speedup). |
GEOCODING_BATCH_SIZE |
10 |
Number of concurrent geocoding requests during bulk operations. |
BULK_GEOCODE_ENABLED |
true |
Enable bulk re-geocoding from the admin UI. |
BULK_GEOCODE_MAX_BATCH |
5000 |
Maximum locations per bulk geocoding run. |
Overpass / Area Import ¶
OpenStreetMap data import for map enrichment.
| Variable | Default | Description |
|---|---|---|
OVERPASS_API_URL |
https://overpass-api.de/api/interpreter |
Overpass API endpoint. Use a private instance for heavy usage. |
OVERPASS_MIN_DELAY_MS |
30000 |
Minimum delay between requests (ms). The public API requires 30 seconds. |
AREA_IMPORT_MAX_GRID_POINTS |
500 |
Maximum reverse-geocode grid points per area import. |
Pangolin Tunnel ¶
Expose services to the internet without port forwarding, using a self-hosted Pangolin instance.
| Variable | Default | Description |
|---|---|---|
PANGOLIN_API_URL |
https://api.bnkserve.org/v1 |
Pangolin server API endpoint. |
PANGOLIN_API_KEY |
(empty) | API key for Pangolin management. |
PANGOLIN_ORG_ID |
(empty) | Organization ID in Pangolin. |
PANGOLIN_SITE_ID |
(empty) | Site ID (populated after setup via admin GUI). |
PANGOLIN_ENDPOINT |
https://pangolin.bnkserve.org |
Pangolin tunnel endpoint. |
PANGOLIN_NEWT_ID |
(empty) | Newt client ID (populated after setup). |
PANGOLIN_NEWT_SECRET |
(empty) | Newt client secret (populated after setup). |
Setup flow
Configure the tunnel from Admin → Settings → Pangolin. The setup wizard walks you through creating a site, copying credentials, and connecting the Newt container. See Deployment for the full guide.
Monitoring ¶
These services are behind the monitoring Docker Compose profile. Start them with:
| Variable | Default | Description |
|---|---|---|
PROMETHEUS_PORT |
9090 |
Prometheus web UI / query port. |
GRAFANA_PORT |
3005 |
Grafana dashboard port. |
GRAFANA_ADMIN_PASSWORD |
admin |
Change in production. |
GRAFANA_ROOT_URL |
http://localhost:3005 |
Public URL for Grafana (used in links). |
CADVISOR_PORT |
8086 |
cAdvisor container metrics port. |
NODE_EXPORTER_PORT |
9100 |
Prometheus node exporter port. |
REDIS_EXPORTER_PORT |
9121 |
Redis metrics exporter port. |
ALERTMANAGER_PORT |
9093 |
Alertmanager web UI port. |
GOTIFY_PORT |
8889 |
Gotify push notification port. |
GOTIFY_ADMIN_USER |
admin |
Gotify admin username. |
GOTIFY_ADMIN_PASSWORD |
admin |
Change in production. |
GRAFANA_EMBED_PORT |
8894 |
Port for iframe embedding Grafana in admin. |
ALERTMANAGER_EMBED_PORT |
8895 |
Port for iframe embedding Alertmanager in admin. |
Bunker Ops (Fleet Management) ¶
Remote metrics push for managing multiple Changemaker Lite instances from a central monitoring server.
| Variable | Default | Description |
|---|---|---|
INSTANCE_LABEL |
(empty) | Unique label for this instance (used as a Prometheus metric label). Falls back to DOMAIN if empty. |
BUNKER_OPS_ENABLED |
false |
Enable remote metrics push to a central VictoriaMetrics server. |
BUNKER_OPS_REMOTE_WRITE_URL |
(empty) | VictoriaMetrics remote_write endpoint (e.g., https://ops.example.com/api/v1/write). |
Generating Secrets¶
Use these commands to generate all required secrets at once:
# JWT secrets (two separate values)
echo "JWT_ACCESS_SECRET=$(openssl rand -hex 32)"
echo "JWT_REFRESH_SECRET=$(openssl rand -hex 32)"
# Encryption key (must differ from JWT secrets)
echo "ENCRYPTION_KEY=$(openssl rand -hex 32)"
# Database and Redis passwords
echo "V2_POSTGRES_PASSWORD=$(openssl rand -hex 24)"
echo "REDIS_PASSWORD=$(openssl rand -hex 24)"
# Listmonk
echo "LISTMONK_DB_PASSWORD=$(openssl rand -hex 24)"
echo "LISTMONK_WEB_ADMIN_PASSWORD=$(openssl rand -hex 16)"
LISTMONK_TOKEN=$(openssl rand -hex 16)
echo "LISTMONK_API_TOKEN=$LISTMONK_TOKEN"
echo "LISTMONK_ADMIN_PASSWORD=$LISTMONK_TOKEN"
# Supporting services
echo "GITEA_DB_PASSWD=$(openssl rand -hex 24)"
echo "GITEA_DB_ROOT_PASSWORD=$(openssl rand -hex 24)"
echo "N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)"
echo "N8N_USER_PASSWORD=$(openssl rand -hex 16)"
echo "NC_ADMIN_PASSWORD=$(openssl rand -hex 16)"
echo "INITIAL_ADMIN_PASSWORD=$(openssl rand -base64 18)"
# Vaultwarden
echo "VAULTWARDEN_ADMIN_TOKEN=$(openssl rand -hex 32)"
# Rocket.Chat
echo "ROCKETCHAT_ADMIN_PASSWORD=$(openssl rand -hex 16)"
# Gancio
echo "GANCIO_ADMIN_PASSWORD=$(openssl rand -hex 16)"
# Jitsi Meet
echo "JITSI_APP_SECRET=$(openssl rand -hex 32)"
echo "JITSI_JICOFO_AUTH_PASSWORD=$(openssl rand -hex 16)"
echo "JITSI_JVB_AUTH_PASSWORD=$(openssl rand -hex 16)"
Tip
Copy the output and paste the values into your .env file. The INITIAL_ADMIN_PASSWORD uses base64 encoding to ensure it contains uppercase, lowercase, and digits (meeting the password policy).
Minimal vs Full Deployment¶
For a basic deployment with campaigns, map, and admin:
For the complete platform including media, newsletters, monitoring, and all services:
# Everything above, plus:
ENABLE_MEDIA_FEATURES=true
ENABLE_PAYMENTS=true
ENABLE_CHAT=true
ENABLE_MEET=true
ENABLE_SMS=true
LISTMONK_SYNC_ENABLED=true
GANCIO_SYNC_ENABLED=true
LISTMONK_DB_PASSWORD=...
LISTMONK_WEB_ADMIN_PASSWORD=...
LISTMONK_API_TOKEN=...
NC_ADMIN_PASSWORD=...
GITEA_DB_PASSWD=...
GITEA_DB_ROOT_PASSWORD=...
N8N_ENCRYPTION_KEY=...
N8N_USER_PASSWORD=...
VAULTWARDEN_ADMIN_TOKEN=...
ROCKETCHAT_ADMIN_PASSWORD=...
GANCIO_ADMIN_PASSWORD=...
JITSI_APP_SECRET=...
JITSI_JICOFO_AUTH_PASSWORD=...
JITSI_JVB_AUTH_PASSWORD=...
JVB_ADVERTISE_IP=your.public.ip.here
EMAIL_TEST_MODE=false
SMTP_HOST=smtp.your-provider.com
SMTP_PORT=587
SMTP_USER=you@example.com
SMTP_PASS=your-smtp-password