1{ 2 config, 3 lib, 4 pkgs, 5 ... 6}: 7 8let 9 cfg = config.services.woodpecker-server; 10in 11{ 12 meta.maintainers = with lib.maintainers; [ ambroisie ]; 13 14 options = { 15 services.woodpecker-server = { 16 enable = lib.mkEnableOption "the Woodpecker-Server, a CI/CD application for automatic builds, deployments and tests"; 17 package = lib.mkPackageOption pkgs "woodpecker-server" { }; 18 environment = lib.mkOption { 19 default = { }; 20 type = lib.types.attrsOf lib.types.str; 21 example = lib.literalExpression '' 22 { 23 WOODPECKER_HOST = "https://woodpecker.example.com"; 24 WOODPECKER_OPEN = "true"; 25 WOODPECKER_GITEA = "true"; 26 WOODPECKER_GITEA_CLIENT = "ffffffff-ffff-ffff-ffff-ffffffffffff"; 27 WOODPECKER_GITEA_URL = "https://git.example.com"; 28 } 29 ''; 30 description = "woodpecker-server config environment variables, for other options read the [documentation](https://woodpecker-ci.org/docs/administration/server-config)"; 31 }; 32 environmentFile = lib.mkOption { 33 type = with lib.types; coercedTo path (f: [ f ]) (listOf path); 34 default = [ ]; 35 example = [ "/root/woodpecker-server.env" ]; 36 description = '' 37 File to load environment variables 38 from. This is helpful for specifying secrets. 39 Example content of environmentFile: 40 ``` 41 WOODPECKER_AGENT_SECRET=your-shared-secret-goes-here 42 WOODPECKER_GITEA_SECRET=gto_************************************** 43 ``` 44 ''; 45 }; 46 }; 47 }; 48 49 config = lib.mkIf cfg.enable { 50 systemd.services = { 51 woodpecker-server = { 52 description = "Woodpecker-Server Service"; 53 wantedBy = [ "multi-user.target" ]; 54 after = [ "network-online.target" ]; 55 wants = [ "network-online.target" ]; 56 serviceConfig = { 57 DynamicUser = true; 58 WorkingDirectory = "%S/woodpecker-server"; 59 StateDirectory = "woodpecker-server"; 60 StateDirectoryMode = "0700"; 61 UMask = "0007"; 62 ConfigurationDirectory = "woodpecker-server"; 63 EnvironmentFile = cfg.environmentFile; 64 ExecStart = "${cfg.package}/bin/woodpecker-server"; 65 Restart = "on-failure"; 66 RestartSec = 15; 67 CapabilityBoundingSet = ""; 68 # Security 69 NoNewPrivileges = true; 70 # Sandboxing 71 ProtectSystem = "strict"; 72 ProtectHome = true; 73 PrivateTmp = true; 74 PrivateDevices = true; 75 PrivateUsers = true; 76 ProtectHostname = true; 77 ProtectClock = true; 78 ProtectKernelTunables = true; 79 ProtectKernelModules = true; 80 ProtectKernelLogs = true; 81 ProtectControlGroups = true; 82 RestrictAddressFamilies = [ "AF_UNIX AF_INET AF_INET6" ]; 83 LockPersonality = true; 84 MemoryDenyWriteExecute = true; 85 RestrictRealtime = true; 86 RestrictSUIDSGID = true; 87 PrivateMounts = true; 88 # System Call Filtering 89 SystemCallArchitectures = "native"; 90 SystemCallFilter = "~@clock @privileged @cpu-emulation @debug @keyring @module @mount @obsolete @raw-io @reboot @setuid @swap"; 91 }; 92 inherit (cfg) environment; 93 }; 94 }; 95 }; 96}