prepare nginx migration

This commit is contained in:
Tigor Hutasuhut 2024-11-24 20:16:30 +07:00
parent e174dae818
commit da4896341c
24 changed files with 331 additions and 19 deletions

View file

@ -137,11 +137,17 @@
];
};
services.caddy.virtualHosts."public.tigor.web.id".extraConfig = # caddy
''
file_server browse
root * /nas/public
'';
services.nginx.virtualHosts."public.tigor.web.id" = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = "/nas/public";
tryFiles = "$uri $uri/ $uri.html =404";
extraConfig = ''
autoindex on;
'';
};
};
systemd.tmpfiles.settings = {
"100-nas-public-dir" = {

View file

@ -10,6 +10,7 @@ in
{
options.profile.services = {
caddy.enable = mkEnableOption "caddy";
nginx.enable = mkEnableOption "nginx";
cockpit.enable = mkEnableOption "cockpit";
forgejo.enable = mkEnableOption "forgejo";
kavita.enable = mkEnableOption "kavita";

View file

@ -37,12 +37,12 @@
servarr.recyclarr.enable = true;
servarr.real-debrid-manager.enable = false;
servarr.rdtclient.enable = true;
openobserve.enable = true;
openobserve.enable = false;
minecraft.enable = false;
memos.enable = true;
morphos.enable = true;
soulseek.enable = true;
valheim.enable = true;
valheim.enable = false;
};
home.programs.zellij = {
@ -53,7 +53,8 @@
};
services = {
caddy.enable = true;
caddy.enable = false;
nginx.enable = true;
cockpit.enable = true;
forgejo.enable = true;
kavita.enable = true;
@ -65,12 +66,12 @@
jellyfin.enable = true;
rust-motd.enable = true;
wireguard.enable = true;
photoprism.enable = true;
photoprism.enable = false;
navidrome.enable = true;
telemetry.enable = true;
ntfy-sh.enable = true;
ntfy-sh.client.enable = false;
couchdb.enable = true;
couchdb.enable = false;
technitium.enable = false;
};
};

View file

@ -17,6 +17,12 @@ in
reverse_proxy ${ip}:5230
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://${ip}:5230";
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${rootVolume}
chown ${uid}:${gid} ${rootVolume}

View file

@ -16,6 +16,12 @@ in
reverse_proxy ${ip}:8080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/".proxyPass = "http://${ip}:8080";
};
virtualisation.oci-containers.containers.${name} = {
inherit image;
hostname = name;

View file

@ -16,6 +16,19 @@ in
reverse_proxy ${ip}:80
'';
services.nginx.virtualHosts."pihole.tigor.web.id" = {
enableACME = true;
forceSSL = true;
locations = {
"= /" = {
return = "301 /admin";
};
"/" = {
proxyPass = "http://${ip}:80";
};
};
};
sops.secrets."pihole/env" = {
sopsFile = ../../secrets/pihole.yaml;
};
@ -50,7 +63,7 @@ in
${strings.concatStringsSep "\n" (
attrsets.mapAttrsToList (
name: _: "192.168.100.5 ${strings.removePrefix "https://" name}"
) config.services.caddy.virtualHosts
) config.services.nginx.virtualHosts
)}
'';
};

View file

