Deployment manifests for pgwd — Compose, Helm, and docker run. This repository is the home for all deployment-related work (Kubernetes, Compose, runbooks). hrodrig/pgwd is the application source, binaries, and container image only — the Helm chart is not in that repo on main; use pgwd-selfhosted (run/kubernetes/helm/pgwd/) or the future Helm repo on GitHub Pages.
Releases: Root VERSION and Git tags v<semver> on main name repository snapshots. Work in progress lands on develop first — for reproducible paths, prefer main or a tag, not unreviewed develop.
Policies: Community and policies, community standards — changelog, contributing, security, code of conduct, agent guidelines.
- Pick a path
- Standalone binary
- Docker single container
- Docker Compose minimal
- Kubernetes Helm
- Persistent data and secrets
- Repository layout
- Versioning
- Community and policies
- Community standards
- License
| You want… | Section |
|---|---|
| Binary only (no Docker) | Standalone binary |
Single container (docker run) |
Docker single container |
| Compose, one service (quick VPS) | Docker Compose minimal |
| Kubernetes | Kubernetes Helm |
Shared env template for Compose: copy run/common/.env.example to ${PGWD_HOST_DATA}/.env, set PGWD_HOST_DATA inside that file, and pass --env-file "${PGWD_HOST_DATA}/.env" to Compose. Which Compose file? run/docker-compose/README.md. Optional: run/scripts/compose-stack.sh (--help). Deeper walkthroughs: run/README.md.
Default image tag in examples is v0.6.4 (pgwd releases); set PGWD_VERSION to the tag you run. pgwd 0.6+ adds an optional SQLite store (history, hysteresis, resolution notifications), HTTP /healthz and Prometheus /metrics, databases: multi-DB YAML, and CSV export (CLI). The minimal Compose layout here stays env-only and does not mount SQLite or publish a port unless you extend it — see run/common/.env.example and pgwd README. This repo does not ship a bundled Prometheus stack; scrape /metrics with your own monitoring.
Goal: run the app without Docker.
- Download a release asset for your OS/arch from pgwd Releases.
- Extract the binary. Prefer state outside the download folder — same idea as Compose
PGWD_HOST_DATA(e.g./home/pgwd/pgwd-dataor${HOME}/pgwd-data):
export PGWD_HOST_DATA=/home/pgwd/pgwd-data
mkdir -p "$PGWD_HOST_DATA"
export PGWD_DB_URL='postgres://user:pass@localhost:5432/mydb?sslmode=disable'
export PGWD_INTERVAL=60
./pgwdThe minimal path uses environment variables, Postgres, optional Slack/Loki, and logs for checks. SQLite, HTTP /metrics, hysteresis, multi-DB YAML, CSV export — pgwd README and contrib/pgwd.conf.example.
Stop: Ctrl+C. Configuration: contrib/pgwd.conf.example and upstream README.
Multi-database YAML (databases:): databases: cannot be combined with -kube-postgres in the same process; SQLite history uses (client, cluster, database) (not the URL host) — use a unique client per entry when the same DB name appears on different hosts. See Multi-database limitations in the pgwd README.
More: run/standalone/README.md · Linux · macOS · Windows · *BSD · Solaris / illumos
Cron, no long-lived daemon: Cron / one-shot (PGWD_INTERVAL=0).
Goal: one container, no Compose file.
Examples use the GHCR image with environment variables (see run/docker/README.md).
docker run -d \
--name pgwd \
-e PGWD_DB_URL='postgres://user:pass@host:5432/dbname?sslmode=disable' \
-e PGWD_INTERVAL=60 \
ghcr.io/hrodrig/pgwd:v0.6.4Use an image tag that exists on GHCR (releases); match PGWD_VERSION in run/common/.env.example. See run/docker/README.md for optional notifiers, PGWD_DRY_RUN, and one-shot / --rm. Compose index when you need the minimal Compose layout.
Check: docker logs pgwd — look for total= / active= when Postgres is reachable.
Remove:
docker stop pgwd && docker rm pgwdMore: run/docker/README.md · Compose layouts
Goal: quick stack from this repo (single service, GHCR image).
git clone https://github.com/hrodrig/pgwd-selfhosted.git
cd pgwd-selfhosted
export PGWD_HOST_DATA=/home/pgwd/pgwd-data
mkdir -p "$PGWD_HOST_DATA"
cp run/common/.env.example "${PGWD_HOST_DATA}/.env"
# Edit "${PGWD_HOST_DATA}/.env": PGWD_DB_URL, PGWD_VERSION, PGWD_HOST_DATA (same path as above), optional notifiers
docker compose --env-file "${PGWD_HOST_DATA}/.env" -f run/docker-compose/minimal/docker-compose.yml up -dCheck: docker logs pgwd — look for total= / active= when Postgres is reachable.
Remove:
docker compose --env-file "${PGWD_HOST_DATA}/.env" -f run/docker-compose/minimal/docker-compose.yml downMore: run/docker-compose/minimal/README.md · Compose index
Naming: This GitHub repository is pgwd-selfhosted (deployment manifests). The Helm chart lives under run/kubernetes/helm/pgwd/ — pgwd is the chart name (see Chart.yaml). Chart development happens only here; pgwd does not include contrib/helm/pgwd on main. After the first chart release, packaged charts (pgwd-<chart-version>.tgz) and index.yaml on GitHub Pages / Releases will follow CONTRIBUTING.md. Git tags for this repo use v<semver> per VERSION.
Install today (clone — no Helm repo required):
git clone https://github.com/hrodrig/pgwd-selfhosted.git
cd pgwd-selfhosted
helm show values ./run/kubernetes/helm/pgwd > my-values.yaml
# Edit my-values.yaml — do not commit secrets to git (Postgres URL, Slack/Loki, image.tag, etc.).
helm upgrade --install pgwd ./run/kubernetes/helm/pgwd -n pgwd --create-namespace -f my-values.yamlQuick dry-run try (DB URL + no notifier secrets): run/kubernetes/helm/pgwd/README.md · kind: make test-kind-postgres (Postgres only) or make test-helm-kind (+ Helm pgwd) — testing/kind/README.md.
After the first chart release (Helm repo on GitHub Pages): when helm search repo pgwd works, you can install from the published index instead of the chart path:
helm repo add pgwd https://hrodrig.github.io/pgwd-selfhosted
helm repo update
helm search repo pgwd -l
helm show values pgwd/pgwd --version 0.1.8 > my-values.yaml
# Edit my-values.yaml — do not commit secrets to git.
helm upgrade --install pgwd pgwd/pgwd --version 0.1.8 -n pgwd --create-namespace -f my-values.yamlUse the version: from helm search once index.yaml is live (it may differ from 0.1.8). If helm repo add or search fails, the repo may not be published yet — use the clone path above.
Full options: run/kubernetes/helm/pgwd/README.md.
Secrets (recommended): do not put postgres:// URLs or webhooks in shell history. Prefer secrets.existingSecret with keys url, slack-webhook, loki-url (see secrets in values.yaml):
kubectl create namespace pgwd
kubectl create secret generic pgwd-secrets \
-n pgwd \
--from-literal=url='postgres://user:[email protected]:5432/mydb?sslmode=disable' \
--from-literal=slack-webhook='https://hooks.slack.com/services/...' \
--from-literal=loki-url='http://loki.monitoring.svc.cluster.local:3100/loki/api/v1/push'Then in my-values.yaml: set secrets.create: false, secrets.existingSecret: pgwd-secrets, and keep env.PGWD_* for non-secret settings (interval, log level, etc.).
You may use config.enabled: true for a full config file (db: + notifications, etc.); see the chart README.
See values.yaml in-tree for defaults.
Check: kubectl get pods -n pgwd -l app.kubernetes.io/name=pgwd and kubectl logs for Postgres stats lines.
pgwd on a bastion / laptop (not in-cluster): when pgwd and kubectl run on a host that uses port-forward to reach many in-cluster Postgres services (e.g. cron or heartbeat), see run/scripts/kubernetes-from-host/README.md — example scripts, PATH (including Snap), sleep between runs, and CLI flags vs /etc/pgwd/pgwd.conf.
Remove:
helm uninstall pgwd -n pgwdMore: run/kubernetes/helm/pgwd/README.md · run/kubernetes/manifests · run/scripts/kubernetes-from-host (pgwd + kubectl from host)
Recommended on servers: colocate env files (and any local state) outside the clone (see below).
Keep ${PGWD_HOST_DATA}/.env in one host directory (e.g. /home/pgwd/pgwd-data/). Set PGWD_HOST_DATA inside that file to that absolute path. Run Compose from the clone root with --env-file "${PGWD_HOST_DATA}/.env". See run/common/.env.example. Optional helper: run/scripts/compose-stack.sh (./run/scripts/compose-stack.sh --help).
run/
├── common/.env.example # Shared vars for Compose + image tag
├── scripts/ # compose-stack.sh; kubernetes-from-host/ (pgwd + kubectl examples)
├── standalone/README.md # Index; linux, macos, windows, solaris/, bsd/{freebsd,openbsd,netbsd,dragonfly}/
├── docker/ # docker run
├── docker-compose/
│ ├── README.md # minimal
│ └── minimal/
└── kubernetes/
├── helm/pgwd/ # Helm chart named "pgwd" (app); not the repo name
└── manifests/
VERSION— semver of this repository (Compose, docs,run/, etc.). When you change it, align the Version badge in this README and (if you keep a release entry) CHANGELOG.md; onmain, tag withv<semver>(e.g.v0.2.0). This number is not tied to the Helm chart on every bump.- Helm chart (
run/kubernetes/helm/pgwd/Chart.yaml→version:) — semver of the chart package published to GitHub Pages / Releases. Bumpversion:when the chart itself changes (templates,values, etc.). It may lag behindVERSION(e.g. repo0.1.8, chart0.1.8when both bump together). chart-releaser may skip publishing ifrun/kubernetes/helm/did not change — expected for docs-only repo releases. Chart.yaml→appVersion— pgwd application / image line; align with pgwd releases when you bump the deployed image story (defaults in this repo track v0.6.4).PGWD_VERSIONin${PGWD_HOST_DATA}/.env(or the env file you pass to Compose) — container image tag on GHCR (pgwd releases), not the same asVERSION.
| Document | Purpose |
|---|---|
| CHANGELOG.md | Release history and notable changes to this repository (manifests, docs, layout). |
| CONTRIBUTING.md | How to open issues/PRs, branch policy (develop → main), and checks before submitting. |
| CODE_OF_CONDUCT.md | Community standards (Contributor Covenant). |
| SECURITY.md | How to report security vulnerabilities responsibly. |
| AGENTS.md | Guidelines for AI coding agents (Cursor, etc.) working in this repo. |
Application issues (bugs, features in the Go app or UI) belong in pgwd — not here.
- License:
LICENSE - Contributing:
CONTRIBUTING.md - Code of conduct:
CODE_OF_CONDUCT.md - Security policy:
SECURITY.md - Changelog:
CHANGELOG.md - Agent guidelines:
AGENTS.md
Thanks for self-hosting pgwd with these manifests. We would love to hear how easy or difficult it was to run pgwd self-hosted (Compose, Helm, docker run, or anything in run/). Share feedback in GitHub Issues or, if enabled for this repository, Discussions.
MIT — see LICENSE.