Renovate now runs from its own repository for every repo, with the
shared rules in its preset. Extend that preset here and keep only what
is specific to this repo (the Ansible var manager, the Paper JRE, the
runner and nix notes); drop the workflow that ran it for iac alone.
Assisted-by: Claude:opus-5-5
The first run failed with "home directory /homeless-shelter exists":
job containers are unprivileged, Nix cannot sandbox builds in them, and
unsandboxed builds trip over each other's leftovers.
Evaluate the system in the job instead, which still catches broken
options before main, and let nixos-rebuild build on the target host,
where the Nix daemon has a proper sandbox.
Assisted-by: Claude:fable-5-2
asxpio-services is to move from Debian with Docker to NixOS with
Podman. This is the target system; nothing is switched over yet.
One flake holds what was spread over cloud-init, Ansible roles and
hand-made units: network and WireGuard, users and SSH restrictions,
firewall, the weekly image prune, and the four container stacks
(Paper and Fossils Minecraft, SillyTavern, the Forgejo runner), each
as a systemd unit under Podman. The runner keeps running as a
container and starts jobs through Podman's Docker-compatible socket.
Secrets (WireGuard keys, RCON and CurseForge keys) are encrypted with
sops for the admin's age key and the server's SSH host key, so the
repository holds no plaintext secret and CI needs none of them.
Containers that own data wait for /opt/.restored. On a freshly
installed disk a game server would otherwise generate a new world
exactly where the restore is about to land.
Tried on a throwaway server (.#rehearsal): install with nixos-anywhere
keeping a given host key, secret decryption, all stacks, a real Paper
server stopping with a full save, what CI jobs need from the engine
(short image names, the nix-store volume, service containers by name,
a kaniko build, the socket inside a job), an update over SSH and a
reboot.
migration/ has the scripts that move the data through object storage,
and a workflow builds the system on every push and switches the host
on main.
Assisted-by: Claude:fable-5-2
The unquoted value contains ": ", which YAML reads as a nested mapping,
so Forgejo rejected the whole workflow and the last two pushes ran
nothing. Quote it.
Assisted-by: Claude:opus-5-5
Every run was listed as "deploy", so dry runs on Renovate branches
looked like deployments. Name each run after what it does and the
branch it ran on.
Assisted-by: Claude:opus-5-5
The repository was renamed from infrastructure to iac. Renovate looks
repositories up by name, and with push-to-create on, the old name now
belongs to a different, empty repository.
Assisted-by: Claude:opus-5-5
Versions are pinned across the Ansible vars, compose files, Terraform
providers and workflows, and nothing says when one is behind. Run
Renovate daily from Forgejo Actions: one PR per available bump, with
the upstream changelog in the body, which the deploy pipeline then
dry-runs like any other branch.
Variables are tracked through a "# renovate: datasource=... depName=..."
comment above them; Forgejo, Traefik, the runner and its nix image get
one here. The Paper JRE tag is left alone, the runner and nix bumps
carry their manual follow-up steps in the PR, and Renovate's own image
is bumped monthly.
Needs the repository secrets RENOVATE_TOKEN (bot user with write
access) and GH_COM_TOKEN (read-only github.com token for release
notes).
Assisted-by: Claude:opus-5-5
Service changes were made by hand on the servers, which is how the
repository drifted. Apply site.yaml from a workflow instead: every
push dry-runs it against production, and a push to main applies it.
Jobs run in containers on asxpio-services. asxpio-ops is reached over
the private network; the services host is reached through asxpio-ops,
because a container connecting to its own host arrives from a Docker
bridge address that sshd and the firewall refuse. Host keys are pinned
in known_hosts.
Ansible comes from a pinned nixpkgs revision so every run uses the
same version.
Assisted-by: Claude:fable-5-2