Fediversity/machines/dev/forgejo-ci/woodpecker.nix
Kiara Grouwstra 10f4764e45
Some checks failed
ci/woodpecker/manual/check-deployment-cli Pipeline failed
ci/woodpecker/manual/check-deployment-basic Pipeline failed
ci/woodpecker/manual/check-deployment-panel Pipeline failed
ci/woodpecker/manual/check-mastodon Pipeline failed
ci/woodpecker/manual/check-panel Pipeline failed
ci/woodpecker/manual/check-peertube Pipeline failed
ci/woodpecker/manual/check-pre-commit Pipeline was successful
ci/woodpecker/manual/check-data-model Pipeline was successful
ci/woodpecker/manual/update Pipeline was successful
ci/woodpecker/manual/check-resources Pipeline was successful
ci/woodpecker/manual/cd Pipeline failed
make it secure
2025-08-05 17:06:46 +02:00

237 lines
6.9 KiB
Nix

{
lib,
pkgs,
config,
...
}:
{
security.acme = {
acceptTerms = true;
defaults.email = "something@fediversity.eu";
};
users.groups.woodpecker-agent-docker = { };
age.secrets =
lib.mapAttrs
(_: group: {
owner = "root";
inherit group;
mode = "440";
})
{
woodpecker-gitea-client = "woodpecker-server";
woodpecker-gitea-secret = "woodpecker-server";
woodpecker-agent-container = "woodpecker-agent-docker";
};
# needs `sudo generate-vars`
vars.settings.on-machine.enable = true;
vars.generators.woodpecker-agent-secret = {
runtimeInputs = [ pkgs.openssl ];
files.my-secret.secret = true;
script = ''
openssl rand -hex 32 > "$out"/my-secret
'';
};
vars.generators.woodpecker-rpc-secret = {
runtimeInputs = with pkgs; [
coreutils
bash
];
files.rpc-secret.secret = true;
# wrap in bash command to prevent `vars`' pipefail aborting half-way
script = ''
bash -c "tr -dc 'A-Za-z0-9\!?%=' < /dev/urandom | head -c 32 > $out/rpc-secret"
'';
};
vars.generators.woodpecker =
let
fileNames = [
"woodpecker-gitea-client"
"woodpecker-gitea-secret"
"woodpecker-agent-container"
];
in
{
runtimeInputs = [
pkgs.coreutils
pkgs.openssl
];
files = lib.genAttrs fileNames (_: {
secret = true;
});
script = ''
${lib.concatStringsSep "\n" (
lib.lists.map (file: ''cp ${config.age.secrets.${file}.path} "$out/"'') fileNames
)}
'';
};
# FIXME: make `WOODPECKER_AGENT_SECRET_FILE` work so i can just do the following again instead of using templates:
# `woodpecker-agents.agents.docker.environment.WOODPECKER_AGENT_SECRET_FILE = config.age.secrets.woodpecker-agent-docker.path;`
vars.generators."templates" = rec {
dependencies = [
"woodpecker"
"woodpecker-agent-secret"
"woodpecker-rpc-secret"
];
runtimeInputs = [
pkgs.coreutils
pkgs.gnused
];
script = lib.concatStringsSep "\n" (
lib.mapAttrsToList (template: _: ''
cp "$templates/${template}" "$out/${template}"
echo "filling placeholders in template ${template}..."
${lib.concatStringsSep "\n" (
lib.lists.map (dependency: ''
echo "filling placeholders in template ${template} from generator ${dependency}..."
${lib.concatStringsSep "\n" (
lib.mapAttrsToList (
parent:
{ placeholder, ... }:
''
sed -i "s/${placeholder}/$(cat "$in/${dependency}/${parent}")/g" "$out/${template}"
echo "- substituted ${parent}"
''
) config.vars.generators.${dependency}.files
)}
'') dependencies
)}
'') files
);
files =
let
# https://woodpecker-ci.org/docs/administration/configuration/agent
shared = ''
WOODPECKER_SERVER=localhost:9000
WOODPECKER_USERNAME=x-oauth-basic
WOODPECKER_HOSTNAME=https://woodpecker.fediversity.eu
WOODPECKER_MAX_WORKFLOWS=5
WOODPECKER_LOG_LEVEL=info
WOODPECKER_DEBUG_PRETTY=true
WOODPECKER_DEBUG_NOCOLOR=false
WOODPECKER_GRPC_SECURE=true
'';
in
{
# https://woodpecker-ci.org/docs/administration/configuration/server
"woodpecker-server.conf" = {
secret = true;
template = pkgs.writeText "woodpecker-server.conf" ''
WOODPECKER_DATABASE_DRIVER=sqlite3
WOODPECKER_DISABLE_USER_AGENT_REGISTRATION=false
WOODPECKER_OPEN=false
WOODPECKER_ADMIN=kiara,fricklerhandwerk,niols
WOODPECKER_HOST=https://woodpecker.fediversity.eu
WOODPECKER_GITEA=true
WOODPECKER_GITEA_URL=https://git.fediversity.eu
WOODPECKER_GITEA_CLIENT=${config.vars.generators.woodpecker.files.woodpecker-gitea-client.placeholder}
WOODPECKER_GITEA_SECRET=${config.vars.generators.woodpecker.files.woodpecker-gitea-secret.placeholder}
WOODPECKER_AGENT_SECRET=${config.vars.generators.woodpecker-agent-secret.files.my-secret.placeholder}
WOODPECKER_GRPC_SECRET=${config.vars.generators.woodpecker-rpc-secret.files.rpc-secret.placeholder}
WOODPECKER_LOG_LEVEL=info
WOODPECKER_DEFAULT_CLONE_PLUGIN=docker.io/woodpeckerci/plugin-git
WOODPECKER_SERVER_ADDR=:8000
WOODPECKER_GRPC_ADDR=:9000
'';
};
# https://woodpecker-ci.org/docs/administration/configuration/backends/docker#environment-variables
"woodpecker-agent-podman.conf" = {
secret = true;
template = pkgs.writeText "woodpecker-agent-podman.conf" (
lib.concatStringsSep "\n" [
shared
''
WOODPECKER_AGENT_SECRET=${config.vars.generators.woodpecker.files.woodpecker-agent-container.placeholder}
WOODPECKER_BACKEND=docker
WOODPECKER_AGENT_LABELS=type=docker
DOCKER_HOST=unix:///run/podman/podman.sock
''
]
);
};
};
};
# enable git-lfs
programs.git = {
enable = true;
lfs.enable = true;
};
services = {
nginx = {
enable = true;
recommendedProxySettings = true;
recommendedOptimisation = true;
recommendedTlsSettings = true;
virtualHosts."woodpecker.fediversity.eu" = {
enableACME = true;
forceSSL = true;
locations."/" = {
recommendedProxySettings = true;
proxyPass = "http://127.0.0.1:8000";
};
};
};
woodpecker-server = {
enable = true;
environmentFile = config.vars.generators."templates".files."woodpecker-server.conf".path;
};
# https://woodpecker-ci.org/docs/administration/configuration/agent
woodpecker-agents.agents = {
docker = {
enable = true;
environmentFile = [ config.vars.generators."templates".files."woodpecker-agent-podman.conf".path ];
extraGroups = [
"podman"
"woodpecker-agent-docker"
];
};
};
};
networking = {
firewall = {
enable = lib.mkForce true;
allowedTCPPorts = [
22
80
443
];
# needed for podman to be able to talk over dns
interfaces."podman+" = {
allowedUDPPorts = [ 53 ];
allowedTCPPorts = [ 53 ];
};
};
# helps make sure DNS resolves from the containers
nftables.enable = lib.mkForce false;
};
virtualisation.podman = {
enable = true;
autoPrune = {
enable = true;
dates = "weekly";
};
defaultNetwork.settings = {
dns_enabled = true;
ipv6_enabled = true;
};
};
systemd.services = {
woodpecker-agent-docker = {
wants = [ "podman.socket" ];
after = [ "podman.socket" ];
};
};
}