Compare commits
7 commits
4c6bc31476
...
d97a085af5
| Author | SHA1 | Date | |
|---|---|---|---|
| d97a085af5 | |||
| 061fdb2a47 | |||
| e8d9329e8e | |||
| b4650bba54 | |||
| d7a0b75042 | |||
| 791deb39f9 | |||
| 97d6838274 |
12 changed files with 541 additions and 161 deletions
50
flake.lock
generated
50
flake.lock
generated
|
|
@ -30,11 +30,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1772058043,
|
"lastModified": 1774779250,
|
||||||
"narHash": "sha256-m1cmQgb6tBcHkndKZ8BSsw6PRNJMG89FZwoYVOuKi34=",
|
"narHash": "sha256-n7zH1dk+mcUt59i5FDSF3q6G398NzKVt/E/lM2DZY8A=",
|
||||||
"owner": "AdnanHodzic",
|
"owner": "AdnanHodzic",
|
||||||
"repo": "auto-cpufreq",
|
"repo": "auto-cpufreq",
|
||||||
"rev": "5d600d710bb2aa331e1a4370e08476bcdea1cab5",
|
"rev": "a620b9971963730978a0e5fc9d92bf613218d21e",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -50,11 +50,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1773889306,
|
"lastModified": 1776613567,
|
||||||
"narHash": "sha256-PAqwnsBSI9SVC2QugvQ3xeYCB0otOwCacB1ueQj2tgw=",
|
"narHash": "sha256-gC9Cp5ibBmGD5awCA9z7xy6MW6iJufhazTYJOiGlCUI=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "disko",
|
"repo": "disko",
|
||||||
"rev": "5ad85c82cc52264f4beddc934ba57f3789f28347",
|
"rev": "32f4236bfc141ae930b5ba2fb604f561fed5219d",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -144,11 +144,11 @@
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774559029,
|
"lastModified": 1775425411,
|
||||||
"narHash": "sha256-deix7yg3j6AhjMPnFDCmWB3f83LsajaaULP5HH2j34k=",
|
"narHash": "sha256-KY6HsebJHEe5nHOWP7ur09mb0drGxYSzE3rQxy62rJo=",
|
||||||
"owner": "nix-community",
|
"owner": "nix-community",
|
||||||
"repo": "home-manager",
|
"repo": "home-manager",
|
||||||
"rev": "a0bb0d11514f92b639514220114ac8063c72d0a3",
|
"rev": "0d02ec1d0a05f88ef9e74b516842900c41f0f2fe",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -181,11 +181,11 @@
|
||||||
},
|
},
|
||||||
"nixos-hardware": {
|
"nixos-hardware": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774465523,
|
"lastModified": 1776983936,
|
||||||
"narHash": "sha256-4v7HPm63Q90nNn4fgkgKsjW1AH2Klw7XzPtHJr562nM=",
|
"narHash": "sha256-ZOQyNqSvJ8UdrrqU1p7vaFcdL53idK+LOM8oRWEWh6o=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixos-hardware",
|
"repo": "nixos-hardware",
|
||||||
"rev": "de895be946ad1d8aafa0bb6dfc7e7e0e9e466a29",
|
"rev": "2096f3f411ce46e88a79ae4eafcfc9df8ed41c61",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -197,11 +197,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774388614,
|
"lastModified": 1776734388,
|
||||||
"narHash": "sha256-tFwzTI0DdDzovdE9+Ras6CUss0yn8P9XV4Ja6RjA+nU=",
|
"narHash": "sha256-vl3dkhlE5gzsItuHoEMVe+DlonsK+0836LIRDnm6MXQ=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "1073dad219cb244572b74da2b20c7fe39cb3fa9e",
|
"rev": "10e7ad5bbcb421fe07e3a4ad53a634b0cd57ffac",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -261,11 +261,11 @@
|
||||||
},
|
},
|
||||||
"nixpkgs-unstable": {
|
"nixpkgs-unstable": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774386573,
|
"lastModified": 1776877367,
|
||||||
"narHash": "sha256-4hAV26quOxdC6iyG7kYaZcM3VOskcPUrdCQd/nx8obc=",
|
"narHash": "sha256-EHq1/OX139R1RvBzOJ0aMRT3xnWyqtHBRUBuO1gFzjI=",
|
||||||
"owner": "nixos",
|
"owner": "nixos",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "46db2e09e1d3f113a13c0d7b81e2f221c63b8ce9",
|
"rev": "0726a0ecb6d4e08f6adced58726b95db924cef57",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -307,11 +307,11 @@
|
||||||
"utils": "utils"
|
"utils": "utils"
|
||||||
},
|
},
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1769870714,
|
"lastModified": 1775228763,
|
||||||
"narHash": "sha256-wjwCj70iiFXoAasQto+3jTaA4wCMOAs/rdX+nsmtBrQ=",
|
"narHash": "sha256-8fKOEOouCaPZLBTdWPS+uU0bxsPp1OmfloDNoNSiu8w=",
|
||||||
"owner": "SaumonNet",
|
"owner": "SaumonNet",
|
||||||
"repo": "proxmox-nixos",
|
"repo": "proxmox-nixos",
|
||||||
"rev": "c1f79f104930347a0b84abbca0d42884063a8c09",
|
"rev": "e803cb839e5e5207fa37d92bc6ac7290f4dba633",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
|
|
@ -338,11 +338,11 @@
|
||||||
"secrets": {
|
"secrets": {
|
||||||
"flake": false,
|
"flake": false,
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1774571252,
|
"lastModified": 1777076192,
|
||||||
"narHash": "sha256-NU/vfItTMSjaRTXe0UDzbWR8UnhkBUFU47OpqEpxKb4=",
|
"narHash": "sha256-N7n2OPN2IRWwL73Cr6mc5nNhucHmMeFas9hQ/NF0bFg=",
|
||||||
"ref": "refs/heads/main",
|
"ref": "refs/heads/main",
|
||||||
"rev": "7965907ae885d77acb3c4ecc11cee096a12af868",
|
"rev": "34ff1c4b0460a2e103a8fec183f53f274dc123ed",
|
||||||
"revCount": 25,
|
"revCount": 32,
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "ssh://git@git.jfreudenberger.de/JuliusFreudenberger/nix-private.git"
|
"url": "ssh://git@git.jfreudenberger.de/JuliusFreudenberger/nix-private.git"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
18
flake.nix
18
flake.nix
|
|
@ -167,6 +167,24 @@
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
srv03 = nixpkgs.lib.nixosSystem rec {
|
||||||
|
system = "x86_64-linux";
|
||||||
|
|
||||||
|
specialArgs = {
|
||||||
|
inherit inputs outputs;
|
||||||
|
pkgs-unstable = import nixpkgs-unstable {
|
||||||
|
inherit system;
|
||||||
|
config.allowUnfree = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
modules = [
|
||||||
|
disko.nixosModules.disko
|
||||||
|
agenix.nixosModules.default
|
||||||
|
./hosts/srv03
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
homeConfigurations = {
|
homeConfigurations = {
|
||||||
|
|
|
||||||
91
hosts/srv03/default.nix
Normal file
91
hosts/srv03/default.nix
Normal file
|
|
@ -0,0 +1,91 @@
|
||||||
|
{ inputs, outputs, config, lib, pkgs, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[
|
||||||
|
./secrets.nix
|
||||||
|
|
||||||
|
../../modules/disko/legacy-full-ext4-swap.nix
|
||||||
|
|
||||||
|
../../users/julius/nixos-server.nix
|
||||||
|
../../modules/nix.nix
|
||||||
|
../../modules/locale.nix
|
||||||
|
../../modules/server-cli.nix
|
||||||
|
../../modules/sshd.nix
|
||||||
|
../../modules/qemu-guest.nix
|
||||||
|
../../modules/docker.nix
|
||||||
|
../../modules/traefik.nix
|
||||||
|
../../modules/pocket-id.nix
|
||||||
|
../../modules/auto-upgrade.nix
|
||||||
|
"${inputs.secrets}/modules/opkssh.nix"
|
||||||
|
# Include the results of the hardware scan.
|
||||||
|
./hardware-configuration.nix
|
||||||
|
];
|
||||||
|
|
||||||
|
#services.openssh.openFirewall = false;
|
||||||
|
|
||||||
|
services = {
|
||||||
|
traefik-docker = {
|
||||||
|
enable = true;
|
||||||
|
dashboardUrl = "traefik.netbird.jfreudenberger.de";
|
||||||
|
dnsChallengeProvider = "inwx";
|
||||||
|
dnsSecrets = [
|
||||||
|
config.age.secrets.inwx
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
pocket-id-docker.enable = true;
|
||||||
|
pocket-id = {
|
||||||
|
settings = {
|
||||||
|
APP_URL = "https://login.jfreudenberger.de";
|
||||||
|
TRUST_PROXY = true;
|
||||||
|
};
|
||||||
|
environmentFile = config.age.secrets.pocket-id.path;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.network = {
|
||||||
|
enable = true;
|
||||||
|
networks."10-wan" = {
|
||||||
|
matchConfig.Name = "enp1s0";
|
||||||
|
networkConfig.DHCP = "no";
|
||||||
|
address = [
|
||||||
|
"46.224.47.24/32"
|
||||||
|
"2a01:4f8:c013:bf68::1/64"
|
||||||
|
];
|
||||||
|
routes = [
|
||||||
|
{ Gateway = "172.31.1.1"; GatewayOnLink = true; }
|
||||||
|
{ Gateway = "fe80::1"; GatewayOnLink = true; }
|
||||||
|
];
|
||||||
|
dns = [ "9.9.9.9" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
boot = {
|
||||||
|
tmp.cleanOnBoot = true;
|
||||||
|
growPartition = true;
|
||||||
|
kernelParams = [ "console=ttyS0" ];
|
||||||
|
loader = {
|
||||||
|
grub.enable = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
# Disable classic networking configuration
|
||||||
|
networking.useDHCP = lib.mkForce false;
|
||||||
|
|
||||||
|
networking.hostName = "srv03"; # Define your hostname.
|
||||||
|
|
||||||
|
# This option defines the first version of NixOS you have installed on this particular machine,
|
||||||
|
# and is used to maintain compatibility with application data (e.g. databases) created on older NixOS versions.
|
||||||
|
# Most users should NEVER change this value after the initial install, for any reason,
|
||||||
|
# even if you've upgraded your system to a new NixOS release.
|
||||||
|
# This value does NOT affect the Nixpkgs version your packages and OS are pulled from,
|
||||||
|
# so changing it will NOT upgrade your system - see https://nixos.org/manual/nixos/stable/#sec-upgrading for how
|
||||||
|
# to actually do that.
|
||||||
|
# This value being lower than the current NixOS release does NOT mean your system is
|
||||||
|
# out of date, out of support, or vulnerable.
|
||||||
|
# Do NOT change this value unless you have manually inspected all the changes it would make to your configuration,
|
||||||
|
# and migrated your data accordingly.
|
||||||
|
# For more information, see `man configuration.nix` or https://nixos.org/manual/nixos/stable/options#opt-system.stateVersion .
|
||||||
|
system.stateVersion = "25.05"; # Did you read the comment?
|
||||||
|
}
|
||||||
24
hosts/srv03/hardware-configuration.nix
Normal file
24
hosts/srv03/hardware-configuration.nix
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
# Do not modify this file! It was generated by ‘nixos-generate-config’
|
||||||
|
# and may be overwritten by future invocations. Please make changes
|
||||||
|
# to /etc/nixos/configuration.nix instead.
|
||||||
|
{ config, lib, pkgs, modulesPath, ... }:
|
||||||
|
|
||||||
|
{
|
||||||
|
imports =
|
||||||
|
[ (modulesPath + "/profiles/qemu-guest.nix")
|
||||||
|
];
|
||||||
|
|
||||||
|
boot.initrd.availableKernelModules = [ "ahci" "xhci_pci" "virtio_pci" "virtio_scsi" "sd_mod" "sr_mod" ];
|
||||||
|
boot.initrd.kernelModules = [ ];
|
||||||
|
boot.kernelModules = [ "kvm-intel" ];
|
||||||
|
boot.extraModulePackages = [ ];
|
||||||
|
|
||||||
|
# Enables DHCP on each ethernet and wireless interface. In case of scripted networking
|
||||||
|
# (the default) this is the recommended approach. When using systemd-networkd it's
|
||||||
|
# still possible to use this option, but it's recommended to use it in conjunction
|
||||||
|
# with explicit per-interface declarations with `networking.interfaces.<interface>.useDHCP`.
|
||||||
|
networking.useDHCP = lib.mkDefault true;
|
||||||
|
# networking.interfaces.enp1s0.useDHCP = lib.mkDefault true;
|
||||||
|
|
||||||
|
nixpkgs.hostPlatform = lib.mkDefault "x86_64-linux";
|
||||||
|
}
|
||||||
7
hosts/srv03/secrets.nix
Normal file
7
hosts/srv03/secrets.nix
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
age.secrets = {
|
||||||
|
inwx.file = "${inputs.secrets}/secrets/dns-management/inwx";
|
||||||
|
pocket-id.file = "${inputs.secrets}/secrets/srv03/pocket-id";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
remmina
|
remmina
|
||||||
|
|
||||||
teleport_17.client
|
teleport_17.client
|
||||||
|
opkssh
|
||||||
];
|
];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
45
modules/disko/legacy-full-ext4-swap.nix
Normal file
45
modules/disko/legacy-full-ext4-swap.nix
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
disko.devices = {
|
||||||
|
disk = {
|
||||||
|
sda = {
|
||||||
|
type = "disk";
|
||||||
|
device = "/dev/sda";
|
||||||
|
content = {
|
||||||
|
type = "gpt";
|
||||||
|
partitions = {
|
||||||
|
MBR = {
|
||||||
|
type = "EF02"; # for grub MBR
|
||||||
|
size = "1M";
|
||||||
|
priority = 1; # Needs to be first partition
|
||||||
|
};
|
||||||
|
ESP = {
|
||||||
|
size = "1G";
|
||||||
|
type = "EF00";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "vfat";
|
||||||
|
mountpoint = "/boot";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
root = {
|
||||||
|
end = "-1G";
|
||||||
|
content = {
|
||||||
|
type = "filesystem";
|
||||||
|
format = "ext4";
|
||||||
|
mountpoint = "/";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
encryptedSwap = {
|
||||||
|
size = "100%";
|
||||||
|
content = {
|
||||||
|
type = "swap";
|
||||||
|
randomEncryption = true;
|
||||||
|
priority = 100;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -38,7 +38,7 @@ in {
|
||||||
};
|
};
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
''--mount=type=volume,source=dockhand-data,target=/app/data,volume-driver=local''
|
''--mount=type=volume,source=dockhand-data,target=/app/data,volume-driver=local''
|
||||||
''--group-add=131'' # docker group
|
''--group-add=${config.ids.gids.docker}''
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
...
|
...
|
||||||
}: {
|
}: {
|
||||||
|
|
||||||
boot.kernelPackages = pkgs.linuxPackages_latest;
|
boot.kernelPackages = pkgs.linuxKernel.packages.linux_zen;
|
||||||
|
|
||||||
services.logind.settings.Login = {
|
services.logind.settings.Login = {
|
||||||
HandleLidSwitch= "suspend-then-hibernate";
|
HandleLidSwitch= "suspend-then-hibernate";
|
||||||
|
|
|
||||||
58
modules/pocket-id.nix
Normal file
58
modules/pocket-id.nix
Normal file
|
|
@ -0,0 +1,58 @@
|
||||||
|
{
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.pocket-id-docker;
|
||||||
|
pocketidCfg = config.services.pocket-id;
|
||||||
|
version = "2.6.2";
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.pocket-id-docker = {
|
||||||
|
enable = lib.mkEnableOption "Pocket ID server hosted as OCI container";
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
pocket-id = {
|
||||||
|
image = "ghcr.io/pocket-id/pocket-id:v${version}";
|
||||||
|
autoStart = true;
|
||||||
|
networks = [
|
||||||
|
"webproxy"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
APP_URL = pocketidCfg.settings.APP_URL;
|
||||||
|
TRUST_PROXY = lib.boolToString pocketidCfg.settings.TRUST_PROXY;
|
||||||
|
ANALYTICS_DISABLED = lib.boolToString pocketidCfg.settings.ANALYTICS_DISABLED;
|
||||||
|
};
|
||||||
|
environmentFiles = [ pocketidCfg.environmentFile ];
|
||||||
|
extraOptions = [
|
||||||
|
''--mount=type=volume,source=data,target=/app/data,volume-driver=local''
|
||||||
|
"--health-cmd=/app/pocket-id healthcheck"
|
||||||
|
"--health-interval=1m30s"
|
||||||
|
"--health-timeout=5s"
|
||||||
|
"--health-retries=2"
|
||||||
|
"--health-start-period=10s"
|
||||||
|
];
|
||||||
|
labels = {
|
||||||
|
"traefik.enable" = "true";
|
||||||
|
"traefik.http.routers.pocket-id.rule" = "Host(`${lib.removePrefix "https://" pocketidCfg.settings.APP_URL}`)";
|
||||||
|
"traefik.http.routers.pocket-id.entrypoints" = "websecure";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."docker-pocket-id" = {
|
||||||
|
after = [
|
||||||
|
"docker-traefik.service"
|
||||||
|
];
|
||||||
|
requires = [
|
||||||
|
"docker-traefik.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
221
modules/traefik-oidc.nix
Normal file
221
modules/traefik-oidc.nix
Normal file
|
|
@ -0,0 +1,221 @@
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
config,
|
||||||
|
lib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
|
||||||
|
cfg = config.services.traefik-docker;
|
||||||
|
|
||||||
|
mapOidcClientNameToEnv = stringToReplace: lib.replaceString "-" "_" (lib.toUpper stringToReplace);
|
||||||
|
|
||||||
|
traefik-mtls-config = (pkgs.formats.yaml { }).generate "traefik-mtls-config" {
|
||||||
|
tls.options.default.clientAuth = {
|
||||||
|
caFiles = "caFiles/root_ca.crt";
|
||||||
|
clientAuthType = "VerifyClientCertIfGiven";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
|
||||||
|
options.services.traefik-docker = {
|
||||||
|
enable = lib.mkEnableOption "traefik web server hosted as OCI container";
|
||||||
|
dashboardUrl = lib.mkOption {
|
||||||
|
description = "External URL the traefik dashboard will be reachable from, without protocol";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
dnsSecrets = lib.mkOption {
|
||||||
|
description = "Secrets for DNS providers.";
|
||||||
|
type = lib.types.listOf lib.types.anything;
|
||||||
|
};
|
||||||
|
mTLSCaCertSecret = lib.mkOption {
|
||||||
|
description = "Agenix secret containing the CA file to verify client certificates against.";
|
||||||
|
};
|
||||||
|
oidcAuthProviderUrl = lib.mkOption {
|
||||||
|
description = "Provider URL of OIDC auth provider.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
oidcClients = lib.mkOption {
|
||||||
|
example = ''
|
||||||
|
immich = {
|
||||||
|
scopes = [
|
||||||
|
"openid"
|
||||||
|
"email"
|
||||||
|
"profile"
|
||||||
|
];
|
||||||
|
enableBypassUsingClientCertificate = true;
|
||||||
|
usePkce = true;
|
||||||
|
};
|
||||||
|
'';
|
||||||
|
description = "Attribute set of OIDC clients with their configurations.";
|
||||||
|
type = lib.types.attrsOf (
|
||||||
|
lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
secret = lib.mkOption {
|
||||||
|
description = ''Agenix secret containing the following needed environment variables in dotenv notation:
|
||||||
|
- <clientName>_OIDC_AUTH_SECRET
|
||||||
|
- <clientName>_OIDC_AUTH_PROVIDER_CLIENT_ID
|
||||||
|
- <clientName>_OIDC_CLIENT_SECRET
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
scopes = lib.mkOption {
|
||||||
|
default = [ "openid" ];
|
||||||
|
example = [ "openid" "email" "profile" "groups" ];
|
||||||
|
description = "OIDC scopes to request from auth provider.";
|
||||||
|
type = lib.types.listOf lib.types.str;
|
||||||
|
};
|
||||||
|
usePkce = lib.mkOption {
|
||||||
|
default = true;
|
||||||
|
description = "Whether to enable PKCE for this provider.";
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
enableBypassUsingClientCertificate = lib.mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "Whether to allow bypassing OIDC protection when a verified client certificate is presented.";
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
useClaimsFromUserInfo = lib.mkOption {
|
||||||
|
default = false;
|
||||||
|
description = "When enabled, an additional request to the provider's userinfo_endpoint is made to validate the token and to retrieve additional claims. The userinfo claims are merged directly into the token claims, with userinfo values overriding token values for non-security-critical claims.";
|
||||||
|
type = lib.types.bool;
|
||||||
|
};
|
||||||
|
headers = lib.mkOption {
|
||||||
|
default = [];
|
||||||
|
description = "Headers to be added to the upstream request. Templating is possible. Documentation can be found here: https://traefik-oidc-auth.sevensolutions.cc/docs/getting-started/middleware-configuration";
|
||||||
|
type = lib.types.listOf (lib.types.submodule {
|
||||||
|
options = {
|
||||||
|
Name = lib.mkOption {
|
||||||
|
description = "The name of the header which should be added to the upstream request.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
Value = lib.mkOption {
|
||||||
|
description = "The value of the header, which can use Go-Templates.";
|
||||||
|
type = lib.types.str;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
config = lib.mkIf cfg.enable {
|
||||||
|
virtualisation.oci-containers.containers = {
|
||||||
|
traefik = {
|
||||||
|
image = "traefik:v3.6.6";
|
||||||
|
cmd = [
|
||||||
|
"--providers.docker=true"
|
||||||
|
"--providers.docker.exposedByDefault=false"
|
||||||
|
"--providers.docker.network=traefik"
|
||||||
|
"--providers.file.directory=/dynamic-config"
|
||||||
|
"--log.level=INFO"
|
||||||
|
"--api=true"
|
||||||
|
"--ping=true"
|
||||||
|
"--entrypoints.web.address=:80"
|
||||||
|
"--entrypoints.websecure.address=:443"
|
||||||
|
"--entrypoints.websecure.transport.respondingTimeouts.readTimeout=600s"
|
||||||
|
"--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=600s"
|
||||||
|
"--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=600s"
|
||||||
|
"--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
||||||
|
"--entrypoints.websecure.asDefault=true"
|
||||||
|
"--entrypoints.websecure.http.middlewares=strip-mtls-headers@docker,pass-tls-client-cert@docker"
|
||||||
|
"--entrypoints.websecure.http.tls.certresolver=letsencrypt"
|
||||||
|
"--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
|
||||||
|
"--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
|
||||||
|
"--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=netcup"
|
||||||
|
"--experimental.plugins.traefik-oidc-auth.modulename=github.com/sevensolutions/traefik-oidc-auth"
|
||||||
|
"--experimental.plugins.traefik-oidc-auth.version=v0.17.0"
|
||||||
|
];
|
||||||
|
autoStart = true;
|
||||||
|
ports = [
|
||||||
|
"80:80"
|
||||||
|
"443:443"
|
||||||
|
];
|
||||||
|
networks = [
|
||||||
|
"traefik"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
OIDC_AUTH_PROVIDER_URL = cfg.oidcAuthProviderUrl;
|
||||||
|
};
|
||||||
|
environmentFiles = lib.forEach cfg.dnsSecrets (secret: secret.path) ++ (lib.mapAttrsToList (oidcClientName: oidcClientConfig: oidcClientConfig.secret.path) cfg.oidcClients);
|
||||||
|
labels = {
|
||||||
|
"traefik.enable" = "true";
|
||||||
|
"traefik.http.routers.dashboard.rule" = "Host(`${cfg.dashboardUrl}`)";
|
||||||
|
"traefik.http.routers.dashboard.service" = "dashboard@internal";
|
||||||
|
"traefik.http.routers.dashboard.middlewares" = "traefik-dashboard-oidc-auth@file";
|
||||||
|
"traefik.http.routers.api.rule" = "Host(`${cfg.dashboardUrl}`) && (PathPrefix(`/api`) || PathPrefix(`/oidc/callback`))";
|
||||||
|
"traefik.http.routers.api.service" = "api@internal";
|
||||||
|
"traefik.http.routers.api.middlewares" = "traefik-dashboard-oidc-auth@file";
|
||||||
|
"traefik.http.middlewares.strip-mtls-headers.headers.customrequestheaders.X-Forwarded-Tls-Client-Cert" = "";
|
||||||
|
"traefik.http.middlewares.pass-tls-client-cert.passtlsclientcert.pem" = "true";
|
||||||
|
};
|
||||||
|
volumes = let
|
||||||
|
oidc-config = lib.mapAttrs' (
|
||||||
|
oidcClientName: oidcClientConfig:
|
||||||
|
lib.nameValuePair "${oidcClientName}-oidc-auth" {
|
||||||
|
plugin.traefik-oidc-auth = {
|
||||||
|
LogLevel = "INFO";
|
||||||
|
Secret = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_SECRET" }}'';
|
||||||
|
Provider = {
|
||||||
|
Url = ''{{ env "OIDC_AUTH_PROVIDER_URL" }}'';
|
||||||
|
ClientId = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_PROVIDER_CLIENT_ID" }}'';
|
||||||
|
ClientSecret = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_PROVIDER_CLIENT_SECRET" }}'';
|
||||||
|
UsePkce = oidcClientConfig.usePkce;
|
||||||
|
UseClaimsFromUserInfo = oidcClientConfig.useClaimsFromUserInfo;
|
||||||
|
};
|
||||||
|
Scopes = oidcClientConfig.scopes;
|
||||||
|
LoginUrl = ''{{ env "OIDC_AUTH_PROVIDER_URL" }}'';
|
||||||
|
} // (lib.attrsets.optionalAttrs oidcClientConfig.enableBypassUsingClientCertificate {
|
||||||
|
BypassAuthenticationRule = "HeaderRegexp(`X-Forwarded-Tls-Client-Cert`, `.+`)";
|
||||||
|
}) // (lib.attrsets.optionalAttrs ((lib.length oidcClientConfig.headers) > 0) {
|
||||||
|
Headers = oidcClientConfig.headers;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
) cfg.oidcClients;
|
||||||
|
traefik-oidc-authentication-config = (pkgs.formats.yaml {}).generate "traefik-oidc-auth" {
|
||||||
|
http.middlewares = oidc-config;
|
||||||
|
};
|
||||||
|
in [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
|
"${traefik-oidc-authentication-config}:/dynamic-config/traefik-oidc-auth.yaml:ro"
|
||||||
|
"${traefik-mtls-config}:/dynamic-config/traefik-mtls.yaml:ro"
|
||||||
|
"${cfg.mTLSCaCertSecret.path}:/caFiles/root_ca.crt:ro"
|
||||||
|
];
|
||||||
|
extraOptions = [
|
||||||
|
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
|
||||||
|
"--add-host=host.docker.internal:host-gateway"
|
||||||
|
"--health-cmd=wget --spider --quiet http://localhost:8080/ping"
|
||||||
|
"--health-interval=10s"
|
||||||
|
"--health-timeout=5s"
|
||||||
|
"--health-retries=3"
|
||||||
|
"--health-start-period=5s"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."docker-traefik" = {
|
||||||
|
after = [
|
||||||
|
"docker-network-traefik.service"
|
||||||
|
];
|
||||||
|
requires = [
|
||||||
|
"docker-network-traefik.service"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."docker-network-traefik" = {
|
||||||
|
path = [ pkgs.docker ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
docker network inspect traefik || docker network create traefik --ipv4 --ipv6 --subnet=172.18.0.0/16 --gateway=172.18.0.1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
networking.firewall.extraCommands = "iptables -t nat -I PREROUTING -s 172.18.0.0/16 -d 172.18.0.0/16 -j MASQUERADE";
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
@ -7,15 +7,7 @@
|
||||||
let
|
let
|
||||||
|
|
||||||
cfg = config.services.traefik-docker;
|
cfg = config.services.traefik-docker;
|
||||||
|
version = "3.6.14";
|
||||||
mapOidcClientNameToEnv = stringToReplace: lib.replaceString "-" "_" (lib.toUpper stringToReplace);
|
|
||||||
|
|
||||||
traefik-mtls-config = (pkgs.formats.yaml { }).generate "traefik-mtls-config" {
|
|
||||||
tls.options.default.clientAuth = {
|
|
||||||
caFiles = "caFiles/root_ca.crt";
|
|
||||||
clientAuthType = "VerifyClientCertIfGiven";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
in {
|
in {
|
||||||
|
|
||||||
|
|
@ -29,105 +21,40 @@ in {
|
||||||
description = "Secrets for DNS providers.";
|
description = "Secrets for DNS providers.";
|
||||||
type = lib.types.listOf lib.types.anything;
|
type = lib.types.listOf lib.types.anything;
|
||||||
};
|
};
|
||||||
mTLSCaCertSecret = lib.mkOption {
|
dnsChallengeProvider = lib.mkOption {
|
||||||
description = "Agenix secret containing the CA file to verify client certificates against.";
|
description = "Name of provider for DNS challenge.";
|
||||||
};
|
|
||||||
oidcAuthProviderUrl = lib.mkOption {
|
|
||||||
description = "Provider URL of OIDC auth provider.";
|
|
||||||
type = lib.types.str;
|
type = lib.types.str;
|
||||||
};
|
};
|
||||||
oidcClients = lib.mkOption {
|
|
||||||
example = ''
|
|
||||||
immich = {
|
|
||||||
scopes = [
|
|
||||||
"openid"
|
|
||||||
"email"
|
|
||||||
"profile"
|
|
||||||
];
|
|
||||||
enableBypassUsingClientCertificate = true;
|
|
||||||
usePkce = true;
|
|
||||||
};
|
|
||||||
'';
|
|
||||||
description = "Attribute set of OIDC clients with their configurations.";
|
|
||||||
type = lib.types.attrsOf (
|
|
||||||
lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
secret = lib.mkOption {
|
|
||||||
description = ''Agenix secret containing the following needed environment variables in dotenv notation:
|
|
||||||
- <clientName>_OIDC_AUTH_SECRET
|
|
||||||
- <clientName>_OIDC_AUTH_PROVIDER_CLIENT_ID
|
|
||||||
- <clientName>_OIDC_CLIENT_SECRET
|
|
||||||
'';
|
|
||||||
};
|
|
||||||
scopes = lib.mkOption {
|
|
||||||
default = [ "openid" ];
|
|
||||||
example = [ "openid" "email" "profile" "groups" ];
|
|
||||||
description = "OIDC scopes to request from auth provider.";
|
|
||||||
type = lib.types.listOf lib.types.str;
|
|
||||||
};
|
|
||||||
usePkce = lib.mkOption {
|
|
||||||
default = true;
|
|
||||||
description = "Whether to enable PKCE for this provider.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
};
|
|
||||||
enableBypassUsingClientCertificate = lib.mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "Whether to allow bypassing OIDC protection when a verified client certificate is presented.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
};
|
|
||||||
useClaimsFromUserInfo = lib.mkOption {
|
|
||||||
default = false;
|
|
||||||
description = "When enabled, an additional request to the provider's userinfo_endpoint is made to validate the token and to retrieve additional claims. The userinfo claims are merged directly into the token claims, with userinfo values overriding token values for non-security-critical claims.";
|
|
||||||
type = lib.types.bool;
|
|
||||||
};
|
|
||||||
headers = lib.mkOption {
|
|
||||||
default = [];
|
|
||||||
description = "Headers to be added to the upstream request. Templating is possible. Documentation can be found here: https://traefik-oidc-auth.sevensolutions.cc/docs/getting-started/middleware-configuration";
|
|
||||||
type = lib.types.listOf (lib.types.submodule {
|
|
||||||
options = {
|
|
||||||
Name = lib.mkOption {
|
|
||||||
description = "The name of the header which should be added to the upstream request.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
Value = lib.mkOption {
|
|
||||||
description = "The value of the header, which can use Go-Templates.";
|
|
||||||
type = lib.types.str;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
});
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
};
|
||||||
|
|
||||||
config = lib.mkIf cfg.enable {
|
config = lib.mkIf cfg.enable {
|
||||||
virtualisation.oci-containers.containers = {
|
virtualisation.oci-containers.containers = {
|
||||||
traefik = {
|
traefik = {
|
||||||
image = "traefik:v3.6.6";
|
image = "traefik:v${version}";
|
||||||
cmd = [
|
cmd = [
|
||||||
"--providers.docker=true"
|
"--providers.docker=true"
|
||||||
|
"--providers.docker.endpoint=http://docker-socket-proxy:2375"
|
||||||
"--providers.docker.exposedByDefault=false"
|
"--providers.docker.exposedByDefault=false"
|
||||||
"--providers.docker.network=traefik"
|
"--providers.docker.network=webproxy"
|
||||||
"--providers.file.directory=/dynamic-config"
|
"--providers.file.directory=/dynamic-config"
|
||||||
"--log.level=INFO"
|
"--log.level=INFO"
|
||||||
"--api=true"
|
"--api=true"
|
||||||
"--ping=true"
|
"--ping=true"
|
||||||
"--entrypoints.web.address=:80"
|
"--entrypoints.web.address=:80"
|
||||||
"--entrypoints.websecure.address=:443"
|
"--entrypoints.websecure.address=:443"
|
||||||
"--entrypoints.websecure.transport.respondingTimeouts.readTimeout=600s"
|
"--entrypoints.websecure.transport.respondingTimeouts.readTimeout=0"
|
||||||
"--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=600s"
|
"--entrypoints.websecure.transport.respondingTimeouts.idleTimeout=0"
|
||||||
"--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=600s"
|
"--entrypoints.websecure.transport.respondingTimeouts.writeTimeout=0"
|
||||||
|
"--serverstransport.forwardingtimeouts.responseheadertimeout=0s"
|
||||||
|
"--serverstransport.forwardingtimeouts.idleconntimeout=0s"
|
||||||
"--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
"--entrypoints.web.http.redirections.entrypoint.to=websecure"
|
||||||
"--entrypoints.websecure.asDefault=true"
|
"--entrypoints.websecure.asDefault=true"
|
||||||
"--entrypoints.websecure.http.middlewares=strip-mtls-headers@docker,pass-tls-client-cert@docker"
|
|
||||||
"--entrypoints.websecure.http.tls.certresolver=letsencrypt"
|
"--entrypoints.websecure.http.tls.certresolver=letsencrypt"
|
||||||
|
"--certificatesresolvers.letsencrypt.acme.email=contact@jfreudenberger.de"
|
||||||
"--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
|
"--certificatesresolvers.letsencrypt.acme.storage=/certs/acme.json"
|
||||||
"--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
|
"--certificatesresolvers.letsencrypt.acme.dnschallenge=true"
|
||||||
"--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=netcup"
|
"--certificatesresolvers.letsencrypt.acme.dnschallenge.provider=${cfg.dnsChallengeProvider}"
|
||||||
"--experimental.plugins.traefik-oidc-auth.modulename=github.com/sevensolutions/traefik-oidc-auth"
|
"--providers.file.filename=/dynamic-config/providers.yaml"
|
||||||
"--experimental.plugins.traefik-oidc-auth.version=v0.17.0"
|
|
||||||
];
|
];
|
||||||
autoStart = true;
|
autoStart = true;
|
||||||
ports = [
|
ports = [
|
||||||
|
|
@ -135,54 +62,17 @@ in {
|
||||||
"443:443"
|
"443:443"
|
||||||
];
|
];
|
||||||
networks = [
|
networks = [
|
||||||
"traefik"
|
"webproxy"
|
||||||
|
"docker-socket"
|
||||||
];
|
];
|
||||||
environment = {
|
environmentFiles = lib.forEach cfg.dnsSecrets (secret: secret.path);
|
||||||
OIDC_AUTH_PROVIDER_URL = cfg.oidcAuthProviderUrl;
|
|
||||||
};
|
|
||||||
environmentFiles = lib.forEach cfg.dnsSecrets (secret: secret.path) ++ (lib.mapAttrsToList (oidcClientName: oidcClientConfig: oidcClientConfig.secret.path) cfg.oidcClients);
|
|
||||||
labels = {
|
|
||||||
"traefik.enable" = "true";
|
|
||||||
"traefik.http.routers.dashboard.rule" = "Host(`${cfg.dashboardUrl}`)";
|
|
||||||
"traefik.http.routers.dashboard.service" = "dashboard@internal";
|
|
||||||
"traefik.http.routers.dashboard.middlewares" = "traefik-dashboard-oidc-auth@file";
|
|
||||||
"traefik.http.routers.api.rule" = "Host(`${cfg.dashboardUrl}`) && (PathPrefix(`/api`) || PathPrefix(`/oidc/callback`))";
|
|
||||||
"traefik.http.routers.api.service" = "api@internal";
|
|
||||||
"traefik.http.routers.api.middlewares" = "traefik-dashboard-oidc-auth@file";
|
|
||||||
"traefik.http.middlewares.strip-mtls-headers.headers.customrequestheaders.X-Forwarded-Tls-Client-Cert" = "";
|
|
||||||
"traefik.http.middlewares.pass-tls-client-cert.passtlsclientcert.pem" = "true";
|
|
||||||
};
|
|
||||||
volumes = let
|
volumes = let
|
||||||
oidc-config = lib.mapAttrs' (
|
traefik-providers-config = (pkgs.formats.yaml {}).generate "traefik-providers-config" {
|
||||||
oidcClientName: oidcClientConfig:
|
tcp.serversTransports.pp-v2.proxyProtocol.version = 2;
|
||||||
lib.nameValuePair "${oidcClientName}-oidc-auth" {
|
|
||||||
plugin.traefik-oidc-auth = {
|
|
||||||
LogLevel = "INFO";
|
|
||||||
Secret = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_SECRET" }}'';
|
|
||||||
Provider = {
|
|
||||||
Url = ''{{ env "OIDC_AUTH_PROVIDER_URL" }}'';
|
|
||||||
ClientId = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_PROVIDER_CLIENT_ID" }}'';
|
|
||||||
ClientSecret = ''{{ env "${mapOidcClientNameToEnv oidcClientName}_OIDC_AUTH_PROVIDER_CLIENT_SECRET" }}'';
|
|
||||||
UsePkce = oidcClientConfig.usePkce;
|
|
||||||
UseClaimsFromUserInfo = oidcClientConfig.useClaimsFromUserInfo;
|
|
||||||
};
|
|
||||||
Scopes = oidcClientConfig.scopes;
|
|
||||||
LoginUrl = ''{{ env "OIDC_AUTH_PROVIDER_URL" }}'';
|
|
||||||
} // (lib.attrsets.optionalAttrs oidcClientConfig.enableBypassUsingClientCertificate {
|
|
||||||
BypassAuthenticationRule = "HeaderRegexp(`X-Forwarded-Tls-Client-Cert`, `.+`)";
|
|
||||||
}) // (lib.attrsets.optionalAttrs ((lib.length oidcClientConfig.headers) > 0) {
|
|
||||||
Headers = oidcClientConfig.headers;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
) cfg.oidcClients;
|
|
||||||
traefik-oidc-authentication-config = (pkgs.formats.yaml {}).generate "traefik-oidc-auth" {
|
|
||||||
http.middlewares = oidc-config;
|
|
||||||
};
|
};
|
||||||
in [
|
in [
|
||||||
"/var/run/docker.sock:/var/run/docker.sock"
|
"/var/run/docker.sock:/var/run/docker.sock"
|
||||||
"${traefik-oidc-authentication-config}:/dynamic-config/traefik-oidc-auth.yaml:ro"
|
"${traefik-providers-config}:/dynamic-config/providers.yaml:ro"
|
||||||
"${traefik-mtls-config}:/dynamic-config/traefik-mtls.yaml:ro"
|
|
||||||
"${cfg.mTLSCaCertSecret.path}:/caFiles/root_ca.crt:ro"
|
|
||||||
];
|
];
|
||||||
extraOptions = [
|
extraOptions = [
|
||||||
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
|
''--mount=type=volume,source=certs,target=/certs,volume-driver=local''
|
||||||
|
|
@ -194,24 +84,49 @@ in {
|
||||||
"--health-start-period=5s"
|
"--health-start-period=5s"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
docker-socket-proxy = {
|
||||||
|
image = "tecnativa/docker-socket-proxy:v0.4.2";
|
||||||
|
autoStart = true;
|
||||||
|
networks = [
|
||||||
|
"docker-socket"
|
||||||
|
];
|
||||||
|
environment = {
|
||||||
|
CONTAINERS = "1";
|
||||||
|
};
|
||||||
|
volumes = [
|
||||||
|
"/var/run/docker.sock:/var/run/docker.sock:ro"
|
||||||
|
];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services."docker-traefik" = {
|
systemd.services."docker-traefik" = {
|
||||||
after = [
|
after = [
|
||||||
"docker-network-traefik.service"
|
"docker-network-webproxy.service"
|
||||||
|
"docker-network-docker-socket.service"
|
||||||
];
|
];
|
||||||
requires = [
|
requires = [
|
||||||
"docker-network-traefik.service"
|
"docker-network-webproxy.service"
|
||||||
|
"docker-network-docker-socket.service"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
systemd.services."docker-network-traefik" = {
|
systemd.services."docker-network-webproxy" = {
|
||||||
path = [ pkgs.docker ];
|
path = [ pkgs.docker ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
};
|
};
|
||||||
script = ''
|
script = ''
|
||||||
docker network inspect traefik || docker network create traefik --ipv4 --ipv6 --subnet=172.18.0.0/16 --gateway=172.18.0.1
|
docker network inspect webproxy || docker network create webproxy --ipv4 --ipv6 --subnet=172.18.0.0/16 --gateway=172.18.0.1
|
||||||
|
'';
|
||||||
|
};
|
||||||
|
|
||||||
|
systemd.services."docker-network-docker-socket" = {
|
||||||
|
path = [ pkgs.docker ];
|
||||||
|
serviceConfig = {
|
||||||
|
Type = "oneshot";
|
||||||
|
};
|
||||||
|
script = ''
|
||||||
|
docker network inspect docker-socket || docker network create docker-socket --ipv4 --ipv6 --subnet=172.19.0.0/16 --gateway=172.19.0.1
|
||||||
'';
|
'';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue