{ config, pkgs, lib, ... }: # Gitea Actions Runner inside a NixOS container. # The container shares the host's /nix/store (read-only) and nix-daemon socket, # so builds go through the host daemon and outputs land in the host store. # Warning: NixOS containers are not fully secure — do not run untrusted code. # To enable, assign a machine the 'gitea-actions-runner' system role. let thisMachineIsARunner = config.thisMachine.hasRole."gitea-actions-runner"; containerName = "gitea-runner"; in { config = lib.mkIf (thisMachineIsARunner && !config.boot.isContainer) { containers.${containerName} = { autoStart = true; ephemeral = true; privateNetwork = true; hostAddress = "172.16.101.1"; localAddress = "172.16.101.2"; bindMounts = { "/run/agenix/gitea-actions-runner-token" = { hostPath = "/run/agenix/gitea-actions-runner-token"; isReadOnly = true; }; "/var/lib/gitea-runner" = { hostPath = "/var/lib/gitea-runner"; isReadOnly = false; }; }; config = { config, lib, pkgs, ... }: { system.stateVersion = "25.11"; networking.hostName = lib.mkForce containerName; services.gitea-actions-runner.instances.inst = { enable = true; name = containerName; url = "https://git.neet.dev/"; tokenFile = "/run/agenix/gitea-actions-runner-token"; labels = [ "nixos:host" ]; }; # Disable dynamic user so runner state persists via bind mount systemd.services.gitea-runner-inst.serviceConfig.DynamicUser = lib.mkForce false; users.users.gitea-runner = { home = "/var/lib/gitea-runner"; group = "gitea-runner"; isSystemUser = true; createHome = true; }; users.groups.gitea-runner = { }; environment.systemPackages = with pkgs; [ git nodejs jq attic-client ]; networking.firewall.enable = false; }; }; # NAT for container outbound access networking.nat.enable = true; networking.nat.internalInterfaces = [ "ve-${containerName}" ]; # Matching user on host — the container's gitea-runner UID must be # recognized by the host's nix-daemon as trusted (shared UID namespace) users.users.gitea-runner = { home = "/var/lib/gitea-runner"; group = "gitea-runner"; isSystemUser = true; createHome = true; }; users.groups.gitea-runner = { }; nix.settings.trusted-users = [ "gitea-runner" ]; # Don't use remote builders for CI # (set on host since container uses host's daemon) nix.distributedBuilds = lib.mkForce false; age.secrets.gitea-actions-runner-token.file = ../../secrets/gitea-actions-runner-token.age; }; }