diff --git a/hosts/cyper-node-2/configuration.nix b/hosts/cyper-node-2/configuration.nix index 560957b..576027f 100644 --- a/hosts/cyper-node-2/configuration.nix +++ b/hosts/cyper-node-2/configuration.nix @@ -4,6 +4,7 @@ ../../nixos/roles/searxng.nix ../../nixos/roles/frontpage ../../nixos/roles/vaultwarden.nix + ../../nixos/roles/gitea.nix ]; networking = { diff --git a/nixos/roles/gitea.nix b/nixos/roles/gitea.nix new file mode 100644 index 0000000..da18476 --- /dev/null +++ b/nixos/roles/gitea.nix @@ -0,0 +1,206 @@ +{ + pkgs, + lib, + config, + ... +}: + +let + giteaTheme = pkgs.fetchFromGitHub { + owner = "catppuccin"; + repo = "gitea"; + rev = "main"; + sha256 = "sha256-ba5Bh/eTg2Dn80vyuudDpZVbKK1EDyv2rFUSwgMONq0="; + }; + + domain = "192.168.2.31"; # swap to git.cyperpunk.de for prod + httpPort = 9000; + sshPort = 12222; +in +{ + sops.secrets = { + "gitea/dbPassword" = { + owner = "gitea"; + group = "gitea"; + mode = "0444"; + }; + "gitea/internalToken" = { + owner = "gitea"; + group = "gitea"; + }; + "gitea/lfsJwtSecret" = { + owner = "gitea"; + group = "gitea"; + }; + "gitea/mailerPassword" = { + owner = "gitea"; + group = "gitea"; + }; + }; + + services.postgresql = { + enable = true; + package = pkgs.postgresql_14; + ensureDatabases = [ "gitea" ]; + ensureUsers = [ + { + name = "gitea"; + ensureDBOwnership = true; + } + ]; + authentication = lib.mkOverride 10 '' + local all all trust + host all all 127.0.0.1/32 md5 + host all all ::1/128 md5 + ''; + }; + + systemd.services.gitea-db-password = { + description = "Set gitea postgres user password"; + requires = [ "postgresql.service" ]; + after = [ "postgresql.service" ]; + before = [ "gitea.service" ]; + wantedBy = [ "gitea.service" ]; + serviceConfig = { + Type = "oneshot"; + User = "postgres"; + RemainAfterExit = true; + }; + script = '' + pass=$(cat ${config.sops.secrets."gitea/dbPassword".path}) + ${pkgs.postgresql_14}/bin/psql -c \ + "ALTER USER gitea WITH PASSWORD '$pass';" + ''; + }; + + services.gitea = { + enable = true; + package = pkgs.gitea; + user = "gitea"; + group = "gitea"; + + database = { + type = "postgres"; + host = "127.0.0.1"; + port = 5432; + name = "gitea"; + user = "gitea"; + passwordFile = config.sops.secrets."gitea/dbPassword".path; + }; + + settings = { + server = { + DOMAIN = domain; + HTTP_ADDR = "0.0.0.0"; + HTTP_PORT = httpPort; + SSH_PORT = sshPort; + SSH_LISTEN_PORT = sshPort; + ROOT_URL = "http://${domain}:${toString httpPort}/"; + DISABLE_SSH = false; + START_SSH_SERVER = true; + }; + + # security = { + # SECRET_KEY_URI = "file://${config.sops.secrets."gitea/secretKey".path}"; + # INTERNAL_TOKEN_URI = "file://${config.sops.secrets."gitea/internalToken".path}"; + # }; + + #lfs = { + # JWT_SECRET_URI = "file://${config.sops.secrets."gitea/lfsJwtSecret".path}"; + # }; + + ui = { + DEFAULT_THEME = "catppuccin-mocha-green"; + THEMES = lib.concatStringsSep "," [ + # built-in + "gitea" + "arc-green" + # latte + "catppuccin-latte-blue" + "catppuccin-latte-flamingo" + "catppuccin-latte-green" + "catppuccin-latte-lavender" + "catppuccin-latte-maroon" + "catppuccin-latte-mauve" + "catppuccin-latte-peach" + "catppuccin-latte-pink" + "catppuccin-latte-red" + "catppuccin-latte-rosewater" + "catppuccin-latte-sapphire" + "catppuccin-latte-sky" + "catppuccin-latte-teal" + "catppuccin-latte-yellow" + # frappe + "catppuccin-frappe-blue" + "catppuccin-frappe-flamingo" + "catppuccin-frappe-green" + "catppuccin-frappe-lavender" + "catppuccin-frappe-maroon" + "catppuccin-frappe-mauve" + "catppuccin-frappe-peach" + "catppuccin-frappe-pink" + "catppuccin-frappe-red" + "catppuccin-frappe-rosewater" + "catppuccin-frappe-sapphire" + "catppuccin-frappe-sky" + "catppuccin-frappe-teal" + "catppuccin-frappe-yellow" + # macchiato + "catppuccin-macchiato-blue" + "catppuccin-macchiato-flamingo" + "catppuccin-macchiato-green" + "catppuccin-macchiato-lavender" + "catppuccin-macchiato-maroon" + "catppuccin-macchiato-mauve" + "catppuccin-macchiato-peach" + "catppuccin-macchiato-pink" + "catppuccin-macchiato-red" + "catppuccin-macchiato-rosewater" + "catppuccin-macchiato-sapphire" + "catppuccin-macchiato-sky" + "catppuccin-macchiato-teal" + "catppuccin-macchiato-yellow" + # mocha + "catppuccin-mocha-blue" + "catppuccin-mocha-flamingo" + "catppuccin-mocha-green" + "catppuccin-mocha-lavender" + "catppuccin-mocha-maroon" + "catppuccin-mocha-mauve" + "catppuccin-mocha-peach" + "catppuccin-mocha-pink" + "catppuccin-mocha-red" + "catppuccin-mocha-rosewater" + "catppuccin-mocha-sapphire" + "catppuccin-mocha-sky" + "catppuccin-mocha-teal" + "catppuccin-mocha-yellow" + ]; + }; + }; + }; + + # symlink catppuccin css files into gitea's custom dir on every service start + systemd.services.gitea.preStart = lib.mkAfter '' + themeDir="/var/lib/gitea/custom/public/assets/css" + mkdir -p "$themeDir" + for f in ${giteaTheme}/theme/*.css; do + name=$(basename "$f") + ln -sf "$f" "$themeDir/$name" + done + ''; + + users.users.gitea = { + isSystemUser = true; + group = "gitea"; + home = "/var/lib/gitea"; + createHome = true; + }; + users.groups.gitea = { }; + users.users.postgres.extraGroups = [ "gitea" ]; + + networking.firewall.allowedTCPPorts = [ + httpPort + sshPort + ]; +} diff --git a/nixos/roles/restore.sh b/nixos/roles/restore.sh new file mode 100644 index 0000000..74d1870 --- /dev/null +++ b/nixos/roles/restore.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +# Usage: sudo ./restore.sh gitea_dump_*.sql gitea_data_*.tar.gz +set -euo pipefail + +SQL_DUMP="${1:?provide the .sql dump as first argument}" +DATA_ARCHIVE="${2:?provide the data .tar.gz as second argument}" + +GITEA_HOME="/var/lib/gitea" +GITEA_USER="gitea" +DB_NAME="gitea" +DB_USER="gitea" + +echo "[1/5] Stopping gitea..." +systemctl stop gitea + +echo "[2/5] Waiting for postgres..." +until sudo -u postgres psql -c '\q' 2>/dev/null; do sleep 1; done + +echo "[3/5] Restoring database..." +sudo -u postgres psql -c "DROP DATABASE IF EXISTS ${DB_NAME};" +sudo -u postgres psql -c "CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};" +sudo -u postgres psql -d "$DB_NAME" < "$SQL_DUMP" +echo " done." + +echo "[4/5] Restoring gitea data..." +# data/gitea from the docker volume -> /var/lib/gitea +tar xzf "$DATA_ARCHIVE" --strip-components=2 -C "$GITEA_HOME" ./data/gitea + +# ssh host keys -> /var/lib/gitea/ssh +mkdir -p "$GITEA_HOME/ssh" +tar xzf "$DATA_ARCHIVE" --strip-components=1 -C "$GITEA_HOME/ssh" ./ssh + +chown -R "$GITEA_USER":"$GITEA_USER" "$GITEA_HOME" +echo " done." + +echo "[5/5] Starting gitea..." +systemctl start gitea +systemctl status gitea --no-pager diff --git a/secrets/secrets.yaml b/secrets/secrets.yaml index 83debbe..532c4c7 100644 --- a/secrets/secrets.yaml +++ b/secrets/secrets.yaml @@ -6,6 +6,11 @@ matrix_registration_secret: ENC[AES256_GCM,data:KhKkJZqwE8xk4/tuQ7NYTv/Ot1qCAiy8 vaultwarden_admin_token: ENC[AES256_GCM,data:yoBs4CaIEJXB5b3PEwTpXFgxpX39hR9A4r9yamwDV7cTSRRp3n3O2VjDKTcI5Vo6RP2QUjcqUqYf98cZ09wDMc+6+oHHJke7+O0FgRgOC0vOQFs4bfZCBJBLxogrGiwtLGkyykR6VYhrT64AN3CbrXflj82OED2Hl8WwEdruBzGIcfnh6FqQowDx6vDR/kXXJHk=,iv:PJQo5V7FaKPQ+GzZNsy3KB+xyjcDKJ1UBHErrqgn/1U=,tag:BRIDJEDOAeToqio/DHMQaA==,type:str] flame_password: ENC[AES256_GCM,data:1rNB2CskrMV3EYII+0JfZVDvZE8=,iv:pHJtc+1YSPRYrZG97X3r0+x/cPPUlr8jO+0w2HR+VNw=,tag:qQ/1IPxweBt9iIH4Zsh7+A==,type:str] flame_calvin_password: ENC[AES256_GCM,data:P5ppyqTjAJ1TL4hXtx5WyoS9a+g=,iv:sq98P3Oqud2FXfqsD76YS/p5NEF2xlN0MfG+ukCB9B0=,tag:AeKnu4Hg4xQ3tII0y6oNpQ==,type:str] +gitea: + dbPassword: ENC[AES256_GCM,data:S6VvRgkdYk1AzXljyQEEq68UJ9zrFy6+INBMIAspXNcqcM6o+es19o0mcXA=,iv:/pHYpkZZq+9Md+75uSCb2YXfSvaDzUh6mMfH53wb7eg=,tag:ZnbyCQwrK2JnbO5HFqgJYw==,type:str] + internalToken: ENC[AES256_GCM,data:7N8TkPNb1YdCk2uAcCvVd2pKRVOf85//DYxAvz0UCg1E8ccEI5630xVyKafDFiSTM4ER7xiYelartzXL0jLWSf3QNOjSHUP8TIAz4bJRAZUJPxO917bURSLGGe7WEOfONzqy3Ts5QhrJ,iv:DiIs1ytlwLvqD/Ejep6m2fmpSqdFZkxBcgLNt6+29jY=,tag:8jsEcOkH0p+1mP9cnVjiDQ==,type:str] + lfsJwtSecret: ENC[AES256_GCM,data:L20mFZ6zwsF3ZUoodarTJV+vhUdLlBrUbHz7FpEzJ2/C6AdFc1ZZcioN3g==,iv:E2C3gg1OYQ46Ae2bGnhF+3uw+q77l+yph3Kd2fxwW9M=,tag:VQkQ4R9S8Dr39rSLhL/X1w==,type:str] + mailerPassword: "" ssh_private_key: ENC[AES256_GCM,data:R511mVFVk1ogAd5CKk/2P6rtT4NnHIFfKyqeCen545QgcvDqDFmW0rFBmPJyipaya2srJNoWvKJbnvxWtTYeJh2tPAybRMoUicStIFMUn3FPNfjx/WuQFLhKLoU3UOHHPJnkFqkQ9MBqLq2k5K7MVsNNFTxIDCKS1jPgkTmAWjRZ0EFiRXLa+Gvnz3GP5ltgfjDwdPeb5xp0/AqKPD8jea9w5ClR6ckrRHCLsfXhL2e9IaF4B96JlIv4rICLX3HmeIgM2PKl2MnSt8we5z39bBoLSA0yWG6BvpiMBaFqbo7jeHf1SxI6R404/emHhwW3pwSCDrq2ZE1ATG2UmA5NssFcVuaBPBoQer+n5haVYMNpNUp6rtKZeAIbf5JEOXJ6CJqiInfnnzOMNGhGFkGUYkhsy3p6Ti/lmNMPX/xtY+8ZqMwXf5drssm5KgnQ5nDbVqnTWAhoT/D3t+cJVAaXGTGw88fU0X95dZr8vaL/5nBCj1uUdv5cRBJ8PGhqbBX8PoiXrtGooBGhxf6nHbxIneSzG1++MZGo3e1G,iv:D1lgCnZKm3Gyv6cZpQ7zGW7JXN5RCwoaas+LroTkhPc=,tag:WI6Nr1cX8gm5pjFpu/Ok0w==,type:str] ssh_github_key: ENC[AES256_GCM,data:vZAH4cRDsgGXLAppQKOyUPOvmBJZ27bujMGz4hQ8tt0xhGFUP28llwGZz/VRuU02Yv4alLgVWBAIPuyhZT9f35KnjIR1Mmb7HXk/6oaNM59/lBiISLrnOpC10WmJ9O5krKdxwP8ZDvHA34B0s+oYNkTNXiU0S8AVg3icploax7ylKH5Dorj53kjdYSTjd8KN6ZsgCKmcz97+GnP0IgdmauyNL7e+kv9WIfE8Xx1kGvC8WVnidX2YhSxm6vt8l60eUj9etRigU88oFYTDZ+mIf4lucSpzaLZutz2fM/16D/o9SS7mmTrEllj2S+IXc9ZZTRKKDLbW+yv0XUi0XZi+OHAdZScjS54NZKyT9uWrc/IDJHammGsoHRQpHZtbGhkeFi/KdJsYBsWItslXjM0xJVtFIM2tMnd10kv9UGuXsSl9J4NC0rpz3aXnQqG4ZAhMjN9D/DTJpB4K0pcFyd2FDWdrbKq5iPfnU/V6ecnHPML6wCt6gua/LdK1MWoG3l2SqwMLYj1r7UW5fQZqSw1EK0BAtp9cQMLBL/2w8ykMfWpLekE=,iv:gcinU7xOoXQkFVkLNB3sQYHAcZy3pZN+bDRIq4sspys=,tag:yawgAHBKIkGpnKPHsRId4g==,type:str] sops: @@ -19,7 +24,7 @@ sops: N3I5dzUwc3JtYzczMUhyT04vSHlZamMKT+FzYcDLmlEFYxm/XoBpJb8XaZzBH1v9 6fuez+zApathZfl14w41kAUojPWBznnxDqYtNvzVVLXwnpp3BMx+7w== -----END AGE ENCRYPTED FILE----- - lastmodified: "2026-04-11T20:00:05Z" - mac: ENC[AES256_GCM,data:kF9J980KjKieoXEfTXtt79jZsLTBnYn0r7vczQEXckSDtPJ2/fM8uymuVM4H8QRCa5jnlZFI/gYEe9mv9J6jhiV67guwne4pJZ0zaoLdSXaC6UU+EeAzd+bRyHaOPzCR7Fq7vPID7LdW+w1tYlxXN7yEw2mDLyGdg6Qs/G9rAYE=,iv:dLIZmEb+PPXTChmjMrAN8asK3rpbpLRsKSVhQz3O+Zk=,tag:HpJybqhb/aPfKEo6NNbQag==,type:str] + lastmodified: "2026-04-11T21:27:16Z" + mac: ENC[AES256_GCM,data:6uKae66muzkB8qPMUSkya4r4wA4oYnNttu+Md0USTHyY0VlMZefucfgpPGr79JC4l0u99kVRNyEqIY1kp/tdspeKHtGfpWmX4Djx/jMOSPWfzX99Y9ICC9KIdZgYdVJeGiwJKZUEHU0vlAopFGODQ2++sHqjrIAxO1EkGFkAgRA=,iv:Z00NF38aNk26n8+d+3b2bKFJjlN5LVWplyyE6ED9rUw=,tag:5xdT9q0dQXW/SA3CduzJug==,type:str] unencrypted_suffix: _unencrypted version: 3.12.2