From 988a7020f4646983fba7332b42fd26b8fc1183a4 Mon Sep 17 00:00:00 2001 From: imterah Date: Tue, 6 May 2025 22:49:32 -0400 Subject: [PATCH] feature: Add forgejo --- .../stacks/forgejo/docker-compose.nix | 203 ++++++++++++++++++ secrets | 2 +- system/sops.nix | 4 + 3 files changed, 208 insertions(+), 1 deletion(-) create mode 100644 hosts/andromeda/stacks/forgejo/docker-compose.nix diff --git a/hosts/andromeda/stacks/forgejo/docker-compose.nix b/hosts/andromeda/stacks/forgejo/docker-compose.nix new file mode 100644 index 0000000..6b961dd --- /dev/null +++ b/hosts/andromeda/stacks/forgejo/docker-compose.nix @@ -0,0 +1,203 @@ +# Auto-generated using compose2nix v0.3.1. +{ config, pkgs, lib, ... }: + +{ + imports = [ + ../../../../system/sops.nix + ]; + + # Containers + virtualisation.oci-containers.containers."forgejo-db" = { + image = "postgres:17.4"; + environmentFiles = [ config.sops.secrets.forgejo_db_docker_env.path ]; + environment = { + "POSTGRES_DB" = "forgejo"; + "POSTGRES_USER" = "forgejo"; + }; + volumes = [ + "forgejo_db:/var/lib/postgresql/data:rw" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=db" + "--network=forgejo_default" + ]; + }; + + systemd.services."docker-forgejo-db" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_db.service" + ]; + requires = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_db.service" + ]; + partOf = [ + "docker-compose-forgejo-root.target" + ]; + wantedBy = [ + "docker-compose-forgejo-root.target" + ]; + }; + + virtualisation.oci-containers.containers."forgejo-redis" = { + image = "redis:8.0.0"; + volumes = [ + "forgejo_redis:/data:rw" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=redis" + "--network=forgejo_default" + ]; + }; + + systemd.services."docker-forgejo-redis" = { + serviceConfig = { + Restart = lib.mkOverride 90 "no"; + }; + after = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_redis.service" + ]; + requires = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_redis.service" + ]; + partOf = [ + "docker-compose-forgejo-root.target" + ]; + wantedBy = [ + "docker-compose-forgejo-root.target" + ]; + }; + + virtualisation.oci-containers.containers."forgejo-server" = { + image = "codeberg.org/forgejo/forgejo:11"; + environmentFiles = [ config.sops.secrets.forgejo_server_docker_env.path ]; + environment = { + "FORGEJO__cache__ADAPTER" = "redis"; + "FORGEJO__cache__ENABLED" = "true"; + "FORGEJO__cache__HOST" = "redis://redis:6379/0?pool_size=100&idle_timeout=180s"; + "FORGEJO__database__DB_TYPE" = "postgres"; + "FORGEJO__database__HOST" = "db:5432"; + "FORGEJO__database__NAME" = "forgejo"; + "FORGEJO__database__USER" = "forgejo"; + "USER_GID" = "1000"; + "USER_UID" = "1000"; + }; + volumes = [ + "/etc/localtime:/etc/localtime:ro" + "/etc/timezone:/etc/timezone:ro" + "forgejo_forgejo:/data:rw" + ]; + ports = [ + "222:22/tcp" + ]; + labels = { + "traefik.http.routers.gitterahdev.rule" = "Host(`git.terah.dev`)"; + "traefik.http.services.gitterahdev.loadbalancer.server.port" = "3000"; + }; + dependsOn = [ + "forgejo-db" + "forgejo-redis" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=server" + "--network=forgejo_default" + ]; + }; + + systemd.services."docker-forgejo-server" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_forgejo.service" + ]; + requires = [ + "docker-network-forgejo_default.service" + "docker-volume-forgejo_forgejo.service" + ]; + partOf = [ + "docker-compose-forgejo-root.target" + ]; + wantedBy = [ + "docker-compose-forgejo-root.target" + ]; + }; + + # Networks + systemd.services."docker-network-forgejo_default" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f forgejo_default"; + }; + script = '' + docker network inspect forgejo_default || docker network create forgejo_default + ''; + partOf = [ "docker-compose-forgejo-root.target" ]; + wantedBy = [ "docker-compose-forgejo-root.target" ]; + }; + + # Volumes + systemd.services."docker-volume-forgejo_db" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect forgejo_db || docker volume create forgejo_db + ''; + partOf = [ "docker-compose-forgejo-root.target" ]; + wantedBy = [ "docker-compose-forgejo-root.target" ]; + }; + + systemd.services."docker-volume-forgejo_forgejo" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect forgejo_forgejo || docker volume create forgejo_forgejo + ''; + partOf = [ "docker-compose-forgejo-root.target" ]; + wantedBy = [ "docker-compose-forgejo-root.target" ]; + }; + + systemd.services."docker-volume-forgejo_redis" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect forgejo_redis || docker volume create forgejo_redis + ''; + partOf = [ "docker-compose-forgejo-root.target" ]; + wantedBy = [ "docker-compose-forgejo-root.target" ]; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."docker-compose-forgejo-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/secrets b/secrets index 05d59e8..60d55ae 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit 05d59e8bdcd23b9877443bebb1e5894992d786fa +Subproject commit 60d55ae56d5ca38e387e33e8fd186d83e8320839 diff --git a/system/sops.nix b/system/sops.nix index 88dcb68..2ff718f 100755 --- a/system/sops.nix +++ b/system/sops.nix @@ -8,6 +8,7 @@ in sops = { defaultSopsFile = "${secretspath}/secrets.yaml"; + age = { # I'd prefer different OpenSSH keys for different hosts so I'm not 100% screwed if one of my devices get compromised (SSH traffic potentially being decrypted and analyzed). # Therefore, we set a custom path for the sops key & let the SSH key be generated automagically. @@ -15,12 +16,15 @@ in keyFile = "/persist/var/lib/sops-nix/key.txt"; generateKey = false; }; + secrets = { tera_password = { neededForUsers = true; }; reverse_proxy_client_privkey = {}; caddy_docker_env = {}; + forgejo_db_docker_env = {}; + forgejo_server_docker_env = {}; }; }; }