Skip to content

Installing Pinggy

Running the control plane and its PostgreSQL store, and applying schema migrations.

What you need

Pinggy is a single Go control-plane binary backed by exactly one durable datastore: PostgreSQL. Monitoring nodes are a separate binary that connects outbound to the control plane; neither the control plane nor a node needs anything else to run.

Database roles

Pinggy uses three PostgreSQL roles, each with one job. The PostgreSQL administrator runs pinggy provision-database once per database (and again whenever in doubt; it is idempotent), which creates them and their privileges: pinggy_migrator owns the schema and applies migrations, pinggy_app is the control plane's least-privilege runtime identity, and pinggy_audit_expiry is a role nobody can log in as that performs only the bounded 90-day expiry of installation notification test-request audit records.

Applying the schema

The control plane's schema lives in migrations/ as a strictly ordered, forward-only sequence of SQL files, applied in order and never rewritten. Migrations are applied by the one-shot pinggy migrate command with the migration role's credentials. The control plane itself never migrates: it refuses to start if the schema it finds is older than the version this build requires, so an upgrade is pinggy provision-database, then pinggy migrate, then the new binary.

The essential variables

VariablePurpose
PINGGY_DATABASE_URLThe runtime role's (pinggy_app) PostgreSQL connection URL.
PINGGY_MIGRATION_DATABASE_URLThe migration role's URL, given only to pinggy migrate.
PINGGY_ADMIN_DATABASE_URLThe administrator's URL, given only to pinggy provision-database with PINGGY_MIGRATOR_DATABASE_PASSWORD and PINGGY_APP_DATABASE_PASSWORD.
PINGGY_ADDRThe HTTP bind address; :8080 if unstated.
PINGGY_SECURE_COOKIE1 behind HTTPS (the production setting); 0 only for local HTTP.

A production deployment sits behind a TLS-terminating reverse proxy, with PINGGY_SECURE_COOKIE=1 set once that proxy is in place. The control plane refuses to start if it is given the administrator's or the migration role's credentials, or a privileged database role.

Several other subsystems — the outbox delivery engine, retention, rollups, and the public admission policy — have their own optional environment overrides, all of which default to documented values when unset; a deployment that does not need to change them can leave them unset entirely.

Bootstrapping

The first tenant and administrator account are created once, from the command line, before anything is reachable over HTTP:

go run ./cmd/pinggy bootstrap --username admin --password 'change-this-password' --tenant default

Sign in at /login with that account afterward.

Verifying a deployment

gofmt, go vet, and the project's own test suites are how this repository verifies itself before a release; an operator deploying a built binary does not need to run them. What an operator can check directly: the control plane starts, logs a listening address, and answers /login; pg_dump and psql are PostgreSQL's own backup and restore tools and are what this project's backups are built from — there is no separate backup format.

This article is part of this repository and is served by the same binary, so what you read here is the documentation for the version you are running.