Add nginx,traefik,caddy,docker,podman
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dov.reverse-proxy.caddy;
|
||||
caddyWithDuckDNS = pkgs.caddy.withPlugins {
|
||||
plugins = [
|
||||
"github.com/caddy-dns/duckdns@v0.5.0"
|
||||
];
|
||||
# Replace with the hash NixOS provides on the first build attempt.
|
||||
hash = "sha256-83ETc9K4T13Ws8gVOYwLarhuCA48Drs/i3rVLBMHyrc=";
|
||||
};
|
||||
email = "susano@local.com";
|
||||
in {
|
||||
options.dov.reverse-proxy.caddy = { enable = mkEnableOption "caddy config"; };
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
sops.secrets.duckdns-token = {
|
||||
owner = config.services.caddy.user;
|
||||
group = config.services.caddy.group;
|
||||
};
|
||||
|
||||
services.caddy = {
|
||||
enable = cfg.enable;
|
||||
package = caddyWithDuckDNS;
|
||||
|
||||
environmentFile = config.sops.secrets.duckdns-token.path;
|
||||
|
||||
# Add a global options block.
|
||||
# Let's Encrypt will use this email to send you important notices.
|
||||
globalConfig = ''
|
||||
email ${email}
|
||||
'';
|
||||
|
||||
virtualHosts."test.susano-lab.duckdns.org" = {
|
||||
extraConfig = ''
|
||||
# Reverse proxy to your Immich instance.
|
||||
reverse_proxy http://192.168.1.57:2283 {
|
||||
# Send correct headers to the backend service.
|
||||
header_up Host {host}
|
||||
header_up X-Real-IP {remote_ip}
|
||||
header_up X-Forwarded-For {remote_ip}
|
||||
header_up X-Forwarded-Proto {scheme}
|
||||
|
||||
# Recommended for large file uploads in Immich.
|
||||
transport http {
|
||||
read_buffer 1m
|
||||
}
|
||||
}
|
||||
|
||||
# Configure automatic HTTPS with the DuckDNS provider.
|
||||
tls {
|
||||
dns duckdns {env.DUCKDNS_TOKEN}
|
||||
|
||||
propagation_timeout -1
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./nginx
|
||||
./traefik
|
||||
./caddy
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dov.reverse-proxy.nginx;
|
||||
email = "susano@local.com";
|
||||
# configFile = pkgs.writeText "duckdns_config"
|
||||
# ''
|
||||
# example config file bla bla
|
||||
# '';
|
||||
in {
|
||||
options.dov.reverse-proxy.nginx = { enable = mkEnableOption "nginx config"; };
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
sops.secrets.duckdns-token = {
|
||||
owner = config.services.nginx.user;
|
||||
group = config.services.nginx.group;
|
||||
};
|
||||
|
||||
# 1. Enable Nginx
|
||||
|
||||
# 2. Enable Automatic Certificate Management (ACME)
|
||||
# NixOS uses acme.sh to handle Let's Encrypt certificates.
|
||||
security.acme = {
|
||||
acceptTerms = true;
|
||||
defaults.email = email;
|
||||
|
||||
# Define the certificates you want to obtain.
|
||||
# We use the DNS-01 challenge for wildcard domains.
|
||||
certs = {
|
||||
# Certificate for *.susano-lab.duckdns.org
|
||||
"susano-lab.duckdns.org" = {
|
||||
domain = "*.susano-lab.duckdns.org";
|
||||
extraDomainNames = [ "susano-lab.duckdns.org" ];
|
||||
dnsProvider = "duckdns";
|
||||
# The credentialsFile points to the secret file we created.
|
||||
credentialsFile = config.sops.secrets.duckdns-token.path;
|
||||
group = config.services.nginx.group;
|
||||
};
|
||||
|
||||
# Certificate for *.susano-tailscale.duckdns.org
|
||||
"susano-tailscale.duckdns.org" = {
|
||||
domain = "*.susano-tailscale.duckdns.org";
|
||||
extraDomainNames = [ "susano-tailscale.duckdns.org" ];
|
||||
dnsProvider = "duckdns";
|
||||
credentialsFile = config.sops.secrets.duckdns-token.path;
|
||||
group = config.services.nginx.group;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# 3. Define Nginx Reverse Proxy Configuration
|
||||
services.nginx = {
|
||||
enable = cfg.enable;
|
||||
|
||||
# Use httpConfig to define 'map' blocks at the correct level.
|
||||
httpConfig = ''
|
||||
# Map for susano-lab.duckdns.org domains
|
||||
map $host $lab_proxy_pass {
|
||||
"immich.susano-lab.duckdns.org" "http://192.168.1.57:2283";
|
||||
"jellyfin.susano-lab.duckdns.org" "http://192.168.1.64:8096";
|
||||
"jellyseer.susano-lab.duckdns.org" "http://192.168.1.68:5055";
|
||||
"nginx.susano-lab.duckdns.org" "http://192.168.1.57:81";
|
||||
"portainer.susano-lab.duckdns.org" "https://192.168.1.57:9443";
|
||||
"qbittorrent.susano-lab.duckdns.org" "http://192.168.1.57:8080";
|
||||
"radarr.susano-lab.duckdns.org" "http://192.168.1.57:7878";
|
||||
"searxng.susano-lab.duckdns.org" "http://192.168.1.82:8080";
|
||||
"sonarr.susano-lab.duckdns.org" "http://192.168.1.57:8989";
|
||||
"susano-lab.duckdns.org" "http://192.168.1.53:8006";
|
||||
default "http://127.0.0.1:8000"; # Optional: a default to avoid errors if no host matches
|
||||
}
|
||||
|
||||
# Map for susano-tailscale.duckdns.org domains
|
||||
map $host $tailscale_proxy_pass {
|
||||
"immich.susano-tailscale.duckdns.org" "http://192.168.1.57:2283";
|
||||
"searxng.susano-tailscale.duckdns.org" "http://192.168.1.82:8080";
|
||||
default "http://127.0.0.1:8000"; # Optional: a default
|
||||
}
|
||||
|
||||
# Map for susano-traefik.duckdns.org domains
|
||||
map $host $traefik_proxy_pass {
|
||||
"immich.susano-traefik.duckdns.org" "http://192.168.1.57:2283";
|
||||
default "http://127.0.0.1:8000"; # Optional: a default
|
||||
}
|
||||
'';
|
||||
|
||||
virtualHosts = {
|
||||
|
||||
# === Group for susano-lab.duckdns.org subdomains ===
|
||||
"susano-lab" = {
|
||||
serverName = "susano-lab.duckdns.org";
|
||||
serverAliases = [
|
||||
"test.susano-lab.duckdns.org"
|
||||
"immich.susano-lab.duckdns.org"
|
||||
"jellyfin.susano-lab.duckdns.org"
|
||||
"jellyseer.susano-lab.duckdns.org"
|
||||
"nginx.susano-lab.duckdns.org"
|
||||
"portainer.susano-lab.duckdns.org"
|
||||
"qbittorrent.susano-lab.duckdns.org"
|
||||
"radarr.susano-lab.duckdns.org"
|
||||
"searxng.susano-lab.duckdns.org"
|
||||
"sonarr.susano-lab.duckdns.org"
|
||||
];
|
||||
useACMEHost = "susano-lab.duckdns.org";
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
# The map block is removed from here.
|
||||
# We now use the variable defined in httpConfig.
|
||||
proxy_pass $lab_proxy_pass;
|
||||
|
||||
# Standard proxy headers for websockets and correct IP forwarding.
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
'';
|
||||
};
|
||||
|
||||
# === Group for susano-tailscale.duckdns.org subdomains ===
|
||||
"susano-tailscale" = {
|
||||
serverName = "susano-tailscale.duckdns.org";
|
||||
serverAliases = [
|
||||
"immich.susano-tailscale.duckdns.org"
|
||||
"searxng.susano-tailscale.duckdns.org"
|
||||
];
|
||||
useACMEHost = "susano-tailscale.duckdns.org";
|
||||
forceSSL = true;
|
||||
|
||||
locations."/".extraConfig = ''
|
||||
# Use the second variable defined in httpConfig.
|
||||
proxy_pass $tailscale_proxy_pass;
|
||||
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
{ config, lib, pkgs, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.dov.reverse-proxy.traefik;
|
||||
in {
|
||||
options.dov.reverse-proxy.traefik = { enable = mkEnableOption "traefik config"; };
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# 1. SOPS Configuration for the DuckDNS Token
|
||||
# This decrypts the secret and provides it to the Traefik service.
|
||||
sops.secrets.duckdns-token = {
|
||||
# The Traefik service needs permission to read this file.
|
||||
owner = "traefik";
|
||||
group = config.services.traefik.group;
|
||||
};
|
||||
|
||||
# 3. Traefik Service Configuration
|
||||
services.traefik = {
|
||||
enable = true;
|
||||
|
||||
# Load the DuckDNS token as an environment variable for Traefik.
|
||||
environmentFiles = [ config.sops.secrets.duckdns-token.path ];
|
||||
|
||||
# Static configuration (traefik.yml) - defines entrypoints and certificate resolvers.
|
||||
staticConfigOptions = {
|
||||
# -- EntryPoints: Where Traefik listens for traffic --
|
||||
entryPoints = {
|
||||
# Unsecured HTTP on port 80, mainly for redirection
|
||||
web = {
|
||||
address = ":80";
|
||||
# Redirect all traffic from this entrypoint to the 'websecure' (HTTPS) entrypoint
|
||||
http.redirections.entryPoint = {
|
||||
to = "websecure";
|
||||
scheme = "https";
|
||||
permanent = true;
|
||||
};
|
||||
};
|
||||
# Secured HTTPS on port 443
|
||||
websecure = {
|
||||
address = ":443";
|
||||
};
|
||||
};
|
||||
|
||||
# -- Certificate Resolver: How Traefik gets SSL certs --
|
||||
certificatesResolvers = {
|
||||
# We'll name our resolver 'duckdns'
|
||||
duckdns = {
|
||||
acme = {
|
||||
email = "susano@local.com";
|
||||
storage = "/var/lib/traefik/acme.json"; # Where Traefik stores certs
|
||||
# Use the DNS-01 challenge with the DuckDNS provider
|
||||
dnsChallenge = {
|
||||
provider = "duckdns";
|
||||
# Traefik will get the DUCKDNS_TOKEN from the environment file.
|
||||
resolvers = [
|
||||
"1.1.1.1:53"
|
||||
"8.8.8.8:53"
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# Optional but recommended: Enable the Traefik Dashboard
|
||||
api.dashboard = true;
|
||||
};
|
||||
|
||||
# Dynamic configuration - defines the actual routers and services.
|
||||
dynamicConfigOptions = {
|
||||
http = {
|
||||
routers = {
|
||||
# --- Router for the Traefik dashboard (optional) ---
|
||||
dashboard-router = {
|
||||
rule = "Host(`traefik.local.susano-traefik.duckdns.org`)"; # Example: A local-only subdomain
|
||||
entryPoints = [ "websecure" ];
|
||||
service = "api@internal"; # Special service for the dashboard
|
||||
tls.certResolver = "duckdns";
|
||||
};
|
||||
|
||||
immich-router = {
|
||||
rule = "Host(`immich.susano-traefik.duckdns.org`)"; # 1. The new domain
|
||||
entryPoints = [ "websecure" ]; # 2. Listen on HTTPS
|
||||
service = "immich-service"; # 3. Link to the new Immich service
|
||||
tls.certResolver = "duckdns"; # 4. Use the same SSL resolver
|
||||
};
|
||||
};
|
||||
|
||||
services = {
|
||||
immich-service = {
|
||||
loadBalancer.servers = [
|
||||
# The backend URL for Immich
|
||||
{ url = "http://192.168.1.57:2283"; }
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
middlewares = {
|
||||
# --- Middleware for dashboard authentication (optional) ---
|
||||
auth = {
|
||||
# Run `nix-shell -p apacheHttpdTools --run "htpasswd -nb your-user your-password"`
|
||||
# to generate the user:password hash.
|
||||
basicAuth.users = [
|
||||
"your-user:$apr1$....some-hash-here...."
|
||||
];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user