This session completed Approach C end-to-end on marcelle (status=COMPLETED,
mkdocs untouched, idempotent on re-run). Four fixes landed:
1. template-engine.ts: dropped nginx/conf.d/*.hbs (default, api, services)
from renderAllTemplates AND renderAllTemplatesInMemory. The new
prod-style docker-compose.yml.hbs does NOT mount conf.d/ into the
nginx container ("Note: conf.d is NOT mounted (configs are generated
at startup from templates)" — nginx confs are baked into the nginx
Docker image). Writing them was a no-op orphan that showed up as 3
"modified" lines in preview unnecessarily.
Same reason removed nginx/nginx.conf from staticFiles.
2. templates/configs/{pangolin/resources.yml,prometheus/prometheus.yml,
grafana/datasources/datasources.yml}.hbs: synced byte-identical to
canonical changemaker.lite/configs/*. These ARE mounted into pangolin
tunnel + prometheus + grafana respectively. Preview now reports
"unchanged" for them on install.sh tenants.
3. templates/docker-compose.yml.hbs: dropped the CCP-tenant header
comment, making the template now BYTE-IDENTICAL (58907 bytes) to
canonical changemaker.lite/docker-compose.prod.yml. Even a 1-byte
comment difference caused docker compose to compute new config hashes
for every service, triggering full-stack recreates (including
ccp-agent — the Phase 6 self-destruct trap from upgrade.sh).
4. upgrade.service.ts:runReleaseUpgrade — composeUp now restricted to
core app services [api, admin, media-api, nginx] (same set as
image-upgrade.sh). Unscoped composeUp would recreate ccp-agent
mid-apply and orphan the runner. Until Approach C inherits the
deferred-ccp-agent-restart pattern from upgrade.sh, this restriction
keeps the apply path safe. Limitation: brand-new services in a
release won't auto-deploy via Approach C alone — operator must
follow with Approach A (full upgrade.sh) to pick them up.
E2E verification on marcelle:
- Apply: status=COMPLETED, duration<10s.
- mkdocs.yml md5 unchanged (38810d9df8b4258ad46a6739232cf88a).
- mkdocs/docs file count unchanged (242).
- docker-compose.yml now byte-identical to canonical (58907 bytes).
- app + api public sites: 200 both.
- Re-preview: ALL 10 files show "unchanged" — true idempotency.
Phase 6 acceptance gate met. Approach C now fully operational on the
install.sh fleet.
Bunker Admin
Changemaker Lite
A self-hosted campaign platform for community organizers who want to own their data.
Documentation · Website · Apache 2.0 License
Changemaker Lite consolidates advocacy campaigns, geographic mapping, volunteer canvassing, media management, newsletters, and administration into a single Docker Compose stack. One .env file, one command to start, everything under your control.
Why Changemaker Lite?
Most campaign tools are SaaS platforms that lock you into monthly subscriptions, hold your data hostage, and disappear when funding dries up. Changemaker Lite is different:
- Self-hosted -- runs on any machine with Docker. Your server, your data.
- All-in-one -- replaces 5-10 separate tools with a single integrated platform.
- Free and open source -- Apache 2.0 licensed. Fork it, modify it, make it yours.
- Privacy-first -- no telemetry, no third-party analytics, no data leaving your server.
What's Inside
Advocacy Campaigns
Let supporters look up their elected representatives by postal code and send advocacy emails in a few clicks. Track responses, moderate a public response wall, and monitor email delivery.
Interactive Map & Canvassing
Import thousands of addresses, draw canvassing areas, schedule volunteer shifts, and track door-to-door visits with GPS. Volunteers get a full-screen mobile map with real-time location tracking and visit recording.
Volunteer Portal
Volunteers get their own portal with shift sign-ups, canvassing assignments, activity tracking, a social calendar, and a friends system to stay connected with their team.
Media Library & Public Gallery
Upload campaign videos, manage metadata, schedule publishing, and share them through a public gallery. Includes GDPR-compliant analytics.
Landing Pages & Email Templates
Build campaign microsites with a drag-and-drop GrapesJS editor. Design email templates for consistent campaign communications.
SMS Campaigns, Newsletters & More
Send SMS campaigns via an Android bridge, sync subscribers to Listmonk for newsletters, recognize volunteers on a Wall of Fame leaderboard, and monitor everything with built-in Prometheus + Grafana observability.
Quick Start
Production (pre-built images)
# 1. One-command install: checks host ports, downloads tarball, runs config wizard
curl -fsSL https://gitea.bnkops.com/admin/changemaker.lite/raw/branch/main/scripts/install.sh | bash
# 2. Start services (first pull ~3 min + ~90s stabilization)
cd ~/changemaker.lite && docker compose up -d
# 3. Verify the install
bash scripts/test-deployment.sh --wait 60
The installer checks your host's port availability before extracting — no more half-started stacks from cockpit on :9090 or other surprises. The generated admin password is printed to stdout and saved to data/admin-credentials.txt (mode 0600). See Prerequisites for what you need lined up first.
Development (source)
git clone <repo-url> changemaker.lite
cd changemaker.lite
cp .env.example .env
# Edit .env -- set passwords, JWT secrets, admin credentials
docker compose up -d v2-postgres redis api admin
docker compose exec api npx prisma migrate deploy
docker compose exec api npx prisma db seed
Then open http://localhost:3000 and log in with the admin credentials from your .env.
Useful tools
bash scripts/validate-env.sh # re-check .env + host ports
bash scripts/test-deployment.sh # full deployment health sweep
bash scripts/pangolin-teardown.sh # wipe tunnel org before reinstall (dry-run by default)
bash scripts/ccp-deregister.sh # deregister from Changemaker Control Panel (dry-run by default)
Documentation
Full documentation is available at cmlite.org/docs/getting-started.
The docs site covers installation, configuration, all features, architecture details, production deployment with Pangolin tunnels, and troubleshooting. It is the authoritative and up-to-date reference for Changemaker Lite.
Architecture at a Glance
| Layer | Technology |
|---|---|
| API | Express.js + Prisma + PostgreSQL 16 |
| Media API | Fastify + Prisma (shared DB) |
| Frontend | React + Vite + Ant Design + Zustand |
| Reverse Proxy | Nginx (subdomain routing) |
| Cache & Queue | Redis + BullMQ |
| Newsletter | Listmonk |
| Monitoring | Prometheus + Grafana + Alertmanager |
| Tunneling | Pangolin (self-hosted Cloudflare alternative) |
The entire stack runs on Docker Compose. Enable optional modules (media, newsletters, SMS, monitoring) with feature flags in .env.
License
AI Disclaimer
AI tools were used to assist in the creation of this project. All generated code has been reviewed. Users should test all functionality to ensure it meets their requirements.












