ready for runners

This commit is contained in:
plasmagoat 2025-06-06 23:32:17 +02:00
parent fc9971ddc9
commit 7dd5043b5d
49 changed files with 2569 additions and 1085 deletions

View file

@ -0,0 +1,10 @@
{ lib, config, ... }:
let
internalNetwork = "192.168.1.0/24";
in
{
internal-whitelist = {
ipWhiteList.sourceRange = [ internalNetwork ];
};
}

View file

@ -0,0 +1,140 @@
{ lib, config, ... }:
{
traefik = {
rule = "Host(`traefik.procopius.dk`)";
service = "traefik";
entryPoints = [ "websecure" ];
middlewares = [ "internal-whitelist" ];
tls = { certResolver = "letsencrypt"; };
};
proxmox = {
rule = "Host(`proxmox.procopius.dk`)";
service = "proxmox";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
forgejo = {
rule = "Host(`git.procopius.dk`)";
service = "forgejo";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
prometheus = {
rule = "Host(`prometheus.procopius.dk`)";
service = "prometheus";
entryPoints = [ "websecure" ];
middlewares = [ "internal-whitelist" ];
tls = { certResolver = "letsencrypt"; };
};
grafana = {
rule = "Host(`grafana.procopius.dk`)";
service = "grafana";
entryPoints = [ "websecure" ];
middlewares = [ "internal-whitelist" ];
tls = { certResolver = "letsencrypt"; };
};
alertmanager = {
rule = "Host(`alertmanager.procopius.dk`)";
service = "alertmanager";
entryPoints = [ "websecure" ];
middlewares = [ "internal-whitelist" ];
tls = { certResolver = "letsencrypt"; };
};
jellyfin = {
rule = "Host(`jellyfin.procopius.dk`)";
service = "jellyfin";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
sonarr = {
rule = "Host(`sonarr.procopius.dk`)";
service = "sonarr";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
radarr = {
rule = "Host(`radarr.procopius.dk`)";
service = "radarr";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
ente = {
rule = "Host(`ente.procopius.dk`)";
service = "ente";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
photos = {
rule = "Host(`photos.procopius.dk`)";
service = "photos";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
minio = {
rule = "Host(`minio.procopius.dk`)";
service = "minio";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
minio-api = {
rule = "Host(`minio-api.procopius.dk`)";
service = "minio-api";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
account = {
rule = "Host(`account.procopius.dk`)";
service = "account";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
auth = {
rule = "Host(`auth.procopius.dk`)";
service = "auth";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
nas = {
rule = "Host(`nas.procopius.dk`)";
service = "nas";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
umami = {
rule = "Host(`umami.procopius.dk`)";
service = "umami";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
mesterjakob = {
rule = "Host(`mester.jakobblum.dk`)";
service = "mesterjakob";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
catchAll = {
rule = "HostRegexp(`.+`)";
service = "nginx";
entryPoints = [ "websecure" ];
tls = { certResolver = "letsencrypt"; };
};
}

View file

@ -0,0 +1,38 @@
{ lib, config, ... }:
{
proxmox.loadBalancer.servers = [ { url = "https://192.168.1.205:8006"; } ];
proxmox.loadBalancer.serversTransport = "insecureTransport";
traefik.loadBalancer.servers = [ { url = "http://localhost:8080"; } ];
forgejo.loadBalancer.servers = [ { url = "http://forgejo.lab:3000"; } ];
nginx.loadBalancer.servers = [ { url = "https://192.168.1.226:4433"; } ];
nginx.loadBalancer.serversTransport = "insecureTransport";
prometheus.loadBalancer.servers = [ { url = "http://monitor.lab:9090"; } ];
grafana.loadBalancer.servers = [ { url = "http://monitor.lab:3000"; } ];
alertmanager.loadBalancer.servers = [ { url = "http://monitor.lab:9093"; } ];
# from nginx
account.loadBalancer.servers = [ { url = "http://192.168.1.226:3001"; } ];
auth.loadBalancer.servers = [ { url = "http://192.168.1.226:3005"; } ];
ente.loadBalancer.servers = [ { url = "http://192.168.1.226:8087"; } ];
photos.loadBalancer.servers = [ { url = "http://192.168.1.226:3000"; } ];
minio.loadBalancer.servers = [ { url = "http://192.168.1.226:3201"; } ];
minio-api.loadBalancer.servers = [ { url = "http://192.168.1.226:3200"; } ];
nas.loadBalancer.servers = [ { url = "https://192.168.1.226:5001"; } ];
nas.loadBalancer.serversTransport = "insecureTransport";
jellyfin.loadBalancer.servers = [ { url = "http://192.168.1.226:8096"; } ];
radarr.loadBalancer.servers = [ { url = "http://192.168.1.226:7878"; } ];
sonarr.loadBalancer.servers = [ { url = "http://192.168.1.226:8989"; } ];
umami.loadBalancer.servers = [ { url = "http://192.168.1.226:3333"; } ];
mesterjakob.loadBalancer.servers = [ { url = "http://192.168.1.226:4200"; } ];
}

View file

@ -0,0 +1,61 @@
{ lib, config, ... }:
{
entryPoints = {
web = {
address = ":80";
asDefault = true;
http.redirections.entrypoint = {
to = "websecure";
scheme = "https";
};
};
websecure = {
address = ":443";
http.tls.certResolver = "letsencrypt";
};
metrics = {
address = ":8082";
};
};
api = {
dashboard = true;
insecure = true;
};
certificatesResolvers = {
letsencrypt = {
acme = {
email = "david.mikael@proton.me";
storage = "/var/lib/traefik/acme.json";
# httpChallenge = {
# entryPoint = "web";
# };
dnsChallenge = {
provider = "cloudflare";
delayBeforeCheck = 10;
resolvers = [ "1.1.1.1:53" "8.8.8.8:53" ];
};
};
};
};
metrics = {
prometheus = {
entryPoint = "metrics";
};
};
log = {
level = "DEBUG";
filePath = "/var/log/traefik/traefik.log";
};
accessLog = {
format = "json";
filePath = "/var/log/traefik/access.log";
};
}

View file

@ -1,18 +1,13 @@
{ config, lib, pkgs, ... }: {
networking = {
hostName = "traefik";
interfaces.eth0 = {
ipv4.addresses = [{
address = "192.168.1.171";
prefixLength = 24;
}];
};
firewall.allowedTCPPorts = [ 80 443 8080 8082 ];
networking.hostName = "traefik";
networking.interfaces.eth0.ipv4.addresses = [{
address = "192.168.1.80";
prefixLength = 24;
}];
defaultGateway = {
address = "192.168.1.1";
interface = "eth0";
};
};
networking.firewall.allowedTCPPorts = [ 80 443 8080 8082 ];
networking.nameservers = [ "192.168.1.53" ];
networking.defaultGateway = "192.168.1.1";
}

View file

@ -14,10 +14,10 @@
{
targets = [ "localhost" ];
labels = {
job = "traefik";
job = "/var/log/traefik/*.log";
host = config.networking.hostName;
env = "proxmox";
instance = "${config.networking.hostName}.local"; # prometheus scrape target
instance = "${config.networking.hostName}.lab"; # prometheus scrape target
__path__ = "/var/log/traefik/*.log";
};
}

View file

@ -1,158 +1,36 @@
{ config, lib, pkgs, ... }: {
{ config, lib, pkgs, ... }:
# Traefik reverse proxy setup
let
staticConfig = import ./configuration/static.nix { inherit lib config; };
middlewaresConfig = import ./configuration/middlewares.nix { inherit lib config; };
routersConfig = import ./configuration/routers.nix { inherit lib config; };
servicesConfig = import ./configuration/services.nix { inherit lib config; };
in
{
services.traefik = {
enable = true;
staticConfigOptions = {
entryPoints = {
web = {
address = ":80";
asDefault = true;
http.redirections.entrypoint = {
to = "websecure";
scheme = "https";
};
};
# ==== Static Configuration ====
staticConfigOptions = staticConfig;
websecure = {
address = ":443";
asDefault = true;
http.tls.certResolver = "letsencrypt";
};
# ==== Dynamic Configuration ====
dynamicConfigOptions.http = {
routers = routersConfig;
services = servicesConfig;
middlewares = middlewaresConfig;
metrics = {
address = ":8082";
serversTransports = {
insecureTransport = {
insecureSkipVerify = true;
};
};
api.dashboard = true;
api.insecure = true;
# Enable Let's Encrypt
certificatesResolvers = {
letsencrypt = {
acme = {
email = "david.mikael@proton.me"; # Replace with your email
storage = "/var/lib/traefik/acme.json"; # Location to store ACME certificates
httpChallenge = {
entryPoint = "web"; # Uses HTTP challenge (can also use DNS)
};
# Uncomment the following for staging (testing) environment
# caServer = "https://acme-staging-v02.api.letsencrypt.org/directory";
};
};
};
# Enable Prometheus metrics
metrics = {
prometheus = {
entryPoint = "metrics";
};
};
log = {
level = "DEBUG";
filePath = "/var/log/traefik/traefik.log";
};
accessLog = {
format = "json";
filePath = "/var/log/traefik/access.log";
};
# Enable access logs (you can customize the log format)
# accessLog = {
# filePath = "/var/log/traefik/access.log"; # Log to a file
# format = "common"; # You can adjust this to `json` or `common`
# };
# tracing = {
# enabled = true;
# provider = "jaeger"; # or zipkin, or other
# jaeger = {
# apiURL = "http://localhost:5775"; # Replace with your Jaeger instance URL
# };
# };
};
dynamicConfigOptions = {
# Add IP whitelisting middleware to restrict access to internal network only
http.middlewares = {
internal-whitelist = {
ipWhiteList = {
sourceRange = ["192.168.1.0/24"]; # Adjust to your internal network range
# Alternatively use `127.0.0.1/32` for localhost access
};
};
};
# Route to Proxmox UI
http.routers.proxmox = {
rule = "Host(`proxmox.procopius.dk`)";
service = "proxmox";
entryPoints = [ "web" "websecure" ];
tls = {
certResolver = "letsencrypt"; # Use Let's Encrypt
};
};
# Route to Traefik Dashboard
http.routers.traefik = {
rule = "Host(`traefik.procopius.dk`)";
service = "traefik";
entryPoints = [ "web" "websecure" ];
middlewares = ["internal-whitelist"];
tls = {
certResolver = "letsencrypt"; # Use Let's Encrypt
};
};
http.routers.forgejo = {
rule = "Host(`git.procopius.dk`)";
service = "forgejo";
entryPoints = [ "web" "websecure" ];
tls = {
certResolver = "letsencrypt"; # Use Let's Encrypt
};
};
# Route to Traefik Dashboard
http.routers.catchAll = {
# rule = "Host(`jellyfin.procopius.dk`)";
rule = "HostRegexp(`.+`)";
# rule = "HostRegexp(`{host:.+}`)";
service = "nginx";
entryPoints = [ "web" "websecure" ];
tls = {
certResolver = "letsencrypt"; # Use Let's Encrypt
};
};
# Define the services
http.services.proxmox.loadBalancer.servers = [
{ url = "https://192.168.1.205:8006"; } # Proxmox
];
http.services.proxmox.loadBalancer.serversTransport = "insecureTransport";
http.services.traefik.loadBalancer.servers = [
{ url = "http://traefik.local:8080"; } # Traefik Dashboard
];
http.services.forgejo.loadBalancer.servers = [
{ url = "http://192.168.1.249:3000"; } # forgejo
];
http.services.nginx.loadBalancer.servers = [
{ url = "https://192.168.1.226:4433"; } # nginx
];
http.services.nginx.loadBalancer.serversTransport = "insecureTransport";
http.serversTransports.insecureTransport.insecureSkipVerify = true;
};
};
# Optionally, you can add Docker support if using Docker Compose
systemd.services.traefik.serviceConfig.Environment = [
"CLOUDFLARE_DNS_API_TOKEN=gQYyG6cRw-emp_qpsUj9TrkYgoVC1v9UUtv94ozA"
"CLOUDFLARE_ZONE_API_TOKEN=gQYyG6cRw-emp_qpsUj9TrkYgoVC1v9UUtv94ozA"
];
virtualisation.docker.enable = true;
}