Update nginx

This commit is contained in:
muon 2026-01-02 21:28:26 +00:00
parent b8961e7263
commit c54a2dd183
3 changed files with 237 additions and 171 deletions

View file

@ -1,15 +1,20 @@
{ config, lib, pkgs, inputs, system, ... }: {
let config,
lib,
pkgs,
inputs,
system,
...
}: let
cfg = config.mods; cfg = config.mods;
keys = [ keys = [
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKEio+Y5wBVD1wILaH2R3wV10FvVjiqy/4gGBWHOITTB muon@muon" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKEio+Y5wBVD1wILaH2R3wV10FvVjiqy/4gGBWHOITTB muon@muon"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKevYmkH7xvYoquBjnYZ7PJiVqf+GOh9fxAJBN6wZGBB gin4@hi.is" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKevYmkH7xvYoquBjnYZ7PJiVqf+GOh9fxAJBN6wZGBB gin4@hi.is"
"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILmAOd9VbhyJeibt6Vrb101MNTk5W8+rh94Djv/C+pyu muon@muho" "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILmAOd9VbhyJeibt6Vrb101MNTk5W8+rh94Djv/C+pyu muon@muho"
]; ];
in { in {
# Hardware # Hardware
imports = [ ./hardware-configuration.nix ../ports.nix ]; imports = [./hardware-configuration.nix ../ports.nix];
# System # System
mods.user.name = "muon"; mods.user.name = "muon";
@ -46,29 +51,82 @@ in {
enable = true; enable = true;
listen = "[::]:8008"; listen = "[::]:8008";
root = "/var/www"; root = "/var/www";
configuration = { general = { directory-listing = true; }; }; configuration = {general = {directory-listing = true;};};
}; };
services.nginx.virtualHosts = { services.nginx.virtualHosts = {
"muon.host" = { "muon.host" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
default = true; default = true;
locations."/" = { proxyPass = "http://localhost:8008"; }; locations."/" = {proxyPass = "http://localhost:8008";};
}; };
"nvr.muon.host" = { "nvr.muon.host" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { proxyPass = "http://10.0.0.2:8095"; }; locations."/" = {proxyPass = "http://10.0.0.2:8095";};
}; };
"tetterodesportcomplex.nl" = { "tetterodesportcomplex.nl" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { proxyPass = "http://10.0.0.3:5001"; }; locations."/" = {proxyPass = "http://10.0.0.3:5001";};
}; };
"www.tetterodesportcomplex.nl" = { "www.tetterodesportcomplex.nl" = {
enableACME = true; enableACME = true;
forceSSL = true; forceSSL = true;
locations."/" = { proxyPass = "http://10.0.0.3:5001"; }; locations."/" = {proxyPass = "http://10.0.0.3:5001";};
};
"seedbox.muon.host" = {
forceSSL = true;
enableACME = true;
locations = {
"/" = {
proxyPass = "http://10.0.0.3:3013";
};
"/api" = {
proxyPass = "http://10.0.0.3:3014";
extraConfig =
#sh
''
limit_req zone=api burst=20 nodelay;
# CORS headers
add_header Access-Control-Allow-Origin "*" always;
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization" always;
add_header Access-Control-Expose-Headers "Content-Length,Content-Range" always;
# Handle preflight requests
if ($request_method = 'OPTIONS') {
add_header Access-Control-Allow-Origin "*";
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
add_header Access-Control-Allow-Headers "DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization";
add_header Content-Type text/plain;
add_header Content-Length 0;
return 204;
}
'';
};
"/api/stream" = {
proxyPass = "http://10.0.0.3:3014";
extraConfig =
#sh
''
limit_req zone=download burst=10 nodelay;
proxy_set_header Range $http_range;
# Streaming optimizations
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
proxy_connect_timeout 30s;
proxy_send_timeout 300s;
# Allow large file streaming
client_max_body_size 0;
proxy_max_temp_file_size 0;
'';
};
};
}; };
}; };
@ -79,9 +137,8 @@ in {
networking.firewall = { networking.firewall = {
enable = true; enable = true;
allowedTCPPorts = [ 80 8080 ]; allowedTCPPorts = [80 8080];
}; };
system.stateVersion = "24.05"; # Did you read the comment? system.stateVersion = "24.05"; # Did you read the comment?
} }

