---
title: Services
description: All services that make up the Changemaker Lite platform — configuration, ports, and links to upstream docs.
icon: material/server-network
tags:
  - reference
  - operator
  - services
  - docker
---

# Services

Changemaker Lite orchestrates 30+ services via Docker Compose. This page is your map to every service: what it does, how to reach it, and where to find its upstream documentation.

---

## Core Platform

The essential services that power the application.

<div class="grid cards" markdown>

-   :material-api:{ .lg .middle } **Express API**

    ---

    Main V2 API server. Handles authentication, campaigns, map, shifts, pages, email, and all business logic. Prisma ORM with PostgreSQL.

    **Port:** `4000` &middot; **Container:** `changemaker-v2-api`

    [:octicons-arrow-right-24: API Reference](../api/index.md)

-   :material-video:{ .lg .middle } **Fastify Media API**

    ---

    Video library server. Upload, metadata extraction (FFprobe), analytics, scheduled publishing, and public gallery. Shares the same PostgreSQL database.

    **Port:** `4100` &middot; **Container:** `changemaker-media-api`

    [:octicons-arrow-right-24: Media Guide](../admin/media/index.md)

-   :material-react:{ .lg .middle } **Admin GUI**

    ---

    React single-page application (Vite + Ant Design + Zustand). Serves the admin dashboard, public campaign pages, volunteer portal, and media gallery &mdash; all from one build.

    **Port:** `3000` &middot; **Container:** `changemaker-v2-admin`

    [:octicons-arrow-right-24: Feature Guides](../getting-started/features.md)

