diff --git a/modules/containers/remnawave-examples/docker-compose-local.nix b/modules/containers/remnawave-examples/docker-compose-local.nix new file mode 100644 index 0000000..caf26b3 --- /dev/null +++ b/modules/containers/remnawave-examples/docker-compose-local.nix @@ -0,0 +1,103 @@ +# Auto-generated by compose2nix. + +{ pkgs, lib, config, ... }: + +{ + # Runtime + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + }; + + # Enable container name DNS for all Podman networks. + networking.firewall.interfaces = let + matchAll = if !config.networking.nftables.enable then "podman+" else "podman*"; + in { + "${matchAll}".allowedUDPPorts = [ 53 ]; + }; + + virtualisation.oci-containers.backend = "podman"; + + # Containers + virtualisation.oci-containers.containers."remnawave-panel-1" = { + image = "localhost/compose2nix/remnawave-panel-1"; + environment = { + "API_INSTANCES" = "1"; + "APP_PORT" = "3000"; + "BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false"; + "BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]"; + "CLOUDFLARE_TOKEN" = "ey..."; + "DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres"; + "FRONT_END_DOMAIN" = "*"; + "IS_DOCS_ENABLED" = "false"; + "IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false"; + "JWT_API_TOKENS_SECRET" = "787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da"; + "JWT_AUTH_SECRET" = "2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a"; + "METRICS_PASS" = "admin"; + "METRICS_PORT" = "3001"; + "METRICS_USER" = "admin"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false"; + "PANEL_DOMAIN" = "rw.zeroq.ru"; + "POSTGRES_DB" = "remnawave"; + "POSTGRES_PASSWORD" = "gQLqOm2jK/Z1oBXCD18XSgr76M8ZqkVhHZbNKvZQXnY="; + "POSTGRES_USER" = "remnawave"; + "REDIS_SOCKET" = "/var/run/valkey/valkey.sock"; + "SCALAR_PATH" = "/scalar"; + "SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub"; + "SWAGGER_PATH" = "/docs"; + # "TELEGRAM_BOT_TOKEN" = "change_me"; + # "TELEGRAM_NOTIFY_CRM" = "change_me"; + # "TELEGRAM_NOTIFY_NODES" = "change_me"; + # "TELEGRAM_NOTIFY_SERVICE" = "change_me"; + # "TELEGRAM_NOTIFY_TBLOCKER" = "change_me"; + # "TELEGRAM_NOTIFY_USERS" = "change_me"; + "WEBHOOK_ENABLED" = "false"; + "WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ"; + "WEBHOOK_URL" = "https://your-webhook-url.com/endpoint"; + }; + ports = [ + "3003:3003/tcp" + ]; + log-driver = "journald"; + extraOptions = [ + "--network-alias=remnawave-panel-1" + "--network=remnawavebackend_default" + ]; + }; + systemd.services."podman-remnawave-panel-1" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + partOf = [ + "podman-compose-remnawave-root.target" + ]; + wantedBy = [ + "podman-compose-remnawave-root.target" + ]; + }; + + # Builds + systemd.services."podman-build-remnawave-panel-1" = { + path = [ pkgs.podman pkgs.git ]; + serviceConfig = { + Type = "oneshot"; + TimeoutSec = 300; + }; + script = '' + cd /mnt/s/Deploy/remnawave-backend + podman build -t compose2nix/remnawave-panel-1 . + ''; + }; + + # Root service + # When started, this will automatically create all resources and start + # the containers. When stopped, this will teardown all resources. + systemd.targets."podman-compose-remnawave-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/modules/containers/remnawave-examples/docker-compose-prod.nix b/modules/containers/remnawave-examples/docker-compose-prod.nix new file mode 100644 index 0000000..58d94fd --- /dev/null +++ b/modules/containers/remnawave-examples/docker-compose-prod.nix @@ -0,0 +1,263 @@ +# Auto-generated by compose2nix. + +{ pkgs, lib, config, ... }: + +{ + # Runtime + virtualisation.podman = { + enable = true; + autoPrune.enable = true; + dockerCompat = true; + }; + + # Enable container name DNS for all Podman networks. + networking.firewall.interfaces = let + matchAll = if !config.networking.nftables.enable then "podman+" else "podman*"; + in { + "${matchAll}".allowedUDPPorts = [ 53 ]; + }; + + virtualisation.oci-containers.backend = "podman"; + + # Containers + virtualisation.oci-containers.containers."remnawave" = { + image = "remnawave/backend:2"; + environment = { + "API_INSTANCES" = "1"; + "APP_PORT" = "3000"; + "BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false"; + "BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]"; + "CLOUDFLARE_TOKEN" = "ey..."; + "DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres"; + "FRONT_END_DOMAIN" = "*"; + "IS_DOCS_ENABLED" = "false"; + "IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false"; + "JWT_API_TOKENS_SECRET" = "787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da"; + "JWT_AUTH_SECRET" = "2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a"; + "METRICS_PASS" = "admin"; + "METRICS_PORT" = "3001"; + "METRICS_USER" = "admin"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false"; + "PANEL_DOMAIN" = "rw.zeroq.ru"; + "POSTGRES_DB" = "remnawave"; + "POSTGRES_PASSWORD" = "gQLqOm2jK/Z1oBXCD18XSgr76M8ZqkVhHZbNKvZQXnY="; + "POSTGRES_USER" = "remnawave"; + "REDIS_SOCKET" = "/var/run/valkey/valkey.sock"; + "SCALAR_PATH" = "/scalar"; + "SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub"; + "SWAGGER_PATH" = "/docs"; + "TELEGRAM_BOT_TOKEN" = "change_me"; + "TELEGRAM_NOTIFY_CRM" = "change_me"; + "TELEGRAM_NOTIFY_NODES" = "change_me"; + "TELEGRAM_NOTIFY_SERVICE" = "change_me"; + "TELEGRAM_NOTIFY_TBLOCKER" = "change_me"; + "TELEGRAM_NOTIFY_USERS" = "change_me"; + "WEBHOOK_ENABLED" = "false"; + "WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ"; + "WEBHOOK_URL" = "https://your-webhook-url.com/endpoint"; + }; + volumes = [ + "valkey-socket:/var/run/valkey:rw" + ]; + ports = [ + "127.0.0.1:3000:3000/tcp" + "127.0.0.1:3001:3001/tcp" + ]; + dependsOn = [ + "remnawave-db" + "remnawave-redis" + ]; + log-driver = "journald"; + extraOptions = [ + "--health-cmd=curl -f http://localhost:3001/health" + "--health-interval=30s" + "--health-retries=3" + "--health-start-period=30s" + "--health-timeout=5s" + "--hostname=remnawave" + "--network-alias=remnawave" + "--network=remnawave-network" + ]; + }; + systemd.services."podman-remnawave" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-remnawave-network.service" + "podman-volume-valkey-socket.service" + ]; + requires = [ + "podman-network-remnawave-network.service" + "podman-volume-valkey-socket.service" + ]; + partOf = [ + "podman-compose-remnawave-root.target" + ]; + wantedBy = [ + "podman-compose-remnawave-root.target" + ]; + }; + virtualisation.oci-containers.containers."remnawave-db" = { + image = "postgres:17.6"; + environment = { + "API_INSTANCES" = "1"; + "APP_PORT" = "3000"; + "BANDWIDTH_USAGE_NOTIFICATIONS_ENABLED" = "false"; + "BANDWIDTH_USAGE_NOTIFICATIONS_THRESHOLD" = "[60, 80]"; + "CLOUDFLARE_TOKEN" = "ey..."; + "DATABASE_URL" = "postgresql://remnawave:remnawave@remnawave-db:5432/postgres"; + "FRONT_END_DOMAIN" = "*"; + "IS_DOCS_ENABLED" = "false"; + "IS_TELEGRAM_NOTIFICATIONS_ENABLED" = "false"; + "JWT_API_TOKENS_SECRET" = "787aa44c10130a9fa17ea3ea50c1248dd3e868f74941b96c09d608051399f88b95b67cd68d045aa39658b4b3fe933bf2b2c1437522498976f39f85ae1eab40da"; + "JWT_AUTH_SECRET" = "2bc14bacb6b82ce9e3ef69f8dd7bfb6b8a531f4f516902735d1d8f1bac8ff9b5077398f95b942b1adafc0ca1da4cdfd24a18539fa6eb26bee3f597a45deac94a"; + "METRICS_PASS" = "admin"; + "METRICS_PORT" = "3001"; + "METRICS_USER" = "admin"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_AFTER_HOURS" = "[6, 24, 48]"; + "NOT_CONNECTED_USERS_NOTIFICATIONS_ENABLED" = "false"; + "PANEL_DOMAIN" = "rw.zeroq.ru"; + "POSTGRES_DB" = ""; + "POSTGRES_PASSWORD" = ""; + "POSTGRES_USER" = ""; + "REDIS_SOCKET" = "/var/run/valkey/valkey.sock"; + "SCALAR_PATH" = "/scalar"; + "SUB_PUBLIC_DOMAIN" = "rw.zeroq.ru/api/sub"; + "SWAGGER_PATH" = "/docs"; + "TELEGRAM_BOT_TOKEN" = "change_me"; + "TELEGRAM_NOTIFY_CRM" = "change_me"; + "TELEGRAM_NOTIFY_NODES" = "change_me"; + "TELEGRAM_NOTIFY_SERVICE" = "change_me"; + "TELEGRAM_NOTIFY_TBLOCKER" = "change_me"; + "TELEGRAM_NOTIFY_USERS" = "change_me"; + "TZ" = "UTC"; + "WEBHOOK_ENABLED" = "false"; + "WEBHOOK_SECRET_HEADER" = "vsmu67Kmg6R8FjIOF1WUY8LWBHie4scdEqrfsKmyf4IAf8dY3nFS0wwYHkhh6ZvQ"; + "WEBHOOK_URL" = "https://your-webhook-url.com/endpoint"; + }; + volumes = [ + "remnawave-db-data:/var/lib/postgresql/data:rw" + ]; + ports = [ + "127.0.0.1:6767:5432/tcp" + ]; + log-driver = "journald"; + extraOptions = [ + "--health-cmd=pg_isready -U \${POSTGRES_USER} -d \${POSTGRES_DB}" + "--health-interval=3s" + "--health-retries=3" + "--health-timeout=10s" + "--hostname=remnawave-db" + "--network-alias=remnawave-db" + "--network=remnawave-network" + ]; + }; + systemd.services."podman-remnawave-db" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-remnawave-network.service" + "podman-volume-remnawave-db-data.service" + ]; + requires = [ + "podman-network-remnawave-network.service" + "podman-volume-remnawave-db-data.service" + ]; + partOf = [ + "podman-compose-remnawave-root.target" + ]; + wantedBy = [ + "podman-compose-remnawave-root.target" + ]; + }; + virtualisation.oci-containers.containers."remnawave-redis" = { + image = "valkey/valkey:9-alpine"; + volumes = [ + "valkey-socket:/var/run/valkey:rw" + ]; + cmd = [ "valkey-server" "--save" "" "--appendonly" "no" "--maxmemory-policy" "noeviction" "--loglevel" "warning" "--unixsocket" "/var/run/valkey/valkey.sock" "--unixsocketperm" "777" "--port" "0" ]; + log-driver = "journald"; + extraOptions = [ + "--health-cmd=[\"valkey-cli\", \"-s\", \"/var/run/valkey/valkey.sock\", \"ping\"]" + "--health-interval=3s" + "--health-retries=3" + "--health-timeout=3s" + "--hostname=remnawave-redis" + "--network-alias=remnawave-redis" + "--network=remnawave-network" + ]; + }; + systemd.services."podman-remnawave-redis" = { + serviceConfig = { + Restart = lib.mkOverride 90 "always"; + }; + after = [ + "podman-network-remnawave-network.service" + "podman-volume-valkey-socket.service" + ]; + requires = [ + "podman-network-remnawave-network.service" + "podman-volume-valkey-socket.service" + ]; + partOf = [ + "podman-compose-remnawave-root.target" + ]; + wantedBy = [ + "podman-compose-remnawave-root.target" + ]; + }; + + # Networks + systemd.services."podman-network-remnawave-network" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + ExecStop = "podman network rm -f remnawave-network"; + }; + script = '' + podman network inspect remnawave-network || podman network create remnawave-network --driver=bridge + ''; + partOf = [ "podman-compose-remnawave-root.target" ]; + wantedBy = [ "podman-compose-remnawave-root.target" ]; + }; + + # Volumes + systemd.services."podman-volume-remnawave-db-data" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + podman volume inspect remnawave-db-data || podman volume create remnawave-db-data --driver=local + ''; + partOf = [ "podman-compose-remnawave-root.target" ]; + wantedBy = [ "podman-compose-remnawave-root.target" ]; + }; + systemd.services."podman-volume-valkey-socket" = { + path = [ pkgs.podman ]; + serviceConfig = { + Type = "oneshot"; + RemainAfterExit = true; + }; + script = '' + podman volume inspect valkey-socket || podman volume create valkey-socket --driver=local + ''; + partOf = [ "podman-compose-remnawave-root.target" ]; + wantedBy = [ "podman-compose-remnawave-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."podman-compose-remnawave-root" = { + unitConfig = { + Description = "Root target generated by compose2nix."; + }; + wantedBy = [ "multi-user.target" ]; + }; +} diff --git a/modules/essentials/systemd-routines.nix b/modules/essentials/systemd-routines.nix index c3a8603..ad29bf2 100644 --- a/modules/essentials/systemd-routines.nix +++ b/modules/essentials/systemd-routines.nix @@ -15,7 +15,7 @@ Group = "users"; Nice = 10; Type = "oneshot"; - WorkingDirectory = "/tmp"; + WorkingDirectory = "/tmp"; Environment = [ "HOME=/home/oqyude" ]; @@ -36,4 +36,4 @@ }; }; }; -} \ No newline at end of file +} diff --git a/modules/server/bentopdf.nix b/modules/server/bentopdf.nix new file mode 100644 index 0000000..3b21a50 --- /dev/null +++ b/modules/server/bentopdf.nix @@ -0,0 +1,16 @@ +{ + config, + inputs, + ... +}: +# let +# pkgs-stable = import inputs.nixpkgs-stable { system = "x86_64-linux"; }; +# in +{ + services.bentopdf = { + enable = true; + domain = "bentopdf.local"; + nginx.enable = true; + # package = pkgs-stable.bentopdf; + }; +} diff --git a/modules/server/default.nix b/modules/server/default.nix index 4d7af11..0633cb7 100644 --- a/modules/server/default.nix +++ b/modules/server/default.nix @@ -5,6 +5,7 @@ { imports = [ ../software/beets + ./bentopdf.nix ./calibre-web.nix ./glances.nix ./immich.nix diff --git a/modules/server/nginx.nix b/modules/server/nginx.nix index 15c3971..8d8319c 100644 --- a/modules/server/nginx.nix +++ b/modules/server/nginx.nix @@ -31,6 +31,27 @@ in } ]; }; + "bentopdf.local" = { + forceSSL = false; + enableACME = false; + listen = [ + { + addr = "0.0.0.0"; + port = 80; + } + { + addr = "100.64.0.0"; + port = 8446; + } + { + addr = "192.168.1.20"; + port = 8446; + } + ]; + extraConfig = '' + client_max_body_size 5G; + ''; + }; "nextcloud.local" = { forceSSL = false; enableACME = false; diff --git a/modules/vds/nginx.nix b/modules/vds/nginx.nix index 9a5d924..4ca0cd4 100644 --- a/modules/vds/nginx.nix +++ b/modules/vds/nginx.nix @@ -193,17 +193,17 @@ in client_max_body_size 5G; ''; }; - # "pdf.zeroq.su" = { - # forceSSL = true; - # enableACME = true; - # locations."/" = { - # proxyPass = "http://${server}:6060"; - # proxyWebsockets = true; - # }; - # extraConfig = '' - # client_max_body_size 5G; - # ''; - # }; + "pdf.zeroq.su" = { + forceSSL = true; + enableACME = true; + locations."/" = { + proxyPass = "http://${server}:8446"; + proxyWebsockets = true; + }; + extraConfig = '' + client_max_body_size 5G; + ''; + }; # "ai.zeroq.su" = { # forceSSL = true; # enableACME = true; diff --git a/pkgs/pcbu-desktop/default.nix b/pkgs/pcbu-desktop/default.nix index 46816df..361eb28 100644 --- a/pkgs/pcbu-desktop/default.nix +++ b/pkgs/pcbu-desktop/default.nix @@ -9,35 +9,37 @@ let sha256 = "sha256-+NxAm6vhMH51z6BscuFvaMidHN/3tNBR1g+i0q9hjWE="; }; -in pkgs.appimageTools.wrapType2 { +in +pkgs.appimageTools.wrapType2 { inherit pname version src; - extraPkgs = pkgs: with pkgs; [ - glib - nss - nspr - libdrm - libGL - libxkbcommon - libX11 - libXcursor - libXrandr - libXi - libXext - libXfixes - libXrender - libXtst - libxcrypt-legacy - gtk3 - alsa-lib - at-spi2-atk - at-spi2-core - cups - dbus - expat - pango - cairo - ]; + extraPkgs = + pkgs: with pkgs; [ + glib + nss + nspr + libdrm + libGL + libxkbcommon + libX11 + libXcursor + libXrandr + libXi + libXext + libXfixes + libXrender + libXtst + libxcrypt-legacy + gtk3 + alsa-lib + at-spi2-atk + at-spi2-core + cups + dbus + expat + pango + cairo + ]; extraInstallCommands = '' mkdir -p $out/share/applications @@ -49,4 +51,4 @@ in pkgs.appimageTools.wrapType2 { Categories=Utility; EOF ''; -} \ No newline at end of file +}