Self-hosting
Prerequisites, architecture, environment, TLS, and upgrades for a production Pulse deploy.
Prerequisites
Section titled “Prerequisites”- Linux host, 2 vCPU / 2 GB RAM minimum (4 GB recommended).
- Docker Engine 24+ with the Compose v2 plugin.
- A domain with
A/AAAArecords pointing at the host. - Ports 80 and 443 reachable from the public internet — Traefik uses port 80 for Let’s Encrypt HTTP-01.
- Outbound TCP/443 for image pulls + ACME; TCP/25 or 587 if you intend to send mail directly.
Architecture
Section titled “Architecture”[ Browser ] ──▶ [ Traefik ] ──▶ [ pulse-api ] ──▶ [ Postgres + Timescale ] │ ├──▶ [ Redis ] │ ▲ └──▶ [ pulse-worker × N ]- API — HTTP + WebSocket. Sessions in Postgres, pub/sub via Redis. Migrations on boot.
- Worker — pulls check jobs from Redis, runs them, writes results back. Stateless; scale horizontally.
- Traefik — TLS termination, ACME, optional on-demand certs for status-page custom domains.
Environment
Section titled “Environment”All config is environment-driven. See the reference table. Every service validates env on boot and exits non-zero if a required variable is missing.
Bringing it up
Section titled “Bringing it up”docker compose -f docker/docker-compose.yml up -ddocker compose -f docker/docker-compose.yml psThe API container exits non-zero with a clear log message if anything is missing — docker compose logs api is your first stop on a failed boot.
Traefik is part of the compose stack and handles certificates via Let’s Encrypt’s HTTP-01 challenge. The ACME state is persisted to a named volume (letsencrypt). Back this file up — losing it forces re-issue and you’ll hit LE rate limits if you bounce often.
# manual snapshotdocker run --rm -v pulse_letsencrypt:/src -v /var/backups/pulse:/dst \ alpine sh -c 'cp /src/acme.json /dst/acme-$(date -u +%FT%TZ).json'To use Let’s Encrypt’s staging endpoint while you debug a cert, edit the certificatesresolvers block in docker/docker-compose.yml to point at https://acme-staging-v02.api.letsencrypt.org/directory, then docker compose up -d traefik.
First user
Section titled “First user”Bootstrap signup is open until one user exists, then closes automatically. Browse to /signup, create your operator account, then create members via Settings → Members → Invite.
If you ever lock yourself out, delete the user row in Postgres and the bootstrap path reopens.
Upgrades
Section titled “Upgrades”cd /opt/pulsegit fetch && git checkout v0.X.Ydocker compose -f docker/docker-compose.yml pulldocker compose -f docker/docker-compose.yml up -dThe API applies migrations on boot; no separate command. Migrations are designed to be backwards-compatible within a minor version — you can roll back to the previous tag without data loss.