Files
dezky/infrastructure/production/host/config.env.example
T
Ronni Baslund 861212831d
ci / typecheck (map[dir:apps/booking name:booking]) (push) Has been cancelled
ci / typecheck (map[dir:apps/portal name:portal]) (push) Has been cancelled
ci / typecheck (map[dir:apps/website name:website]) (push) Has been cancelled
ci / typecheck (map[dir:services/platform-api name:platform-api]) (push) Has been cancelled
ci / test (push) Has been cancelled
fix(infra): restic→Storage Box backups working end-to-end
Three fixes found bringing up backups on node1:
- restic.env wrote BACKUP_PATHS/RETENTION unquoted → sourcing ran a path as a
  command ("Is a directory"); now quoted.
- ssh config was written to $BACKUP_HOME/.ssh/config, but restic runs as root
  and its ssh resolves ~ from the passwd db (not $HOME), so it reads
  /root/.ssh/config — write the Storage Box block there. Also
  StrictHostKeyChecking=no + UserKnownHostsFile=/dev/null (safe: restic encrypts
  before upload; fixes flaky Storage Box host-key verification).
- Storage Box SFTP lands in /home, so the repo path needs the /home prefix
  (absolute /dezky hit the root-owned chroot parent → SSH_FX_FAILURE).

Verified: repo initialized, nightly snapshot of mail store + Stalwart config +
etcd snapshots + dumps dir, `restic check` clean, retention applied.
2026-06-08 21:46:49 +02:00

62 lines
4.2 KiB
Bash

# ─────────────────────────────────────────────────────────────
# Dezky production host configuration
#
# Copy to `config.env` and fill in real values. `config.env` is
# gitignored — it holds host-specific values, not the repo's source
# of truth. Both bootstrap.sh and firewall/firewall.sh source this.
# ─────────────────────────────────────────────────────────────
# --- Management allowlist -------------------------------------------------
# Source addresses allowed to reach SSH (22) and the k3s API (6443).
# Everything else on those ports is dropped. Accepts a comma-separated
# list of single IPs and/or CIDRs (e.g. home + office, or a /29 block,
# or a v6 /64 prefix) — the firewall treats these as nftables interval sets.
#
# NOTE: residential IPs can change. If yours is dynamic, prefer a small
# prefix here, and remember Hetzner's KVM/LARA console is always reachable
# out-of-band if you ever lock yourself out (see README).
MGMT_ALLOW_V4="203.0.113.10, 203.0.113.11" # REQUIRED — management IPv4(s)/CIDR(s)
MGMT_ALLOW_V6="" # optional — management IPv6(s)/prefix (empty to skip)
# --- Server identity ------------------------------------------------------
SERVER_HOSTNAME="node1.dezky.eu" # FQDN set on the box
SERVER_PUBLIC_IPV4="" # AX41 primary IPv4 (fill after provisioning)
SERVER_PUBLIC_IPV6="" # AX41 primary IPv6 (fill after provisioning)
# --- Admin (non-root) user ------------------------------------------------
ADMIN_USER="dezky" # created with sudo; root SSH login is then disabled
ADMIN_SSH_PUBKEY="" # REQUIRED — your SSH public key (the WHOLE line, e.g. "ssh-ed25519 AAAA... you@home")
# --- SSH ------------------------------------------------------------------
SSH_PORT="22" # keep 22 unless you have a reason; obscurity is not security
# --- k3s networking (defaults; change ONLY if you customise k3s CIDRs) ----
K3S_POD_CIDR="10.42.0.0/16" # flannel pod network — accepted to/from host
K3S_SERVICE_CIDR="10.43.0.0/16" # cluster service network — accepted to/from host
# --- Rancher Custom-cluster registration (SECRET) -------------------------
# From Rancher → Cluster Management → <cluster> → Registration tab. Create the
# cluster with the **K3s** distribution first. Token + checksum are secrets.
RANCHER_SERVER_URL="https://rancher.example.com"
RANCHER_NODE_TOKEN="" # REQUIRED — node registration token
RANCHER_CA_CHECKSUM="" # REQUIRED — CA checksum from the same command
RANCHER_NODE_ROLES="--etcd --controlplane --worker" # single node = all three
RANCHER_INSECURE_FETCH="true" # true if Rancher is reached by IP / self-signed cert
# --- Stalwart mail (host service) -----------------------------------------
# SECRETS — platform-api (k3s) must use the SAME admin password + webhook secret.
STALWART_VERSION="latest" # pin to a release tag after first install
STALWART_ADMIN_PASSWORD="" # REQUIRED — openssl rand -hex 24
STALWART_WEBHOOK_SECRET="" # REQUIRED — openssl rand -hex 32
# --- Restic backups (host) ------------------------------------------------
# Storage Box is SSH/SFTP on PORT 23, key auth. STORE RESTIC_PASSWORD OFFLINE.
# NOTE: the Storage Box drops you in /home, so the repo path needs the /home
# prefix (an absolute /dezky hits the root-owned chroot parent and fails).
RESTIC_PASSWORD="" # REQUIRED — openssl rand -hex 32 (save offline!)
BACKUP_PRIMARY_REPO="" # sftp:<user>@<user>.your-storagebox.de:/home/dezky
BACKUP_DR_REPO="" # sftp:<user>@<user>.your-storagebox.de:/home/dezky (Helsinki box)
BACKUP_PATHS="/opt/stalwart/data /opt/stalwart/etc /var/lib/rancher/k3s/server/db/snapshots /opt/dezky-backup/dumps"
BACKUP_RETENTION="--keep-daily 7 --keep-weekly 4 --keep-monthly 6"
BACKUP_HEALTHCHECK_URL="" # optional dead-man's-switch base URL