{ config, pkgs, lib, ... }: with lib; let cfg = config.services.skynet_gitlab; backup_path = "/etc/skynet/backups/gitlab"; domain_base = "${cfg.domain.base}.${cfg.domain.tld}"; domain_full = "${cfg.domain.sub}.${domain_base}"; in { imports = [ ./acme.nix ./dns.nix ./firewall.nix ./nginx.nix ]; options.services.skynet_gitlab = { enable = mkEnableOption "Skynet Gitlab"; host = { ip = mkOption { type = types.str; }; name = mkOption { type = types.str; }; }; domain = { tld = mkOption { type = types.str; default = "ie"; }; base = mkOption { type = types.str; default = "skynet"; }; sub = mkOption { type = types.str; default = "gitlab"; }; }; user = mkOption { type = types.str; # changes teh ssh user default = "git"; }; ldap = { base = mkOption { type = types.str; default = "dc=skynet,dc=ie"; description = lib.mdDoc "The base address in the ldap server"; }; }; }; config = mkIf cfg.enable { # delete all data # rm -rf /run/gitlab && rm -rf /var/gitlab && rm -rf /var/lib/postgresql && rm -rf /run/gitlab && rm -rf /var/lib/redis-gitlab # find all data # grep -r --exclude-dir={docker,containers,log,sys,nix,proc} gitlab / age.secrets.gitlab_pw = { file = ../secrets/gitlab/pw.age; owner = cfg.user; group = cfg.user; }; age.secrets.gitlab_secrets_db = { file = ../secrets/gitlab/secrets_db.age; owner = cfg.user; group = cfg.user; }; age.secrets.gitlab_secrets_secret = { file = ../secrets/gitlab/secrets_secret.age; owner = cfg.user; group = cfg.user; }; age.secrets.gitlab_secrets_otp = { file = ../secrets/gitlab/secrets_otp.age; owner = cfg.user; group = cfg.user; }; age.secrets.gitlab_secrets_jws = { file = ../secrets/gitlab/secrets_jws.age; owner = cfg.user; group = cfg.user; }; age.secrets.gitlab_db_pw = { file = ../secrets/gitlab/db_pw.age; owner = cfg.user; group = cfg.user; }; skynet_acme.domains = [ "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" # Lets Encrypt seems to have a 4 levels limit for certs "*.pages.${cfg.domain.base}.${cfg.domain.tld}" ]; # using https://nixos.org/manual/nixos/stable/index.html#module-services-gitlab as a guide skynet_dns.records = [ { record = cfg.domain.sub; r_type = "A"; value = cfg.host.ip; } # for gitlab pages { record = "*.pages.${cfg.domain.base}.${cfg.domain.tld}."; r_type = "A"; value = cfg.host.ip; } # for email { record = "${cfg.domain.sub}"; r_type = "MX"; value = ''10 ${domain_full}.''; } { record = cfg.host.ip; r_type = "PTR"; value = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}."; } { record = "${domain_full}."; r_type = "TXT"; value = ''"v=spf1 a:gitlab.skynet.ie -all"''; } { record = "_dmarc.${domain_full}."; r_type = "TXT"; value = ''"v=DMARC1; p=none"''; } ]; networking.firewall.allowedTCPPorts = [ # for git 2222 ]; services.openssh.ports = [22 2222]; services.nginx.virtualHosts = { "${cfg.host.ip}" = { forceSSL = true; useACMEHost = "skynet"; locations."/".return = "307 https://skynet.ie"; }; # main site "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}" = { forceSSL = true; useACMEHost = "skynet"; locations."/".proxyPass = "http://unix:/run/gitlab/gitlab-workhorse.socket"; }; # pages "*.pages.${cfg.domain.base}.${cfg.domain.tld}" = { forceSSL = true; useACMEHost = "skynet"; locations."/".proxyPass = "http://127.0.0.1:8091"; }; }; # set a valid HELO address services.postfix = { hostname = lib.mkForce domain_full; origin = lib.mkForce domain_full; domain = lib.mkForce domain_base; }; services.skynet_backup.normal.backups = [ backup_path ]; services.gitlab = { enable = true; databasePasswordFile = config.age.secrets.gitlab_db_pw.path; initialRootPasswordFile = config.age.secrets.gitlab_pw.path; https = true; host = "${cfg.domain.sub}.${cfg.domain.base}.${cfg.domain.tld}"; port = 443; user = cfg.user; group = cfg.user; databaseUsername = cfg.user; pages = { # TODO: https://docs.gitlab.com/ee/administration/pages/index.html#add-the-domain-to-the-public-suffix-list enable = true; settings = { # these are just examples, not to use #artifacts-server = "http(s):///api/v4" #gitlab-server = "http(s)://" pages-domain = "pages.${cfg.domain.base}.${cfg.domain.tld}"; listen-http = [ "127.0.0.1:8091" ]; /* auth-client-id = "generated-id-xxxxxxx"; auth-client-secret = { _secret = "/var/keys/auth-client-secret"; }; auth-redirect-uri = "https://projects.example.com/auth"; auth-secret = { _secret = "/var/keys/auth-secret"; }; auth-server = "https://gitlab.example.com"; */ }; }; # see https://github.com/NixOS/nixpkgs/blob/master/nixos/modules/services/misc/gitlab.nix#L295 backup = { startAt = "Sat *-*-* 04:00:00"; # Sat 4am weekly path = backup_path; keepTime = 24; # (Hours) Backups are uploaded to seperate server skip = ["builds" "artifacts" "registry" "terraform_state"]; # see https://docs.gitlab.com/ee/administration/backup_restore/backup_gitlab.html#excluding-specific-data-from-the-backup }; # use the local email client smtp.enable = true; secrets = { dbFile = config.age.secrets.gitlab_secrets_db.path; secretFile = config.age.secrets.gitlab_secrets_secret.path; otpFile = config.age.secrets.gitlab_secrets_otp.path; jwsFile = config.age.secrets.gitlab_secrets_jws.path; }; extraConfig = { gitlab_shell = { ssh_port = 2222; }; ldap = { enabled = true; servers = { main = { label = "Skynet"; host = "account.skynet.ie"; port = 636; uid = "uid"; encryption = "simple_tls"; active_directory = false; base = "ou=users,${cfg.ldap.base}"; user_filter = "(memberOf=cn=skynet-users,ou=groups,${cfg.ldap.base}))"; attributes = { username = "uid"; email = "skMail"; name = "cn"; }; group_base = "ou=groups,${cfg.ldap.base}"; admin_group = "skynet-admins"; sync_ssh_keys = "sshPublicKey"; }; }; }; pages = { # default for pages is set to 8090 but that leaves an "ugly" port in the url, # override it here to make it look good port = 80; #external_http = ["${cfg.host.ip}:80"]; }; }; }; }; }