{
config,
lib,
pkgs,
...
}:
let
inherit (lib)
pipe
flatten
concatMapAttrs
mapAttrsToList
;
inherit (import ../../../lib/caddy.nix { inherit lib; }) security-headers;
domain = "alin.ovh";
serverName = "git.${domain}";
gitoliteCfg = config.services.gitolite;
repos = "${gitoliteCfg.dataDir}/repositories";
mirrors = {
sourcehut = {
hostname = "git.sr.ht";
username = "~alanpearce";
};
codeberg = {
hostname = "codeberg.org";
username = "alanpearce";
};
github = {
hostname = "github.com";
username = "alanpearce";
};
gitlab = {
hostname = "gitlab.com";
username = "alanpearce";
};
};
repoMirrors = {
nixfiles = [
"sourcehut"
"codeberg"
];
searchix = [
"sourcehut"
"codeberg"
];
website = [ "sourcehut" ];
homestead = [ "sourcehut" ];
htmlformat = [
"codeberg"
"github"
];
legit = [ "github" ];
elgit = [ "codeberg" ];
gomponents = [
"sourcehut"
"github"
];
nix-packages = [
"sourcehut"
"github"
];
zola-bearblog = [
"sourcehut"
"codeberg"
"gitlab"
];
};
createMirrorService =
name:
{ hostname, username }:
{
"mirror-to-${name}@" = {
path = with pkgs; [
gitMinimal
openssh
];
serviceConfig = {
Type = "oneshot";
User = "gitolite";
WorkingDirectory = "${repos}/%i.git";
ExecStart = "${pkgs.gitMinimal}/bin/git push --mirror git@${hostname}:${username}/%i";
};
unitConfig = {
# only mirror public repositories
ConditionPathExists = "${repos}/%i.git/git-daemon-export-ok";
};
};
};
createMirrorPath =
name:
{ ... }:
{
"mirror-to-${name}@" = {
pathConfig = {
PathChanged = "${repos}/%i.git/refs/heads";
StartLimitIntervalSec = "1h";
StartLimitBurst = 5;
};
};
};
mkMirrorWants = repo: map (target: "mirror-to-${target}@${repo}.path");
in
{
services.gitolite = {
enable = true;
adminPubkey = "ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBHYUyDdw92TNXguAxcmcmZmn/7ECGdRp6ckjxU+5zCw3BCnsS5+xEvHBVnnFdJRoH2XpfMeJjE+fi67zFVhlbn4= root@secretive.marvin";
extraGitoliteRc = ''
$RC{UMASK} = 0027;
$RC{LOG_EXTRA} = 0;
$RC{HOSTNAME} = "${config.networking.hostName}";
$RC{LOCAL_CODE} = "$rc{GL_ADMIN_BASE}/local";
push( @{$RC{ENABLE}}, 'D' );
push( @{$RC{ENABLE}}, 'Shell alan' );
push( @{$RC{ENABLE}}, 'cgit' );
push( @{$RC{ENABLE}}, 'repo-specific-hooks' );
'';
};
services.elgit = {
enable = true;
group = gitoliteCfg.group;
settings = {
server.name = serverName;
repo = {
root = gitoliteCfg.dataDir;
};
dirs.static = "/srv/http/elgit/static";
};
};
services.gitDaemon = {
enable = true;
user = "gitolite";
group = gitoliteCfg.group;
basePath = repos;
};
services.caddy.virtualHosts = {
"${serverName}" =
let
settings = config.services.elgit.settings;
server = settings.server;
in
{
extraConfig = ''
encode zstd gzip
${security-headers {
overrides.content-security-policy = {
default-src = [ "none" ];
base-uri = [ "none" ];
style-src = [ "self" ];
script-src = [ "none" ];
form-action = [ "self" ];
connect-src = [ "self" ];
img-src = [ "https:" ];
object-src = [ "none" ];
};
}}
reverse_proxy ${server.host}:${toString server.port}
'';
};
"git.alanpearce.eu" = {
extraConfig = ''
redir https://${serverName}{uri} 301 permanent
'';
};
};
systemd.services = concatMapAttrs createMirrorService mirrors;
systemd.paths = concatMapAttrs createMirrorPath mirrors;
systemd.targets.git-mirroring = {
wantedBy = [ "multi-user.target" ];
wants = pipe repoMirrors [
(mapAttrsToList mkMirrorWants)
flatten
];
};
}
system/settings/services/git-server.nix (view raw)