nixos/modules/server/services/forgejo/pages.nix

184 lines
5.6 KiB
Nix
Raw Normal View History

2025-01-05 15:22:43 +04:00
# this pr https://github.com/NixOS/nixpkgs/pull/370864
{ config, pkgs, lib, ... }:
let
inherit (lib) mkIf mkOption mkEnableOption mkPackageOption;
inherit (lib) types;
2025-01-05 15:24:07 +04:00
cfg = config.void.server.services.forgejo.pages;
2025-01-05 15:22:43 +04:00
in {
meta.maintainers = with lib.maintainers; [ NotAShelf ];
options = {
2025-01-05 15:23:33 +04:00
void.server.services.forgejo.pages = {
2025-01-05 15:22:43 +04:00
enable = mkEnableOption "Codeberg pages server";
package = mkPackageOption pkgs "codeberg-pages" { };
stateDir = mkOption {
type = types.str;
default = "/var/lib/codeberg-pages";
description = "Directory in which state will be stored";
};
user = mkOption {
type = types.str;
default = "codeberg-pages";
description = "User account under which Codeberg Pages will run.";
};
group = mkOption {
type = types.str;
default = "codeberg-pages";
description = "Group under under which Codeberg Pages will run.";
};
settings = mkOption {
type = with types; submodule { freeformType = attrsOf str; };
default = { };
example = {
ACME_ACCEPT_TERMS = true;
ENABLE_HTTP_SERVER = true;
GITEA_ROOT = "git.exampledomain.tld";
};
description = ''
Configuration values to be passed to the codeberg pages server
as environment variables.
[pages-server documentation]: https://codeberg.org/Codeberg/pages-server#environment-variables
See [pages-server documentation] for available options.
For sensitive values, prefer using {option}`services.pages-server.environmentFile`.
'';
};
environmentFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/run/secret/pages-server.env";
description = ''
An environment file as defined in {manpage}`systemd.exec(5)`.
Sensitive information, such as `GITEA_API_TOKEN`, may be passed
to the service without adding them to the world-readable Nix store.
'';
};
};
};
config = lib.mkIf cfg.enable {
systemd = {
tmpfiles.rules =
[ "d '${cfg.stateDir}' 0750 ${cfg.user} ${cfg.group} - -" ];
services.codeberg-pages = {
description = "Codeberg Pages Server";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = cfg.settings;
serviceConfig = {
Type = "simple";
User = cfg.user;
Group = cfg.group;
StateDirectory = cfg.stateDir;
WorkingDirectory = cfg.stateDir;
ReadWritePaths = [ cfg.stateDir ];
ExecStart = "${lib.getExe cfg.package}";
EnvironmentFile =
lib.optional (cfg.environmentFile != null) cfg.environmentFile;
Restart = "on-failure";
# Security section directly mimics the one of Forgejo module
# Capabilities
CapabilityBoundingSet = "";
# Security
NoNewPrivileges = true;
# Sandboxing
ProtectSystem = "strict";
ProtectHome = true;
PrivateTmp = true;
PrivateDevices = true;
PrivateUsers = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
RestrictAddressFamilies = [ "AF_UNIX" "AF_INET" "AF_INET6" ];
RestrictNamespaces = true;
LockPersonality = true;
MemoryDenyWriteExecute = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
# System Call Filtering
SystemCallArchitectures = "native";
SystemCallFilter = [
"~@cpu-emulation @debug @keyring @mount @obsolete @privileged @setuid"
"setrlimit"
];
};
};
};
users.users = mkIf (cfg.user == "codeberg-pages") {
codeberg-pages = {
home = cfg.stateDir;
useDefaultShell = true;
group = cfg.group;
isSystemUser = true;
};
};
users.groups =
mkIf (cfg.group == "codeberg-pages") { codeberg-pages = { }; };
2025-01-05 16:22:42 +04:00
services.nginx.virtualHosts = {
2025-01-05 16:24:12 +04:00
"pages.sako.lol" = {
2025-01-05 16:22:42 +04:00
# listen = [{
# addr = "0.0.0.0";
# port = 443;
# # ssl = true;
# }];
2025-01-05 16:23:29 +04:00
forceSSL = true;
2025-01-05 16:24:12 +04:00
enableACME = true;
2025-01-05 16:33:56 +04:00
extraConfig = ''
proxy_ssl_server_name on;
'';
locations."/" = { proxyPass = "https://localhost:4563"; };
2025-01-05 16:22:42 +04:00
};
2025-01-05 16:35:13 +04:00
"*.pages.sako.lol" = {
# listen = [{
# addr = "0.0.0.0";
# port = 443;
# # ssl = true;
# }];
forceSSL = true;
useACMEHost = "pages.sako.lol";
2025-01-05 16:35:13 +04:00
extraConfig = ''
proxy_ssl_server_name on;
'';
locations."/" = { proxyPass = "https://localhost:4563"; };
};
2025-01-05 16:22:42 +04:00
};
2025-01-05 16:20:22 +04:00
security.acme.certs."pages.sako.lol" = {
2025-01-05 17:34:36 +04:00
extraDomainNames = [ "*.pages.sako.lol" ];
2025-01-05 16:19:24 +04:00
credentialsFile = "/srv/secrets/porkbun";
dnsProvider = "porkbun";
webroot = null;
2025-01-05 16:00:01 +04:00
};
2025-01-05 16:27:26 +04:00
# services.nginx.streamConfig = ''
# server {
# server_name *.pages.sako.lol;
# listen 55342 ssl;
# ssl_certificate /var/lib/acme/pages.sako.lol/fullchain.pem;
# ssl_certificate_key /var/lib/acme/pages.sako.lol/key.pem;
# proxy_connect_timeout 1s;
# proxy_timeout 3s;
# proxy_pass https://localhost:4563;
# ssl_preread on;
# }
# '';
2025-01-05 15:22:43 +04:00
};
}