-   :material-database:{ .lg .middle } **PostgreSQL 16**

    ---

    Primary database shared by both APIs. Managed by Prisma migrations. Contains 190+ tables covering users, campaigns, locations, shifts, media, and more.

    **Port:** `5433` (host) / `5432` (container) &middot; **Container:** `changemaker-v2-postgres`

    [:octicons-arrow-right-24: PostgreSQL Docs](https://www.postgresql.org/docs/16/){ target="_blank" }

-   :material-memory:{ .lg .middle } **Redis**

    ---

    In-memory store for rate limiting, BullMQ job queues (email, video scheduling), geocoding cache, and session data. Requires authentication.

    **Port:** `6379` &middot; **Container:** `redis-changemaker`

    [:octicons-arrow-right-24: Redis Docs](https://redis.io/docs/){ target="_blank" }

-   :material-web:{ .lg .middle } **Nginx**

    ---

    Reverse proxy handling all subdomain routing (`app.`, `api.`, `media.`, `docs.`, etc.). Includes security headers (HSTS, CSP, Permissions-Policy) and WebSocket support.

    **Port:** `80` / `443` &middot; **Container:** `changemaker-v2-nginx`

    [:octicons-arrow-right-24: Nginx Docs](https://nginx.org/en/docs/){ target="_blank" }

</div>

---

## Communication & Email

<div class="grid cards" markdown>

-   :material-email-newsletter:{ .lg .middle } **Listmonk**

    ---

    Self-hosted newsletter and mailing list manager. Drop-in replacement for Mailchimp. Opt-in sync with the main platform imports participants, locations, and users as subscriber lists.

    **Port:** `9001` &middot; **Container:** `listmonk-app` &middot; **Subdomain:** `listmonk.DOMAIN`

    [:octicons-arrow-right-24: Listmonk Docs](https://listmonk.app/docs/){ target="_blank" }

-   :material-email-check:{ .lg .middle } **MailHog**

    ---

    Email capture for development. All outgoing email is intercepted and displayed in a web UI when `EMAIL_TEST_MODE=true`. No real emails are sent.

    **Port:** `8025` (web) / `1025` (SMTP) &middot; **Container:** `mailhog-changemaker` &middot; **Subdomain:** `mail.DOMAIN`

    [:octicons-arrow-right-24: MailHog GitHub](https://github.com/mailhog/MailHog){ target="_blank" }

</div>

---

## Content & Editing

<div class="grid cards" markdown>

-   :material-book-open-page-variant:{ .lg .middle } **MkDocs**

    ---

    Material-themed documentation site with full-text search, blog, social cards, and Jinja2 template overrides. Two containers: live preview (dev) and static site (production).

    **Port:** `4003` (dev) / `4004` (static) &middot; **Container:** `mkdocs-changemaker` &middot; **Subdomain:** `docs.DOMAIN`

    [:octicons-arrow-right-24: MkDocs Material](https://squidfunk.github.io/mkdocs-material/){ target="_blank" }

-   :material-microsoft-visual-studio-code:{ .lg .middle } **Code Server**

    ---

    Full VS Code in the browser. Edit configuration files, templates, and documentation from anywhere without SSH. Supports extensions.

    **Port:** `8888` &middot; **Container:** `code-server-changemaker` &middot; **Subdomain:** `code.DOMAIN`

    [:octicons-arrow-right-24: Code Server Docs](https://coder.com/docs/code-server){ target="_blank" }

</div>

---

## Data & Automation

<div class="grid cards" markdown>

-   :material-table:{ .lg .middle } **NocoDB**

    ---

    Airtable-alternative database browser. Provides a spreadsheet-like interface to browse, filter, sort, and export campaign data. Read-only access to the main database.

    **Port:** `8091` &middot; **Container:** `changemaker-v2-nocodb` &middot; **Subdomain:** `db.DOMAIN`

    [:octicons-arrow-right-24: NocoDB Docs](https://docs.nocodb.com/){ target="_blank" }

-   :material-robot:{ .lg .middle } **n8n**

    ---

    Visual workflow automation platform. Connect APIs, trigger actions on events, schedule tasks, and build custom integrations &mdash; all without code. 400+ built-in integrations.

    **Port:** `5678` &middot; **Container:** `n8n-changemaker` &middot; **Subdomain:** `n8n.DOMAIN`

    [:octicons-arrow-right-24: n8n Docs](https://docs.n8n.io/){ target="_blank" }

-   :material-git:{ .lg .middle } **Gitea**

    ---

    Self-hosted Git repository hosting. Version control for campaign code, configuration, templates, and documentation. Includes issues, pull requests, and CI/CD.

    **Port:** `3030` (web) / `2222` (SSH) &middot; **Container:** `gitea-changemaker` &middot; **Subdomain:** `git.DOMAIN`

    [:octicons-arrow-right-24: Gitea Docs](https://docs.gitea.com/){ target="_blank" }

</div>

---

## Utilities

<div class="grid cards" markdown>

-   :material-qrcode:{ .lg .middle } **Mini QR**

    ---

    Lightweight QR code generator. Produces PNG images for walk sheets, campaign materials, and event signage. Embedded in the admin dashboard via iframe.

    **Port:** `8089` &middot; **Container:** `mini-qr` &middot; **Subdomain:** `qr.DOMAIN`

-   :material-home:{ .lg .middle } **Homepage**

    ---

    Service dashboard showing the status of all containers at a glance. Auto-generated `services.yaml` from `config.sh` provides both production and local links.

    **Port:** `3010` &middot; **Container:** `homepage-changemaker` &middot; **Subdomain:** `home.DOMAIN`

    [:octicons-arrow-right-24: Homepage Docs](https://gethomepage.dev/){ target="_blank" }

-   :material-draw:{ .lg .middle } **Excalidraw**

    ---

    Collaborative whiteboard for brainstorming, diagramming, and visual planning. Real-time collaboration via WebSocket.

    **Port:** `8090` &middot; **Container:** `excalidraw-changemaker` &middot; **Subdomain:** `draw.DOMAIN`

    [:octicons-arrow-right-24: Excalidraw](https://excalidraw.com/){ target="_blank" }

-   :material-shield-lock:{ .lg .middle } **Vaultwarden**

    ---

    Self-hosted Bitwarden-compatible password manager. Secure credential sharing for campaign teams. Requires HTTPS for account creation; local browsing works on HTTP.

    **Port:** `8445` &middot; **Container:** `vaultwarden-changemaker` &middot; **Subdomain:** `vault.DOMAIN`

    [:octicons-arrow-right-24: Vaultwarden Wiki](https://github.com/dani-garcia/vaultwarden/wiki){ target="_blank" }

</div>

---

## Team Communication

<div class="grid cards" markdown>

-   :material-chat:{ .lg .middle } **Rocket.Chat**

    ---

    Self-hosted team chat for volunteer coordination. Supports channels, direct messaging, threads, and file sharing. Embeddable in the admin dashboard via iframe. Enable with `ENABLE_CHAT=true`.

    **Port:** `3000` (internal) &middot; **Container:** `rocketchat-changemaker` &middot; **Subdomain:** `chat.DOMAIN`

    [:octicons-arrow-right-24: Rocket.Chat Docs](https://docs.rocket.chat/){ target="_blank" }

-   :material-video:{ .lg .middle } **Jitsi Meet**

    ---

    Self-hosted video conferencing with JWT authentication. Four containers (web, Prosody, Jicofo, JVB) provide the full video call stack. Integrated with Rocket.Chat for one-click calls from channels and DMs. Enable with `ENABLE_MEET=true`.

    **Containers:** `jitsi-web`, `jitsi-prosody`, `jitsi-jicofo`, `jitsi-jvb` &middot; **Subdomain:** `meet.DOMAIN`

    [:octicons-arrow-right-24: Setup Guide](../admin/services/integrations.md) &middot; [:octicons-arrow-right-24: Jitsi Docs](https://jitsi.github.io/handbook/){ target="_blank" }

-   :material-calendar-multiple:{ .lg .middle } **Gancio**

    ---

    Self-hosted event management platform. Automatic shift-to-event sync (when `GANCIO_SYNC_ENABLED=true`) publishes shifts as public events. Uses the shared PostgreSQL database. Embeddable calendar widget available for MkDocs pages.

    **Port:** `8092` &middot; **Container:** `gancio-changemaker` &middot; **Subdomain:** `events.DOMAIN`

    [:octicons-arrow-right-24: Gancio Docs](https://gancio.org/){ target="_blank" }

</div>

---

## Networking & Tunneling

<div class="grid cards" markdown>

-   :material-tunnel:{ .lg .middle } **Pangolin + Newt**

    ---

    Self-hosted tunnel server with the Newt client container. Exposes your services to the internet without port forwarding. Handles SSL/TLS, works behind CGNAT and double NAT.

    **Container:** `newt-changemaker` &middot; Managed from **Admin &rarr; Settings &rarr; Tunnel**

    [:octicons-arrow-right-24: Deployment Guide](../deployment/index.md#pangolin) &middot; [:octicons-arrow-right-24: Pangolin GitHub](https://github.com/fosrl/pangolin){ target="_blank" }

</div>

---

## Monitoring Stack

These services run behind the `monitoring` Docker Compose profile. Start them with:

```bash
docker compose --profile monitoring up -d
```

<div class="grid cards" markdown>

-   :material-chart-line:{ .lg .middle } **Prometheus**

    ---

    Metrics collection and time-series database. Scrapes 12 custom `cm_*` application metrics plus container, host, and Redis metrics. Pre-configured alert rules.

    **Port:** `9090` &middot; **Container:** `prometheus-changemaker`

    [:octicons-arrow-right-24: Prometheus Docs](https://prometheus.io/docs/){ target="_blank" }

-   :material-chart-box:{ .lg .middle } **Grafana**

    ---

    Metrics visualization with 3 auto-provisioned dashboards: API Overview, Infrastructure, and Campaign Activity. Supports custom dashboards and alerting.

    **Port:** `3005` &middot; **Container:** `grafana-changemaker` &middot; **Subdomain:** `grafana.DOMAIN`

    [:octicons-arrow-right-24: Grafana Docs](https://grafana.com/docs/grafana/latest/){ target="_blank" }

-   :material-bell-alert:{ .lg .middle } **Alertmanager**

    ---

    Alert routing and notification delivery. Receives alerts from Prometheus and dispatches to Gotify, email, or webhooks based on configurable rules.

    **Port:** `9093` &middot; **Container:** `alertmanager-changemaker`

    [:octicons-arrow-right-24: Alertmanager Docs](https://prometheus.io/docs/alerting/latest/alertmanager/){ target="_blank" }

-   :material-docker:{ .lg .middle } **cAdvisor**

    ---

    Container resource metrics. Exposes CPU, memory, network, and filesystem usage per container for Prometheus to scrape.

    **Port:** `8086` &middot; **Container:** `cadvisor-changemaker`

    [:octicons-arrow-right-24: cAdvisor GitHub](https://github.com/google/cadvisor){ target="_blank" }

-   :material-server:{ .lg .middle } **Node Exporter**

    ---

    Host system metrics. Reports CPU, memory, disk, and network stats for the underlying server.

    **Port:** `9100` &middot; **Container:** `node-exporter-changemaker`

    [:octicons-arrow-right-24: Node Exporter](https://prometheus.io/docs/guides/node-exporter/){ target="_blank" }

-   :material-database-export:{ .lg .middle } **Redis Exporter**

    ---

    Redis metrics for Prometheus. Exposes connection counts, memory usage, command stats, and keyspace info.

    **Port:** `9121` &middot; **Container:** `redis-exporter-changemaker`

    [:octicons-arrow-right-24: Redis Exporter GitHub](https://github.com/oliver006/redis_exporter){ target="_blank" }

-   :material-cellphone-message:{ .lg .middle } **Gotify**

    ---

    Self-hosted push notification server. Receives alerts from Alertmanager and delivers them to mobile/desktop clients.

    **Port:** `8889` &middot; **Container:** `gotify-changemaker`

    [:octicons-arrow-right-24: Gotify Docs](https://gotify.net/docs/){ target="_blank" }

</div>

---

## Quick Reference

All services at a glance with their default ports and subdomains.

| Service | Port | Subdomain | Docker Profile |
|---------|------|-----------|---------------|
| Express API | 4000 | `api.` | default |
| Media API | 4100 | `media.` | default |
| Admin GUI | 3000 | `app.` | default |
| PostgreSQL | 5433 | &mdash; | default |
| Redis | 6379 | &mdash; | default |
| Nginx | 80/443 | *(all)* | default |
| Listmonk | 9001 | `listmonk.` | default |
| MailHog | 8025 | `mail.` | default |
| MkDocs (dev) | 4003 | `docs.` | default |
| MkDocs (static) | 4004 | *(root)* | default |
| Code Server | 8888 | `code.` | default |
| NocoDB | 8091 | `db.` | default |
| n8n | 5678 | `n8n.` | default |
| Gitea | 3030 | `git.` | default |
| Mini QR | 8089 | `qr.` | default |
| Homepage | 3010 | `home.` | default |
| Excalidraw | 8090 | `draw.` | default |
| Vaultwarden | 8445 | `vault.` | default |
| Rocket.Chat | &mdash; | `chat.` | default |
| Jitsi Meet | &mdash; | `meet.` | default |
| Gancio | 8092 | `events.` | default |
| Newt (tunnel) | &mdash; | &mdash; | default |
| Prometheus | 9090 | &mdash; | `monitoring` |
| Grafana | 3005 | `grafana.` | `monitoring` |
| Alertmanager | 9093 | &mdash; | `monitoring` |
| cAdvisor | 8086 | &mdash; | `monitoring` |
| Node Exporter | 9100 | &mdash; | `monitoring` |
| Redis Exporter | 9121 | &mdash; | `monitoring` |
| Gotify | 8889 | &mdash; | `monitoring` |

!!! tip "Starting services selectively"
    You don't need to run everything. Start only what you need:

    ```bash
    # Core only
    docker compose up -d v2-postgres redis api admin

    # Add nginx for subdomain routing
    docker compose up -d nginx

    # Add monitoring
    docker compose --profile monitoring up -d
    ```

    See [Getting Started](../getting-started/index.md) for the recommended startup order.
