From 1a40c48be86bfca841e9e2d3b0fd8ebee31d3c59 Mon Sep 17 00:00:00 2001 From: imterah Date: Wed, 7 May 2025 23:09:31 -0400 Subject: [PATCH] feature: Adds Pterodactyl --- hosts/andromeda/configuration.nix | 1 + .../stacks/pterodactyl/docker-compose.nix | 206 ++++++++++++++++++ secrets | 2 +- system/sops.nix | 2 + 4 files changed, 210 insertions(+), 1 deletion(-) create mode 100644 hosts/andromeda/stacks/pterodactyl/docker-compose.nix diff --git a/hosts/andromeda/configuration.nix b/hosts/andromeda/configuration.nix index c478b4b..809955f 100755 --- a/hosts/andromeda/configuration.nix +++ b/hosts/andromeda/configuration.nix @@ -20,6 +20,7 @@ ./stacks/caddy/docker-compose.nix ./stacks/portainer/docker-compose.nix ./stacks/passbolt/docker-compose.nix + ./stacks/pterodactyl/docker-compose.nix ./stacks/mcaptcha/docker-compose.nix ./stacks/forgejo/docker-compose.nix ./stacks/terah.dev/docker-compose.nix diff --git a/hosts/andromeda/stacks/pterodactyl/docker-compose.nix b/hosts/andromeda/stacks/pterodactyl/docker-compose.nix new file mode 100644 index 0000000..57fe259 --- /dev/null +++ b/hosts/andromeda/stacks/pterodactyl/docker-compose.nix @@ -0,0 +1,206 @@ +# Auto-generated using compose2nix v0.3.1. +{ config, pkgs, lib, ... }: + +{ + imports = [ + ../../../../system/sops.nix + ]; + + # Containers + virtualisation.oci-containers.containers."pterodactyl-cache" = { + image = "redis:alpine"; + log-driver = "journald"; + extraOptions = [ + "--network-alias=cache" + "--network=pterodactyl_default" + ]; + }; + + systemd.services."docker-pterodactyl-cache" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-pterodactyl_default.service" + ]; + requires = [ + "docker-network-pterodactyl_default.service" + ]; + partOf = [ + "docker-compose-pterodactyl-root.target" + ]; + wantedBy = [ + "docker-compose-pterodactyl-root.target" + ]; + }; + + virtualisation.oci-containers.containers."pterodactyl-database" = { + image = "mariadb:10.11"; + environmentFiles = [ config.sops.secrets.pterodactyl_db_docker_env.path ]; + environment = { + "MYSQL_DATABASE" = "panel"; + "MYSQL_RANDOM_ROOT_PASSWORD" = "true"; + "MYSQL_USER" = "pterodactyl"; + }; + volumes = [ + "pterodactyl_db:/var/lib/mysql:rw" + ]; + cmd = [ "--default-authentication-plugin=mysql_native_password" ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=database" + "--network=pterodactyl_default" + ]; + }; + + systemd.services."docker-pterodactyl-database" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-pterodactyl_default.service" + "docker-volume-pterodactyl_db.service" + ]; + requires = [ + "docker-network-pterodactyl_default.service" + "docker-volume-pterodactyl_db.service" + ]; + partOf = [ + "docker-compose-pterodactyl-root.target" + ]; + wantedBy = [ + "docker-compose-pterodactyl-root.target" + ]; + }; + + virtualisation.oci-containers.containers."pterodactyl-panel" = { + image = "ghcr.io/pterodactyl/panel:latest"; + environmentFiles = [ config.sops.secrets.pterodactyl_pterodactyl_docker_env.path ]; + environment = { + "APP_ENV" = "production"; + "APP_ENVIRONMENT_ONLY" = "false"; + "APP_SERVICE_AUTHOR" = "noreply@hofers.cloud"; + "APP_TIMEZONE" = "America/Indiana/Indianapolis"; + "APP_URL" = "https://pterodactyl.hofers.cloud"; + "CACHE_DRIVER" = "redis"; + "DB_HOST" = "database"; + "DB_PORT" = "3306"; + "QUEUE_DRIVER" = "redis"; + "REDIS_HOST" = "cache"; + "SESSION_DRIVER" = "redis"; + "TRUSTED_PROXIES" = "*"; + }; + volumes = [ + "pterodactyl_ptero_logs:/app/storage/logs:rw" + "pterodactyl_ptero_var:/app/var:rw" + ]; + labels = { + "traefik.http.routers.pterodactyl.rule" = "Host(`pterodactyl.hofers.cloud`)"; + }; + dependsOn = [ + "pterodactyl-cache" + "pterodactyl-database" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=panel" + "--network=pterodactyl_default" + ]; + }; + + systemd.services."docker-pterodactyl-panel" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + RestartMaxDelaySec = lib.mkOverride 90 "1m"; + RestartSec = lib.mkOverride 90 "100ms"; + RestartSteps = lib.mkOverride 90 9; + }; + after = [ + "docker-network-pterodactyl_default.service" + "docker-volume-pterodactyl_ptero_logs.service" + "docker-volume-pterodactyl_ptero_var.service" + ]; + requires = [ + "docker-network-pterodactyl_default.service" + "docker-volume-pterodactyl_ptero_logs.service" + "docker-volume-pterodactyl_ptero_var.service" + ]; + partOf = [ + "docker-compose-pterodactyl-root.target" + ]; + wantedBy = [ + "docker-compose-pterodactyl-root.target" + ]; + }; + + # Networks + systemd.services."docker-network-pterodactyl_default" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "docker network rm -f pterodactyl_default"; + }; + script = '' + docker network inspect pterodactyl_default || docker network create pterodactyl_default + ''; + partOf = [ "docker-compose-pterodactyl-root.target" ]; + wantedBy = [ "docker-compose-pterodactyl-root.target" ]; + }; + + # Volumes + systemd.services."docker-volume-pterodactyl_db" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect pterodactyl_db || docker volume create pterodactyl_db + ''; + partOf = [ "docker-compose-pterodactyl-root.target" ]; + wantedBy = [ "docker-compose-pterodactyl-root.target" ]; + }; + + systemd.services."docker-volume-pterodactyl_ptero_logs" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect pterodactyl_ptero_logs || docker volume create pterodactyl_ptero_logs + ''; + partOf = [ "docker-compose-pterodactyl-root.target" ]; + wantedBy = [ "docker-compose-pterodactyl-root.target" ]; + }; + + systemd.services."docker-volume-pterodactyl_ptero_var" = { + path = [ pkgs.docker ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + docker volume inspect pterodactyl_ptero_var || docker volume create pterodactyl_ptero_var + ''; + partOf = [ "docker-compose-pterodactyl-root.target" ]; + wantedBy = [ "docker-compose-pterodactyl-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-pterodactyl-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/secrets b/secrets index 31517aa..6784f0a 160000 --- a/secrets +++ b/secrets @@ -1 +1 @@ -Subproject commit 31517aa2bc11a5756da029137f8685ac16333975 +Subproject commit 6784f0a795b318b75bf8f816900ee2b927f4df83 diff --git a/system/sops.nix b/system/sops.nix index b47ef53..3002308 100755 --- a/system/sops.nix +++ b/system/sops.nix @@ -29,6 +29,8 @@ in mcaptcha_mcaptcha_docker_env = {}; passbolt_db_docker_env = {}; passbolt_passbolt_docker_env = {}; + pterodactyl_db_docker_env = {}; + pterodactyl_pterodactyl_docker_env = {}; }; }; }