61. pepsi-setup

Provision the database, signing keys and DNS for a deployment.

61.1. Role

pepsi-setup is the administrative bootstrap tool. In one invocation it validates the configuration, installs the schema, generates signing keys and prints the DNS records to publish; a separate check verifies live DNS. References: pepsi-setup(1) / pepsi.conf(5).

61.2. Features

  • Configuration validation. Parses [pepsi], [pepsi-ingress] and the [stage-*] pipeline; checks that [stage-init] exists, that every NEXT_STAGE/BOUNCE_STAGE resolves, that each stage’s program configuration (including smarthost routing) parses, and that domains and PUBLIC_IP values are well-formed. On any error it changes nothing and exits non-zero.

  • TLS certificate provisioning. For every TLS-terminating listener/cert section that has no TLS_CERT/TLS_KEY, it fills in the standard certbot path layout (rewriting the config file in place, comments preserved) and then runs certbot certonly --standalone to obtain any certificate not yet on disk (or to widen one that no longer covers every name). Pass --no-certbot to skip the certbot call and manage certificates yourself. A certificate that is missing and cannot be obtained is deferred, not fatal: the rest of the run proceeds and the end-of-run summary says what is left to do.

  • TLS access provisioning. The servers run as unprivileged users, while certbot keeps /etc/letsencrypt root-only. Under systemd, pepsi-setup writes a LoadCredential= drop-in per unit so systemd reads each certificate and key as root at unit start and hands the service a private copy — the file permissions then do not matter at all. It also grants POSIX ACLs and installs a certbot deploy hook (which re-grants and restarts the servers, so a renewed certificate is actually served), and finally verifies — by becoming the service user and opening the file — that anything left over really is readable.

  • Schema installation. The sole installer of the single pepsi schema: applies the numbered patch series and the re-creatable procedures from SQL_DIR; idempotent and re-runnable. It records what it applied, by content hash, so every program can refuse a schema from another release, and it refuses to install over a newer schema itself (see Upgrading). run --reset drops and recreates the schema (destroying queued mail; on-disk keys are kept).

  • Key generation. For every domain Pepsi is authoritative for — the union of ACCEPTED_DOMAINS, each stage’s SERVER_NAME/POSTMASTER domain, any explicit SIGNING_DOMAIN, SRS_DOMAIN or fixed RESPONSE_FROM, and ARC_DOMAIN — creates an RSA-2048 and an Ed25519 (RFC 8463) DKIM key under KEY_DIR (mode 0600 in 0700 dirs) if absent; existing keys are never overwritten.

  • DNS record output. Prints, in BIND zone format, the DKIM public keys (<selector>._domainkey and <selector>-ed25519._domainkey), an SPF policy built from the PUBLIC_IP of every relay stage (unioned), a DMARC suggestion where none is published, an MTA-STS _mta-sts TXT record (RFC 8461), a TLSRPT record when [pepsi-tlsrpt] RUA is set, and DANE/TLSA records for the TLS listeners. Records already published with the right value are left out. The policy file itself is served by pepsi-httpd, not printed. Long RSA records are split into multiple character-strings. The same SPF record is suggested for every served domain; the output notes that special multi-host setups may prefer a tighter, still-correct per-domain grouping, which pepsi-setup does not compute automatically.

  • Live DNS verification (check): queries DNS and reports, per domain, whether the published DKIM p= matches the local key, the SPF record lists every PUBLIC_IP, the DMARC record is valid, and the _mta-sts TXT is present and parseable; it also compares the MTA-STS policy with the live MX records and with what is actually served, and checks that the SRS domain can receive its bounces. Purely informational: its findings never set the exit status.

  • Setup wizard (--wizard): a short interactive interview that writes a complete, already-validated configuration file (to the --config path, or /etc/pepsi/pepsi.conf by default) and then offers to run the full setup. It imports a previous run’s answers from the file’s [pepsi-wizard] section; --force overwrites a file that has no such section without prompting.

Use pepsi-config to inspect the effective configuration.

61.3. Command-line options

Run with no subcommand performs the full setup (the same as run). Full detail is in pepsi-setup(1); the options are:

Subcommands:

  • run — validate, provision TLS, install schema, generate keys, print DNS (the default action). -r/--reset first drops and recreates the schema (destroys all queued mail; on-disk keys are kept).

  • schema — install or upgrade the schema and the role grants, and nothing else; needs only [pepsi-postgres], so it also works with a telemetry collector’s configuration file. Refuses a newer schema (exit status 78). --backup-dir DIR first saves the schema with pg_dump when there is something to upgrade; --if-installed does nothing on a database with no schema yet. This is what a package upgrade runs; see Upgrading.

  • check — query live DNS and report mismatches; makes no changes, and its findings never set the exit status.

  • visualize — print the [stage-*] pipeline as a Graphviz dot graph on standard output (a solid edge per NEXT_STAGE, a dashed red one per BOUNCE_STAGE); pipe it into dot -Tpng.

  • questions — print the setup interview as JSON: the steps, each question’s shape, default, help text and when it is asked. It is the model both the terminal wizard and the browser setup are described by, and the schema an --answers file is written against.

  • apply — perform the privileged setup work the browser interface has asked for, reading intent rows from pepsi.setup_task. Normally started on demand by systemd. --once drains what is pending and exits; --idle SECS sets how long it waits with nothing to do before exiting; --clear deletes every queued row without executing any of them (mutually exclusive with the other two).

  • bootstrap — mint and print the one-time bearer token that creates the first administrator account (--valid-for SECS, --admin-url URL).

  • import [MTA] — report what would be migrated from an existing MTA (postfix, exim, sendmail, qmail, stalwart) without writing anything; --root reads from under another directory, --out writes the report and converted map files, --alias-style chooses how bare alias names are qualified.

Options, which all come before the subcommand:

  • --no-certbot — do not invoke certbot for missing TLS certificates; they are deferred instead (see TLS certificate provisioning above).

  • --no-reverse-proxy — do not auto-integrate with an existing front HTTP server; let pepsi-httpd bind 443 directly.

  • -y/--yes-to-all, -n/--no-to-all — answer every interactive offer the same way, so setup never blocks on input.

  • --wizard — run the interactive configuration wizard (does not require an existing configuration file); --force overwrites an un-importable file without prompting. With it: --expert SPEC also asks the deeper options (--expert=help lists them), --import MTA / --no-import / --import-root DIR control the migration of an existing MTA’s settings, and --answers FILE answers every question from JSON instead of asking.

  • -c/--config FILE, -L/--log LEVEL, -v/--verbose, -h/--help, -V/--version — the options shared by all Pepsi tools.

61.4. Configuration

Reads the shared [pepsi] (KEY_DIR, DKIM_SELECTOR, DKIM_ALGORITHMS, ARC_DOMAIN, ARC_ALGORITHM, ORIGINATE_SUCCESS_DSN, MTA_STS_MODE, MTA_STS_MAX_AGE), [pepsi-postgres] (CONFIG, SQL_DIR), [pepsi-ingress] (HOSTNAME, ACCEPTED_DOMAINS), and the [stage-*] sections — including each relay stage’s PUBLIC_IP (collected by PROGRAM). Full reference: pepsi.conf(5).

61.5. See also

Installation, Configuration, pepsi-setup(1), pepsi.conf(5).