View file

@ -24,8 +24,8 @@
ntfy = 3010; ntfy = 3010;
audio = 3011; audio = 3011;
atuin = 3012; atuin = 3012;
stream = 3013; # seedbox-frontend # stream = 3013; # seedbox-frontend
seedbox = 3014; # seedbox-backend # seedbox = 3014; # seedbox-backend
search = 8081; search = 8081;
videos = 8082; videos = 8082;

View file

@ -6,8 +6,8 @@
... ...
}: let }: let
cfg = config.mods.server.seedbox; cfg = config.mods.server.seedbox;
port = config.mods.server.nginx.ports.stream; port = 3013;
backend-port = config.mods.server.nginx.ports.seedbox; bport = 3014;
in in
with lib; { with lib; {
options.mods.server.seedbox = { options.mods.server.seedbox = {
@ -17,172 +17,181 @@ in
}; };
}; };
config = mkIf cfg.enable { config =
# Runtime mkIf config.mods.server.nginx.enable {
virtualisation.docker = { }
enable = true; // mkIf cfg.enable {
autoPrune.enable = true; networking.firewall = {
}; allowedTCPPorts = [port bport];
virtualisation.oci-containers.backend = "docker"; allowedUDPPorts = [port bport];
};
# Containers # Runtime
virtualisation.oci-containers.containers."seedbox-backend" = { virtualisation.docker = {
image = "compose2nix/seedbox-backend"; enable = true;
volumes = [ autoPrune.enable = true;
"seedbox-lite_seedbox_cache:/app/cache:rw"
"seedbox-lite_seedbox_data:/app/data:rw"
];
ports = [
"${toString backend-port}:3001/tcp"
];
log-driver = "journald";
extraOptions = [
"--network-alias=seedbox-backend"
"--network=seedbox-lite_seedbox-network"
];
environment = {
NODE_ENV = "production";
ACCESS_PASSWORD = "temp_pass";
}; };
}; virtualisation.oci-containers.backend = "docker";
systemd.services."docker-seedbox-backend" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
RestartMaxDelaySec = lib.mkOverride 90 "1m";
RestartSec = lib.mkOverride 90 "100ms";
RestartSteps = lib.mkOverride 90 9;
};
after = [
"docker-network-seedbox-lite_seedbox-network.service"
"docker-volume-seedbox-lite_seedbox_cache.service"
"docker-volume-seedbox-lite_seedbox_data.service"
];
requires = [
"docker-network-seedbox-lite_seedbox-network.service"
"docker-volume-seedbox-lite_seedbox_cache.service"
"docker-volume-seedbox-lite_seedbox_data.service"
];
partOf = [
"docker-compose-seedbox-lite-root.target"
];
wantedBy = [
"docker-compose-seedbox-lite-root.target"
];
};
virtualisation.oci-containers.containers."seedbox-frontend" = {
image = "compose2nix/seedbox-frontend";
ports = [
"${toString port}:8080/tcp"
];
dependsOn = [
"seedbox-backend"
];
log-driver = "journald";
extraOptions = [
"--network-alias=seedbox-frontend"
"--network=seedbox-lite_seedbox-network"
];
environment = {
NODE_ENV = "production";
ACCESS_PASSWORD = "temp_pass";
};
};
systemd.services."docker-seedbox-frontend" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
RestartMaxDelaySec = lib.mkOverride 90 "1m";
RestartSec = lib.mkOverride 90 "100ms";
RestartSteps = lib.mkOverride 90 9;
};
after = [
"docker-network-seedbox-lite_seedbox-network.service"
];
requires = [
"docker-network-seedbox-lite_seedbox-network.service"
];
partOf = [
"docker-compose-seedbox-lite-root.target"
];
wantedBy = [
"docker-compose-seedbox-lite-root.target"
];
};
# Networks # Containers
systemd.services."docker-network-seedbox-lite_seedbox-network" = { virtualisation.oci-containers.containers."seedbox-backend" = {
path = [pkgs.docker]; image = "compose2nix/seedbox-backend";
serviceConfig = { volumes = [
Type = "oneshot"; "seedbox-lite_seedbox_cache:/app/cache:rw"
RemainAfterExit = true; "seedbox-lite_seedbox_data:/app/data:rw"
ExecStop = "docker network rm -f seedbox-lite_seedbox-network"; ];
ports = [
"${toString bport}:3001/tcp"
];
log-driver = "journald";
extraOptions = [
"--network-alias=seedbox-backend"
"--network=seedbox-lite_seedbox-network"
];
environment = {
NODE_ENV = "production";
ACCESS_PASSWORD = "temp_pass";
FRONTEND_URL = "http://localhost:${toString port}";
};
};
systemd.services."docker-seedbox-backend" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
RestartMaxDelaySec = lib.mkOverride 90 "1m";
RestartSec = lib.mkOverride 90 "100ms";
RestartSteps = lib.mkOverride 90 9;
};
after = [
"docker-network-seedbox-lite_seedbox-network.service"
"docker-volume-seedbox-lite_seedbox_cache.service"
"docker-volume-seedbox-lite_seedbox_data.service"
];
requires = [
"docker-network-seedbox-lite_seedbox-network.service"
"docker-volume-seedbox-lite_seedbox_cache.service"
"docker-volume-seedbox-lite_seedbox_data.service"
];
partOf = [
"docker-compose-seedbox-lite-root.target"
];
wantedBy = [
"docker-compose-seedbox-lite-root.target"
];
};
virtualisation.oci-containers.containers."seedbox-frontend" = {
image = "compose2nix/seedbox-frontend";
ports = [
"${toString port}:8080/tcp"
];
dependsOn = [
"seedbox-backend"
];
log-driver = "journald";
extraOptions = [
"--network-alias=seedbox-frontend"
"--network=seedbox-lite_seedbox-network"
];
environment = {
NODE_ENV = "production";
ACCESS_PASSWORD = "temp_pass";
};
};
systemd.services."docker-seedbox-frontend" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
RestartMaxDelaySec = lib.mkOverride 90 "1m";
RestartSec = lib.mkOverride 90 "100ms";
RestartSteps = lib.mkOverride 90 9;
};
after = [
"docker-network-seedbox-lite_seedbox-network.service"
];
requires = [
"docker-network-seedbox-lite_seedbox-network.service"
];
partOf = [
"docker-compose-seedbox-lite-root.target"
];
wantedBy = [
"docker-compose-seedbox-lite-root.target"
];
}; };
script = ''
docker network inspect seedbox-lite_seedbox-network || docker network create seedbox-lite_seedbox-network --driver=bridge
'';
partOf = ["docker-compose-seedbox-lite-root.target"];
wantedBy = ["docker-compose-seedbox-lite-root.target"];
};
# Volumes # Networks
systemd.services."docker-volume-seedbox-lite_seedbox_cache" = { systemd.services."docker-network-seedbox-lite_seedbox-network" = {
path = [pkgs.docker]; path = [pkgs.docker];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
RemainAfterExit = true; RemainAfterExit = true;
ExecStop = "docker network rm -f seedbox-lite_seedbox-network";
};
script = ''
docker network inspect seedbox-lite_seedbox-network || docker network create seedbox-lite_seedbox-network --driver=bridge
'';
partOf = ["docker-compose-seedbox-lite-root.target"];
wantedBy = ["docker-compose-seedbox-lite-root.target"];
}; };
script = ''
docker volume inspect seedbox-lite_seedbox_cache || docker volume create seedbox-lite_seedbox_cache --driver=local
'';
partOf = ["docker-compose-seedbox-lite-root.target"];
wantedBy = ["docker-compose-seedbox-lite-root.target"];
};
systemd.services."docker-volume-seedbox-lite_seedbox_data" = {
path = [pkgs.docker];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
docker volume inspect seedbox-lite_seedbox_data || docker volume create seedbox-lite_seedbox_data --driver=local
'';
partOf = ["docker-compose-seedbox-lite-root.target"];
wantedBy = ["docker-compose-seedbox-lite-root.target"];
};
# Builds # Volumes
systemd.services."docker-build-seedbox-backend" = { systemd.services."docker-volume-seedbox-lite_seedbox_cache" = {
path = [pkgs.docker pkgs.git]; path = [pkgs.docker];
serviceConfig = { serviceConfig = {
Type = "oneshot"; Type = "oneshot";
TimeoutSec = 300; RemainAfterExit = true;
};
script = ''
docker volume inspect seedbox-lite_seedbox_cache || docker volume create seedbox-lite_seedbox_cache --driver=local
'';
partOf = ["docker-compose-seedbox-lite-root.target"];
wantedBy = ["docker-compose-seedbox-lite-root.target"];
}; };
script = '' systemd.services."docker-volume-seedbox-lite_seedbox_data" = {
cd /tmp path = [pkgs.docker];
git clone https://github.com/hotheadhacker/seedbox-lite.git && cd seedbox-lite/server || cd seedbox-lite/server serviceConfig = {
podman build -t compose2nix/seedbox-backend . Type = "oneshot";
''; RemainAfterExit = true;
}; };
systemd.services."docker-build-seedbox-frontend" = { script = ''
path = [pkgs.docker pkgs.git]; docker volume inspect seedbox-lite_seedbox_data || docker volume create seedbox-lite_seedbox_data --driver=local
serviceConfig = { '';
Type = "oneshot"; partOf = ["docker-compose-seedbox-lite-root.target"];
TimeoutSec = 300; wantedBy = ["docker-compose-seedbox-lite-root.target"];
}; };
script = ''
cd /tmp
git clone https://github.com/hotheadhacker/seedbox-lite.git && cd seedbox-lite/client || cd seedbox-lite/client
podman build -t compose2nix/seedbox-frontend --build-arg VITE_API_BASE_URL=http://localhost:${toString backend-port} .
'';
};
# Root service # Builds
# When started, this will automatically create all resources and start systemd.services."docker-build-seedbox-backend" = {
# the containers. When stopped, this will teardown all resources. path = [pkgs.docker pkgs.git];
systemd.targets."docker-compose-seedbox-lite-root" = { serviceConfig = {
unitConfig = { Type = "oneshot";
Description = "Root target generated by compose2nix."; TimeoutSec = 300;
};
script = ''
cd /tmp
git clone https://github.com/hotheadhacker/seedbox-lite.git && cd seedbox-lite/server || cd seedbox-lite/server
podman build -t compose2nix/seedbox-backend .
'';
};
systemd.services."docker-build-seedbox-frontend" = {
path = [pkgs.docker pkgs.git];
serviceConfig = {
Type = "oneshot";
TimeoutSec = 300;
};
script = ''
cd /tmp
git clone https://github.com/hotheadhacker/seedbox-lite.git && cd seedbox-lite/client || cd seedbox-lite/client
podman build -t compose2nix/seedbox-frontend --build-arg VITE_API_BASE_URL=http://localhost:${toString bport} .
'';
};
# 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-seedbox-lite-root" = {
unitConfig = {
Description = "Root target generated by compose2nix.";
};
wantedBy = ["multi-user.target"];
}; };
wantedBy = ["multi-user.target"];
}; };
};
} }