{ lib, ... }: { services.gitea = { enable = true; # Migrated sqlite DB and repos; do not provision a fresh database. database = { type = "sqlite3"; createDatabase = false; }; settings = { server = { DOMAIN = "git.chiasson.cloud"; HTTP_PORT = 3002; ROOT_URL = "https://git.chiasson.cloud/"; # Clone URLs and LAN git@… -p 222 (was Docker host 222 → container 22). # Port 222 is <1024 (privileged); systemd must grant CAP_NET_BIND_SERVICE below. SSH_PORT = 222; START_SSH_SERVER = true; SSH_LISTEN_HOST = "0.0.0.0"; SSH_LISTEN_PORT = 222; }; service.DISABLE_REGISTRATION = false; }; }; # First boot after migration runs DB migrate + hook regen; default WatchdogSec=30 kills # gitea while storage/actions init is still running. Type=notify also fails if startup # is slow; PrivateUsers breaks access to migrated files owned by the real gitea uid. # Port 222 is privileged (<1024); Docker mapped host 222→container 22 as root. systemd.services.gitea.serviceConfig = { Type = lib.mkForce "simple"; PrivateUsers = lib.mkForce false; NoNewPrivileges = lib.mkForce false; AmbientCapabilities = "CAP_NET_BIND_SERVICE"; CapabilityBoundingSet = lib.mkForce [ "CAP_NET_BIND_SERVICE" ]; TimeoutStartSec = lib.mkForce "20min"; WatchdogSec = lib.mkForce 0; }; networking.firewall.allowedTCPPorts = [ 3002 222 ]; }