@ -24,6 +24,14 @@ lib.mkMerge [
reverse_proxy ${ip}:8080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8080";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${volume}/{config,downloads,progress,watch}
chown ${uid}:${gid} ${volume} ${volume}/{config,downloads,progress,watch}

View file

@ -17,6 +17,14 @@ in
reverse_proxy ${ip}:8080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8080";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${rootVolume}/db
mkdir -p ${rootVolume}/images

View file

@ -24,6 +24,14 @@ in
reverse_proxy ${ip}:8080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8080";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${rootVolume}/db
mkdir -p ${rootVolume}/images

View file

@ -20,6 +20,14 @@ in
reverse_proxy ${ip}:6767
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:6767";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume}
chown ${uid}:${gid} ${mediaVolume} ${configVolume}

View file

@ -22,6 +22,14 @@ in
reverse_proxy ${ip}:9696
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:9696";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume}
chown ${uid}:${gid} ${configVolume}

View file

@ -20,6 +20,15 @@ in
reverse_proxy ${ip}:8080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8080";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume} ${mediaVolume}
chown ${uid}:${gid} ${mediaVolume} ${configVolume}

View file

@ -20,6 +20,15 @@ in
reverse_proxy ${ip}:7878
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:7878";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume} ${mediaVolume}
chown ${uid}:${gid} ${mediaVolume} ${configVolume}

View file

@ -20,6 +20,15 @@ in
reverse_proxy ${ip}:6500
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:6500";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${volumeConfig} ${mediaVolume}
chown ${uid}:${gid} ${volumeConfig} ${mediaVolume}

View file

@ -21,6 +21,15 @@ in
reverse_proxy ${ip}:5000
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:5000";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume} ${mediaVolume} ${watchVolume}
chown ${uid}:${gid} ${configVolume} ${mediaVolume} ${watchVolume}

View file

@ -24,10 +24,28 @@ in
reverse_proxy ${ip}:8989
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8989";
proxyWebsockets = true;
};
};
services.caddy.virtualHosts.${domain-anime}.extraConfig = ''
reverse_proxy ${ip-anime}:8989
'';
services.nginx.virtualHosts.${domain-anime} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8989";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${configVolume} ${mediaVolume} ${configVolumeAnime}
chown ${uid}:${gid} ${mediaVolume} ${configVolume} ${configVolumeAnime}

View file

@ -29,6 +29,15 @@ in
reverse_proxy ${ip}:6080
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:6080";
proxyWebsockets = true;
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${rootVolume}/{config,downloads,incomplete}
chown ${uid}:${gid} ${rootVolume} ${rootVolume}/{config,downloads,incomplete}

View file

@ -21,6 +21,14 @@ in
reverse_proxy ${ip}:4567
'';
services.nginx.virtualHosts.${domain} = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:4567";
};
};
system.activationScripts."podman-${name}" = ''
mkdir -p ${volume}
chown ${uid}:${gid} ${volume}

View file

