Files
nixy/server-modules/gitea.nix
T
2026-08-27 11:34:20 +02:00

171 lines
5.5 KiB
Nix

{
config,
pkgs,
pkgs-unstable,
lib,
...
}: let
inherit (import ./mk-container.nix {inherit lib config;}) mkContainer;
domain = config.var.domain;
catppuccin-gitea = pkgs-unstable.fetchzip {
url = "https://github.com/catppuccin/gitea/releases/download/v1.0.2/catppuccin-gitea.tar.gz";
sha256 = "sha256-rZHLORwLUfIFcB6K9yhrzr+UwdPNQVSadsw6rg8Q7gs=";
stripRoot = false;
};
giteaUrl = "http://10.233.11.2:3002";
githubUsername = "anotherhadi";
giteaGithubMirror = pkgs.writeShellApplication {
name = "gitea-github-mirror";
runtimeInputs = [pkgs.curl pkgs.jq];
text = ''
github_token="$(cat "$GITHUB_TOKEN_FILE")"
gitea_token="$(cat "$GITEA_TOKEN_FILE")"
tmp_github="$(mktemp)"
tmp_gitea="$(mktemp)"
trap 'rm -f "$tmp_github" "$tmp_gitea"' EXIT
page=1
while :; do
resp="$(curl -sf -H "Authorization: Bearer $github_token" \
"https://api.github.com/user/repos?affiliation=owner&per_page=100&page=$page")"
echo "$resp" >> "$tmp_github"
count="$(echo "$resp" | jq 'length')"
[ "$count" -lt 100 ] && break
page=$((page + 1))
done
page=1
while :; do
resp="$(curl -sf -H "Authorization: token $gitea_token" \
"$GITEA_URL/api/v1/users/$GITEA_OWNER/repos?limit=50&page=$page")"
echo "$resp" >> "$tmp_gitea"
count="$(echo "$resp" | jq 'length')"
[ "$count" -lt 50 ] && break
page=$((page + 1))
done
existing="$(jq -s '[.[][].name]' "$tmp_gitea")"
github_repos="$(jq -s 'add | map(select(.archived | not)) | map({name, private, clone_url, description: (.description // "")})' "$tmp_github")"
echo "$github_repos" | jq -c '.[]' | while IFS= read -r repo; do
name="$(echo "$repo" | jq -r '.name')"
if echo "$existing" | jq -e --arg n "$name" 'index($n)' > /dev/null; then
continue
fi
echo "Mirroring new repo: $name"
body="$(echo "$repo" | jq \
--arg owner "$GITEA_OWNER" \
--arg token "$github_token" \
'{clone_addr: .clone_url, service: "github", repo_name: .name, repo_owner: $owner, mirror: true, private: .private, auth_token: $token, description: .description, mirror_interval: "8h0m0s"}')"
curl -sf -X POST -H "Authorization: token $gitea_token" -H "Content-Type: application/json" \
"$GITEA_URL/api/v1/repos/migrate" -d "$body" > /dev/null \
|| echo "Failed to mirror $name" >&2
done
'';
};
in {
imports = [
(mkContainer {
name = "gitea";
hostIp = "10.233.11.1";
containerIp = "10.233.11.2";
internet = true;
bindMounts."/var/lib/gitea" = {
hostPath = "/var/lib/gitea";
isReadOnly = false;
};
nixosConfig = {lib, ...}: {
users.users.gitea.uid = lib.mkForce 978;
users.groups.gitea.gid = lib.mkForce 968;
services.postgresql = {
enable = true;
ensureDatabases = ["gitea"];
ensureUsers = [
{
name = "gitea";
ensureDBOwnership = true;
}
];
};
services.gitea = {
enable = true;
database.type = "postgres";
settings = {
server = {
HTTP_ADDR = "0.0.0.0";
HTTP_PORT = 3002;
ROOT_URL = "https://git.${domain}/";
DOMAIN = "git.${domain}";
LANDING_PAGE = "/anotherhadi";
};
service = {
REGISTER_MANUAL_CONFIRM = true;
DISABLE_REGISTRATION = true;
DEFAULT_KEEP_EMAIL_PRIVATE = true;
SHOW_REGISTRATION_BUTTON = false;
};
ui = {
DEFAULT_THEME = "catppuccin-mocha-mauve";
THEMES = "catppuccin-latte-mauve,catppuccin-frappe-mauve,catppuccin-macchiato-mauve,catppuccin-mocha-mauve";
};
explore = {
DISABLE_USERS_PAGE = true;
DISABLE_ORGANIZATIONS_PAGE = true;
};
repository.DISABLE_STARS = true;
mailer.ENABLED = false;
api.ENABLE_SWAGGER = false;
other.SHOW_FOOTER_VERSION = false;
};
};
systemd.services.gitea.preStart = lib.mkAfter ''
mkdir -p /var/lib/gitea/custom/public/assets
ln -sfn ${catppuccin-gitea} /var/lib/gitea/custom/public/assets/css
'';
networking.firewall.allowedTCPPorts = [3002];
system.stateVersion = "24.05";
};
})
];
services.cloudflared.tunnels."${config.var.tunnelId}".ingress."git.${domain}" = giteaUrl;
sops.secrets = {
github-mirror-token = {};
gitea-mirror-token = {};
};
systemd.services.gitea-github-mirror = {
description = "Mirror all GitHub repos of ${githubUsername} into Gitea";
after = ["network-online.target" "[email protected]"];
wants = ["network-online.target"];
environment = {
GITHUB_TOKEN_FILE = config.sops.secrets.github-mirror-token.path;
GITEA_TOKEN_FILE = config.sops.secrets.gitea-mirror-token.path;
GITEA_URL = giteaUrl;
GITEA_OWNER = githubUsername;
};
serviceConfig = {
Type = "oneshot";
ExecStart = "${giteaGithubMirror}/bin/gitea-github-mirror";
};
};
systemd.timers.gitea-github-mirror = {
description = "Periodically mirror all GitHub repos into Gitea";
wantedBy = ["timers.target"];
timerConfig = {
OnBootSec = "5m";
OnUnitActiveSec = "30m";
Persistent = true;
};
};
}