sd-image.nix imports all-hardware.nix which adds modules like dw-hdmi
that don't exist in the RPi4 kernel. mkForce the availableKernelModules
list to only include Pi-relevant modules.
- Fix Pi kernel build: disable includeDefaultModules in initrd.
NixOS all-hardware.nix includes dw-hdmi which doesn't exist in
the RPi4 kernel 6.12, causing module-shrunk to fail.
- Fix CI: SD image build now depends on build-hosts instead of
flake-check, so it won't run if the Pi build fails.
- Apply same fix to raspberry-pi template.
- Remove deploy-rs flake input
- Remove deploy block from flake.nix
- Remove deployChecks from flake checks
- Remove deploy-rs from forgejo-runner hostPackages
- Deployment is now handled by Comin (auto) and nix run .#deploy (manual)
- Add Comin service for cryodev-main (polls git repo, auto-deploys)
- Fix cryodev-pi Comin URL (cryodev-server.git -> cryodev.git)
- Remove deploy-rs from CI pipeline (was insecure with shared runner)
- Remove deploy SSH key, root SSH login, sudo rules for gitea-runner
- Revert PermitRootLogin back to 'no'
- CI now only runs flake-check + build (no deploy)
- Deployment happens via Comin (both hosts poll and self-deploy)
The nix-daemon runs as root and cannot access the gitea-runner user's
~/.ssh directory. Solution: write the deploy key and SSH config to
/etc/deploy/ and /etc/ssh/ssh_config.d/ which are readable by all
users including the nix-daemon.
- Deploy key is written to /etc/deploy/key (cleaned up after deploy)
- SSH config in /etc/ssh/ssh_config.d/deploy.conf (cleaned up after)
- Minimal NOPASSWD sudo rules for gitea-runner to manage these files
- Reverts local deploy approach, back to deploy-rs over SSH
Runner runs on the same server it deploys to, so SSH to itself was
unnecessarily complex. Now builds locally and activates directly.
- Replace deploy-rs SSH workflow with local build + switch
- Add NOPASSWD sudo for gitea-runner to run nix-env and
switch-to-configuration (required for local deployment)
- Remove SSH key setup from deploy workflow
deploy-rs ignores NIX_SSHOPTS and only uses its own sshOpts.
The host key verification prompt was blocking the non-interactive
CI pipeline. Adding accept-new to sshOpts directly.
deploy-rs was using 'gitea-runner' as ssh_user because the runner
process runs as that user. Set sshUser=root at the node level.
Also add StrictHostKeyChecking=accept-new as fallback for host key.
- Move forgejo-deploy pubkey from users/steffen to hosts/cryodev-main/
(deploy key belongs to the host, not a user)
- Remove deploy key from steffen's authorized keys
- Add users ralph and benjamin (pubkeys pending)
- Register both new users in cryodev-main host config
- Change PermitRootLogin from 'no' to 'prohibit-password' (key-only)
- Add forgejo-deploy public key to root's authorized_keys
- Revert deploy-rs user back to root (needs root for activation)
Root can only login via SSH key, password auth remains disabled.
deploy-rs was configured with default port 22 and user root, but
SSH runs on port 2299 and root login is disabled. Also fix ssh-keyscan
in the deploy workflow to use the correct port.
Runner has label 'host' not 'docker'. Jobs were stuck in 'waiting to
run' because no runner matched the docker label. Also removed the
cachix/install-nix-action steps since Nix is already available on the
host runner.
Consolidate 4 separate workflows into 2:
- ci.yml (pull_request): flake-check -> build-hosts
- deploy.yml (push to main): flake-check -> deploy + build-pi-images
Previously, deploy and build-pi-image ran on push to main without
any checks. Now flake-check must pass before anything gets deployed
or built.
The ACME challenge directory was created with group 'acme' but nginx
needs read access to serve challenge responses. Setting defaults.group
to 'nginx' ensures all ACME directories are accessible by nginx.
NixOS headscale module generates a minimal config.yaml with only
explicitly set values. Headplane with config_strict=true rejects this
because fields like database, derp, dns, listen_addr are missing
(headscale fills these with internal defaults). Setting config_strict
to false makes headplane tolerate the incomplete config.
Runner on the same host cannot reach Forgejo via the public HTTPS URL
during boot (ACME certs not ready, nginx not fully up). Use the local
HTTP endpoint instead.
The gitea-actions-runner NixOS module expects tokenFile to be an
EnvironmentFile containing TOKEN=<value>, but sops-nix writes only
the raw secret value. Use a sops template to prepend TOKEN= prefix.
- Rename SOPS key alias from generic admin_key to steffen_key in
.sops.yaml and all docs (keys should identify the person, not a role)
- Add step 3.6 to first-install docs: create Forgejo admin account
via CLI (required since DISABLE_REGISTRATION is enabled)
- Fix cryodev-pi_key comment naming in .sops.yaml
- Add .gitignore for nix build result symlinks
- Fix all headscale CLI commands: --user now requires numeric ID,
not username (changed in newer headscale versions)
- Add 'headscale users list' step to docs where preauth keys are created
- Extract forgejo-runner config from forgejo.nix into forgejo-runner.nix
- Move forgejo-runner to stage 2 (requires running Forgejo for token)
- Remove all stage-2 secrets from sops.nix (each service file owns its secrets)
- Update first-install docs with corrected staged deployment flow
- Fixes deployment failure caused by runner crashing with placeholder token
- Add apps: create (scaffold host from template), deploy (multi-host
deployment with -n filter), install (NixOS installation from live ISO)
- Register all apps in flake.nix (create, deploy, install, rebuild)
- Add deploy.json config (cryodev-main, SSH port 2299)
- Fix generic-server template: was using Pi hardware/boot config,
now correct x86_64 with systemd-boot, UEFI, ROOT/BOOT/SWAP labels
- Fix template networking.nix: use HOSTNAME placeholder instead of
hardcoded cryodev-pi (both templates)
- Fix headplane upstream pnpm-deps hash mismatch via overlay
- Fix all docs: replace root@ with user@, --ssh-option with
NIX_SSHOPTS, add deploy app references, update first-install guide
to use create app and document service deactivation steps
- Add automatic SD image builds for Raspberry Pi via Forgejo Actions
- Enable binfmt emulation on cryodev-main for aarch64 cross-builds
- Add sd-image.nix module to cryodev-pi configuration
- Create comprehensive docs/ structure with installation guides
- Split installation docs into: first-install (server), reinstall, new-client (Pi)
- Add lib/utils.nix and apps/rebuild from synix
- Fix headplane module for new upstream API (tale/headplane)
- Fix various module issues (mailserver stateVersion, option conflicts)
- Add placeholder secrets.yaml files for both hosts
- Remove old INSTRUCTIONS.md (content moved to docs/)