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
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.
62 lines
4.2 KiB
Bash
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
|