Add gitea

Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
2025-05-16 18:16:25 +01:00
parent 1a445ab6fd
commit 3c09cf9f69
19 changed files with 471 additions and 184 deletions

View File

@@ -0,0 +1,256 @@
{
user ? throw "user argument is required",
home ? throw "home argument is required",
}:
{
config,
inputs,
lib,
pkgs,
system,
...
}:
let
selfPkgs = inputs.self.packages.${system};
hmConfig = config.home-manager.users.${user};
inherit (hmConfig.virtualisation.quadlet) volumes networks;
autheliaClientId = "I2ZYDFGWP1bzfiauXe94IaiReZF6SqoEskSp6phoL2L8l16Cq7YX3Vr4pkQOSYfNDOwuFjTRIpqQ8eAqK0M93NeEgpr8YoPhKHyR";
podman = lib.meta.getExe pkgs.podman;
podmanAsUser = "${config.security.wrapperDir}/git-sudo -u ${user} ${podman}";
in
{
security = {
sudo.extraRules = [
{
users = [ config.users.users.git.name ];
runAs = user;
commands = [
{
command = podman;
options = [ "NOPASSWD" ];
}
];
}
];
wrappers."git-sudo" = {
source = "${config.security.sudo.package}/bin/sudo";
owner = "root";
group = "root";
setuid = true;
};
};
users = {
users.git = {
isSystemUser = true;
description = "Git";
uid = config.ids.uids.git;
group = "git";
shell = pkgs.writeShellApplication {
name = "git-podman-shell";
text = ''
${podmanAsUser} exec -i -e SSH_ORIGINAL_COMMAND="$SSH_ORIGINAL_COMMAND" gitea sh "$@"
'';
passthru.shellPath = "/bin/git-podman-shell";
};
};
groups.git.gid = config.ids.uids.git;
};
services.openssh.extraConfig = ''
Match User git
AuthorizedKeysCommandUser git
AuthorizedKeysCommand ${podmanAsUser} exec -i gitea gitea keys -c /etc/gitea/app.ini -e git -u %u -t %t -k %k
'';
home-manager.users.${user} = {
sops = {
secrets = {
"gitea/postgresql".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/smtp".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/secretKey".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/internalToken".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/jwtSecret".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/lfsJwtSecret".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/authelia/password".sopsFile = ../../../../../../secrets/secrets.yaml;
"gitea/authelia/digest".sopsFile = ../../../../../../secrets/secrets.yaml;
};
templates = {
gitea-postgresql-env.content = ''
POSTGRES_PASSWORD=${hmConfig.sops.placeholder."gitea/postgresql"}
'';
gitea-env.content = ''
GITEA_OAUTH_SECRET=${hmConfig.sops.placeholder."gitea/authelia/password"}
'';
gitea.content = builtins.readFile (
(pkgs.formats.iniWithGlobalSection { }).generate "app.ini" {
globalSection = {
I_AM_BEING_UNSAFE_RUNNING_AS_ROOT = true;
};
sections = {
server = {
ROOT_URL = "https://git.karaolidis.com:443/";
# FIXME: https://github.com/go-gitea/gitea/issues/31112
OFFLINE_MODE = false;
SSH_USER = "git";
SSH_DOMAIN = "karaolidis.com";
SSH_CREATE_AUTHORIZED_KEYS_FILE = false;
LFS_START_SERVER = true;
LFS_ALLOW_PURE_SSH = true;
LFS_JWT_SECRET = hmConfig.sops.placeholder."gitea/lfsJwtSecret";
};
service = {
ALLOW_ONLY_EXTERNAL_REGISTRATION = true;
SHOW_REGISTRATION_BUTTON = false;
};
openid = {
ENABLE_OPENID_SIGNUP = true;
WHITELISTED_URIS = "id.karaolidis.com";
};
oauth2 = {
JWT_SECRET = hmConfig.sops.placeholder."gitea/jwtSecret";
};
oauth2_client = {
ENABLE_AUTO_REGISTRATION = true;
USERNAME = "preferred_username";
};
repository = {
ENABLE_PUSH_CREATE_USER = true;
};
database = {
DB_TYPE = "postgres";
HOST = "gitea-postgresql:5432";
NAME = "gitea";
USER = "gitea";
PASSWD = hmConfig.sops.placeholder."gitea/postgresql";
};
mailer = {
ENABLE = true;
PROTOCOL = "smtp+starttls";
SMTP_ADDR = "smtp.protonmail.ch";
SMTP_PORT = 587;
USER = "jupiter@karaolidis.com";
PASSWD = hmConfig.sops.placeholder."gitea/smtp";
FROM = "jupiter@karaolidis.com";
};
security = {
INSTALL_LOCK = true;
SECRET_KEY = hmConfig.sops.placeholder."gitea/secretKey";
INTERNAL_TOKEN = hmConfig.sops.placeholder."gitea/internalToken";
};
metrics = {
ENABLED = true;
};
};
}
);
authelia-gitea.content = builtins.readFile (
(pkgs.formats.yaml { }).generate "gitea.yaml" {
identity_providers.oidc = {
authorization_policies.git = {
default_policy = "deny";
rules = [
{
policy = "one_factor";
subject = "group:git";
}
];
};
clients = [
{
client_id = autheliaClientId;
client_name = "Gitea";
client_secret = hmConfig.sops.placeholder."gitea/authelia/digest";
redirect_uris = [ "https://git.karaolidis.com/user/oauth2/authelia/callback" ];
authorization_policy = "git";
}
];
};
}
);
};
};
virtualisation.quadlet = {
networks.gitea.networkConfig.internal = true;
volumes = {
gitea-postgresql = { };
gitea = { };
};
containers = {
gitea =
let
entrypoint = pkgs.writeTextFile {
name = "entrypoint.sh";
executable = true;
text = builtins.readFile ./entrypoint.sh;
};
in
{
containerConfig = {
image = "docker-archive:${selfPkgs.docker-gitea}";
networks = [
networks.gitea.ref
networks.traefik.ref
];
volumes = [
"${volumes.gitea.ref}:/var/lib/gitea/data"
"${hmConfig.sops.templates.gitea.path}:/etc/gitea/app.ini:ro"
"${entrypoint}:/entrypoint.sh:ro"
];
environments.GITEA_OAUTH_KEY = autheliaClientId;
environmentFiles = [ hmConfig.sops.templates.gitea-env.path ];
entrypoint = "/entrypoint.sh";
labels = [
"traefik.enable=true"
"traefik.http.routers.gitea.rule=Host(`git.karaolidis.com`)"
];
};
unitConfig.After = [ "sops-nix.service" ];
};
gitea-postgresql = {
containerConfig = {
image = "docker-archive:${selfPkgs.docker-postgresql}";
networks = [ networks.gitea.ref ];
volumes = [ "${volumes.gitea-postgresql.ref}:/var/lib/postgresql/data" ];
environments = {
POSTGRES_DB = "gitea";
POSTGRES_USER = "gitea";
};
environmentFiles = [ hmConfig.sops.templates.gitea-postgresql-env.path ];
};
unitConfig.After = [ "sops-nix.service" ];
};
authelia-init.containerConfig.volumes = [
"${hmConfig.sops.templates.authelia-gitea.path}:/etc/authelia/conf.d/gitea.yaml:ro"
];
};
};
};
}

View File

@@ -0,0 +1,17 @@
#!/bin/sh
gitea migrate -c /etc/gitea/app.ini
gitea admin auth add-oauth \
-c /etc/gitea/app.ini \
--name=authelia \
--provider=openidConnect \
--key="$GITEA_OAUTH_KEY" \
--secret="$GITEA_OAUTH_SECRET" \
--auto-discover-url=https://id.karaolidis.com/.well-known/openid-configuration \
--scopes='openid email profile groups' \
--skip-local-2fa \
--group-claim-name=groups \
--admin-group=admins 2>&1 || true
exec gitea web -c /etc/gitea/app.ini