# cc-ci machine config. M0 = faithful reproduction of the baseline (docs/baseline.md) # so the first flake rebuild is a no-op-then-base. Services (swarm/Traefik/Drone/ # bridge/dashboard) are layered in via ./modules/* in later milestones. { pkgs, ... }: { imports = [ ./hardware.nix ../../modules/packages.nix ../../modules/secrets.nix ../../modules/swarm.nix ../../modules/docker-prune.nix ../../modules/abra.nix ../../modules/proxy.nix ../../modules/drone.nix ../../modules/drone-runner.nix ../../modules/bridge.nix ../../modules/dashboard.nix ../../modules/backupbot.nix ../../modules/harness.nix ../../modules/warm-keycloak.nix ../../modules/nightly-sweep.nix ]; # --- Timezone: create /etc/localtime. Some recipes bind-mount the host's /etc/localtime into # their containers (e.g. immich); without a set timezone NixOS leaves /etc/localtime absent, so # that bind fails ("bind source path does not exist: /etc/localtime") and the service is rejected. # UTC is the right default for a CI host (deterministic timestamps). --- time.timeZone = "UTC"; # Some recipes ALSO bind-mount /etc/timezone (e.g. gitea, and Debian-based images), which # `time.timeZone` does NOT create (it only makes the /etc/localtime symlink). Without this the # bind fails ("bind source path does not exist: /etc/timezone") and the container is rejected. environment.etc."timezone".text = "UTC\n"; # --- Tailscale (ACCESS-CRITICAL: do not break, this is the only route in) --- # Baseline read the hostname from /etc/ts-hostname at eval time; that is impure # under flakes, so we pin the known hostname. The reusable auth-key file persists. services.tailscale = { enable = true; authKeyFile = "/etc/ts-auth-key"; extraUpFlags = [ "--hostname=cc-nix-test" ]; }; # --- SSH (root login over tailscale) --- services.openssh = { enable = true; settings.PermitRootLogin = "yes"; }; # --- Firewall: trust tailscale, allow SSH --- networking.firewall = { enable = true; trustedInterfaces = [ "tailscale0" ]; allowedTCPPorts = [ 22 ]; }; # Phase `nixenv`: the Drone exec runner resolves recipe shell-outs from this host PATH # (PATH=/run/current-system/sw/bin). Reference the SINGLE shared harness tool set # (pkgs.ccciRuntimeTools — includes git-lfs, openssl, etc.) instead of a hand-maintained list, # so the Drone path and the harness env (cc-ci-run / sweep) can never diverge. `openssh` is a # host-only addition (ssh client), not part of the recipe-test tool set. environment.systemPackages = pkgs.ccciRuntimeTools ++ [ pkgs.openssh ]; nix.settings.experimental-features = [ "nix-command" "flakes" ]; system.stateVersion = "24.11"; }