@ -15,11 +15,6 @@ let
user = config.profile.user;
uid = toString user.uid;
gid = toString user.gid;
basic_auth = {
username = "caddy/basic_auth/username";
password = "caddy/basic_auth/password";
template = "caddy/basic_auth";
};
webhook = builtins.readFile (
(pkgs.formats.json { }).generate "webhooks.json" [
{
@ -68,6 +63,16 @@ let
in
lib.mkMerge [
(mkIf podman.${name}.enable {
services.nginx.virtualHosts.${domain} = {
enableACME = true;
# useACMEHost = "ytptube.tigor.web.id";
forceSSL = true;
locations."/" = {
proxyPass = "http://${ip}:8081";
proxyWebsockets = true;
};
};
services.caddy.virtualHosts.${domain}.extraConfig = ''
@require_auth not remote_ip private_ranges

View file

@ -13,6 +13,16 @@ in
environment.systemPackages = mkIf config.profile.podman.enable [
(pkgs.callPackage ../packages/cockpit-podman.nix { })
];
services.nginx.virtualHosts."cockpit.tigor.web.id" = {
enableACME = true;
forceSSL = true;
locations."/" = {
proxyPass = "http://0.0.0.0:9090";
proxyWebsockets = true;
};
};
services.caddy.virtualHosts."cockpit.tigor.web.id".extraConfig = # caddyfile
''
@denied not remote_ip private_ranges

View file

@ -11,14 +11,15 @@
./kavita.nix
./navidrome.nix
./nextcloud.nix
./nginx.nix
./ntfy-sh.nix
./openvpn.nix
./photoprism.nix
./rust-motd.nix
./samba.nix
./stubby.nix
./syncthing.nix
./wireguard.nix
./photoprism.nix
./ntfy-sh.nix
./technitium.nix
./wireguard.nix
];
}

View file

@ -10,6 +10,26 @@ let
in
{
config = mkIf cfg.enable {
services.nginx.virtualHosts."git.tigor.web.id" = {
enableACME = true;
forceSSL = true;
locations = {
"= /" = {
extraConfig =
#nginx
''
if ($http_cookie !~ "gitea_incredible") {
rewrite ^(.*)$ /Tigor redirect;
}
'';
proxyPass = "http://unix:/run/forgejo/forgejo.sock";
};
"/" = {
proxyPass = "http://unix:/run/forgejo/forgejo.sock";
};
};
};
services.caddy.virtualHosts."git.tigor.web.id".extraConfig = ''
@home_not_login {
not header_regexp Cookie gitea_incredible

View file

@ -15,6 +15,7 @@ in
mkdir -p ${dataDir}
chmod -R 0777 /nas/mediaserver
'';
services.caddy.virtualHosts.${domain}.extraConfig = ''
@public not remote_ip private_ranges

131
system/services/nginx.nix Normal file
View file

@ -0,0 +1,131 @@
{
config,
lib,
pkgs,
...
}:
let
cfg = config.profile.services.nginx;
inherit (lib)
mkIf
attrsets
strings
lists
;
in
{
config = mkIf cfg.enable {
services.nginx = {
enable = true;
additionalModules = [
pkgs.nginxModules.pam
];
recommendedTlsSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedZstdSettings = true;
recommendedBrotliSettings = true;
};
users.users.nginx.extraGroups = [ "acme" ];
security.acme = {
acceptTerms = true;
defaults.email = "tigor.hutasuhut@gmail.com";
};
# Enable Basic Authentication via PAM
security.pam.services.nginx.setEnvironment = false;
systemd.services.nginx.serviceConfig = {
SupplementaryGroups = [ "shadow" ];
};
environment.etc."nginx/static/tigor.web.id/index.html" = {
text =
let
domains = attrsets.mapAttrsToList (
name: _: strings.removePrefix "https://" name
) config.services.nginx.virtualHosts;
sortedDomains = lists.sort (a: b: a < b) domains;
list = map (
domain: # html
''
<div class="col-12 col-sm-6 col-md-4 col-lg-3 text-center align-middle">
<a href="https://${domain}">${domain}</a>
</div>
'') sortedDomains;
items = strings.concatStringsSep "\n" list;
in
# html
''
<!DOCTYPE html>
<html>
<head>
<title>Hosted Sites</title>
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css"
integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH"
crossorigin="anonymous">
</head>
<body class="container">
<h1 class="text-center">Hosted Sites</h1>
<div class="row g-4">
${items}
</div>
</body>
</html>
'';
user = "nginx";
group = "nginx";
};
services.nginx.virtualHosts."tigor.web.id" = {
enableACME = true;
forceSSL = true;
locations."/" = {
root = "/etc/nginx/static/tigor.web.id";
tryFiles = "$uri $uri/ $uri.html =404";
};
};
# Enable Real IP from Cloudflare
services.nginx.commonHttpConfig =
let
realIpsFromList = lib.strings.concatMapStringsSep "\n" (x: "set_real_ip_from ${x};");
fileToList = x: lib.strings.splitString "\n" (builtins.readFile x);
cfipv4 = fileToList (
pkgs.fetchurl {
url = "https://www.cloudflare.com/ips-v4";
sha256 = "0ywy9sg7spafi3gm9q5wb59lbiq0swvf0q3iazl0maq1pj1nsb7h";
}
);
cfipv6 = fileToList (
pkgs.fetchurl {
url = "https://www.cloudflare.com/ips-v6";
sha256 = "1ad09hijignj6zlqvdjxv7rjj8567z357zfavv201b9vx3ikk7cy";
}
);
in
#nginx
''
geo $auth_ip {
default "Password required";
10.0.0.0/8 "off";
172.16.0.0/12 "off";
192.168.0.0/16 "off";
}
auth_pam_service_name "nginx";
${realIpsFromList cfipv4}
${realIpsFromList cfipv6}
real_ip_header CF-Connecting-IP;
'';
# This is needed for nginx to be able to read other processes
# directories in `/run`. Else it will fail with (13: Permission denied)
systemd.services.nginx.serviceConfig.ProtectHome = false;
};
}