begin great docker migration

This commit is contained in:
2026-01-30 00:08:37 -06:00
parent 4bccbb92f4
commit 2f4419eb59
15 changed files with 151 additions and 365 deletions

View File

@@ -91,7 +91,6 @@
nextcloud.enable = true;
ntfy.enable = false;
gitea.enable = true;
keycloak.enable = true;
netbird.enable = true;
openwebui.enable = true;

View File

@@ -0,0 +1,26 @@
{ config, lib, nixpkgs-us, ... }: {
options.sysconfig = {
services.netbird.enable = lib.options.mkOption {
type = lib.types.bool;
default = false;
};
};
config = let
pkgs-us = import nixpkgs-us {
system = "x86_64-linux";
};
in lib.mkIf config.sysconfig.services.netbird.enable {
services.netbird = {
enable = config.sysconfig.services.netbird.enable;
ui = {
enable = true;
package = pkgs-us.netbird-ui;
};
package = pkgs-us.netbird;
};
};
}

View File

@@ -1,73 +0,0 @@
{ config, lib, ... }: {
options.sysconfig.containers.keycloak.enable = lib.options.mkOption {
type = lib.types.bool;
default = false;
};
config = lib.mkIf config.sysconfig.containers.keycloak.enable {
sops.secrets."keycloak/dbpass" = {};
containers.keycloak = {
autoStart = true;
privateNetwork = true;
hostAddress = "192.168.100.10";
localAddress = "192.168.100.22";
extraFlags = [
"--load-credential=dbpass:${config.sops.secrets."keycloak/dbpass".path}"
];
bindMounts = {
"/etc/keycloak" = {
hostPath = "/ssd1/Keycloak";
isReadOnly = false;
};
};
config = {
networking.firewall.allowedTCPPorts = [ 80 ];
systemd.services.secrets_setup = {
wantedBy = [ "keycloak.service" ];
serviceConfig = {
LoadCredential = [
"dbpass"
];
};
script = ''
cat ''${CREDENTIALS_DIRECTORY}/dbpass > /etc/keycloak/dbpass
chown postgres:postgres /etc/keycloak/dbpass
'';
};
services.keycloak = {
enable = true;
database.passwordFile = "/etc/keycloak/dbpass";
settings = {
hostname = "auth.esotericbytes.com";
http-enabled = true;
proxy-headers = "xforwarded";
proxy-trusted-addresses = "192.168.100.11";
};
initialAdminPassword = "7567";
};
system.stateVersion = "25.05";
};
};
};
}

View File

@@ -1,265 +0,0 @@
{ config, lib, nixpkgs-us, ... }: {
options.sysconfig = {
services.netbird.enable = lib.options.mkOption {
type = lib.types.bool;
default = false;
};
containers.netbird = {
enable = lib.options.mkOption {
type = lib.types.bool;
default = false;
};
};
};
config = let
pkgs-us = import nixpkgs-us {
system = "x86_64-linux";
config.allowUnfree = true;
};
in {
services.netbird = {
enable = config.sysconfig.services.netbird.enable;
ui = {
enable = true;
#package = pkgs-us.netbird-ui;
};
#package = pkgs-us.netbird;
};
networking = {
firewall = lib.mkIf config.sysconfig.containers.netbird.enable {
allowedUDPPorts = [ 3478 ];
allowedUDPPortRanges = [{ from = 51100; to = 56100; }];
interfaces."ve-netbird" = {
allowedTCPPorts = [ 53 ];
allowedUDPPorts = [ 53 ];
};
};
nat.internalInterfaces = [ "ve-netbird" "wt0" ];
};
sops.secrets."netbird/coturnPass" = lib.mkIf config.sysconfig.containers.netbird.enable {};
containers.netbird = lib.mkIf config.sysconfig.containers.netbird.enable {
autoStart = true;
privateNetwork = true;
hostAddress = "192.168.100.10";
localAddress = "192.168.100.23";
forwardPorts = [
{
hostPort = 3478;
containerPort = 3478;
protocol = "udp";
}
] ++ map (x: { hostPort = x; containerPort = x; protocol = "udp"; }) (builtins.genList (y: 51100 + y) (56100 - 51100));
extraFlags = [
"--load-credential=coturnPass:${config.sops.secrets."netbird/coturnPass".path}"
];
config = {
services.nginx.virtualHosts."vpn.esotericbytes.com" = {
listen = [
{
addr = "0.0.0.0";
port = 80;
ssl = false;
}
];
};
environment.etc."resolv.conf" = {
enable = true;
text = ''
nameserver 1.1.1.1
nameserver 1.0.0.1
options edns0
'';
user = "root";
mode = "0664";
};
services.netbird = {
server = {
enable = true;
enableNginx = true;
domain = "vpn.esotericbytes.com";
dashboard = {
enable = true;
enableNginx = true;
settings = {
AUTH_AUTHORITY = "https://auth.esotericbytes.com/realms/General";
AUTH_CLIENT_ID = "netbird";
AUTH_SUPPORTED_SCOPES = "openid profile email offline_access api";
AUTH_AUDIENCE = "netbird";
USE_AUTH0 = false;
NETBIRD_TOKEN_SOURCE = "accessToken";
};
package = pkgs-us.netbird-dashboard;
};
management = {
enable = true;
enableNginx = true;
disableAnonymousMetrics = true;
dnsDomain = "vpn";
turnDomain = "vpn.esotericbytes.com";
turnPort = 3478;
logLevel = "DEBUG";
oidcConfigEndpoint = "https://auth.esotericbytes.com/realms/General/.well-known/openid-configuration";
settings = {
"TURNConfig" = {
"Turns" = [
{
"Proto" = "udp";
"URI" = "turn:vpn.esotericbytes.com:3478";
"Username" = "netbird";
"Password"._secret = "/etc/netbird/coturnPass";
}
];
"Secret"._secret = "/etc/netbird/coturnPass";
};
"DataStoreEncryptionKey" = null;
"HttpConfig" = {
"Address" = "0.0.0.0:443";
"AuthIssuer" = "https://auth.esotericbytes.com/realms/General";
"AuthAudience" = "netbird";
"AuthKeysLocation" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/certs";
"AuthUserIDClaim" = "";
"CertFile" = "";
"CertKey" = "";
"IdpSignKeyRefreshEnabled" = false;
"OIDCConfigEndpoint" = "https://auth.esotericbytes.com/realms/General/.well-known/openid-configuration";
};
"DeviceAuthorizationFlow" = {
"Provider" = "none";
"ProviderConfig" = {
"Audience" = "netbird";
"AuthorizationEndpoint" = "";
"Domain" = "";
"ClientID" = "";
"ClientSecret" = "";
"TokenEndpoint" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/token";
"DeviceAuthEndpoint" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/auth/device";
"Scope" = "openid";
"UseIDToken" = false;
"RedirectURLs" = null;
};
};
"IdpManagerConfig" = {
"ManagerType" = "keycloak";
"ClientConfig" = {
"Issuer" = "https://auth.esotericbytes.com/realms/General";
"TokenEndpoint" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/token";
"ClientID" = "netbird-backend";
"ClientSecret" = "QuqjTOAHKE6N6jJqkB1F1RGo3kqUhEdg";
"GrantType" = "client_credentials";
};
"ExtraConfig" = {
"AdminEndpoint" = "https://auth.esotericbytes.com/admin/realms/General";
};
"Auth0ClientCredentials" = null;
"AzureClientCredentials" = null;
"KeycloakClientCredentials" = null;
"ZitadelClientCredentials" = null;
};
"PKCEAuthorizationFlow" = {
"ProviderConfig" = {
"Audience" = "netbird";
"ClientID" = "netbird";
"ClientSecret" = "";
"Domain" = "";
"AuthorizationEndpoint" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/auth";
"TokenEndpoint" = "https://auth.esotericbytes.com/realms/General/protocol/openid-connect/token";
"Scope" = "openid profile email offline_access api";
"RedirectURLs" = [
"http://localhost:53000"
];
"UseIDToken" = false;
"DisablePromptLogin" = false;
};
};
};
port = 443;
};
coturn = {
enable = true;
user = "netbird";
passwordFile = "/etc/netbird/coturnPass";
openPorts = map (x: x) (builtins.genList (y: 51100 + y) (56100 - 51100));
};
signal = {
enable = true;
enableNginx = true;
};
};
};
systemd.services.secrets_setup = {
wantedBy = [ "netbird-management.service" "coturn.service" ];
serviceConfig = {
LoadCredential = [
"coturnPass"
];
};
script = ''
if [[ ! -f /etc/netbird/coturnPass ]]; then
cat ''${CREDENTIALS_DIRECTORY}/coturnPass > /etc/netbird/coturnPass
fi
'';
};
networking.firewall = {
allowedTCPPorts = [ 80 ];
allowedUDPPorts = [ 3478 ];
allowedUDPPortRanges = [{ from = 51100; to = 56100; }];
};
system.stateVersion = "25.05";
};
};
};
}

View File

@@ -192,12 +192,6 @@
tls.certResolver = "cloudflare";
};
auth = {
entryPoints = [ "websecure" "localsecure" ];
rule = "Host(`auth.esotericbytes.com`)";
service = "keycloak";
tls.certResolver = "cloudflare";
};
/*gitlab = {
entryPoints = [ "websecure" ];
rule = "Host(`gitlab.esotericbytes.com`)";
@@ -233,13 +227,6 @@
tls.certResolver = "cloudflare";
};*/
netbird = {
entryPoints = [ "websecure" "localsecure" ];
rule = "Host(`vpn.esotericbytes.com`)";
service = "netbird";
tls.certResolver = "cloudflare";
};
openwebui = {
entryPoints = [ "localsecure" ];
rule = "Host(`ai.esotericbytes.com`)";
@@ -273,19 +260,12 @@
jellyfin.loadBalancer.servers = [ { url = "http://192.168.100.14:8096"; } ];
keycloak.loadBalancer.servers = [ { url = "http://192.168.100.22:80"; } ];
#novnc.loadBalancer.servers = [ { url = "http://192.168.100.10:6080"; } ];
nextcloud.loadBalancer.servers = [ { url = "http://192.168.100.15:80"; } ];
#ntfy.loadBalancer.servers = [ { url = "http://192.168.100.19"; } ];
netbird.loadBalancer = {
passHostHeader = true;
servers = [ { url = "http://192.168.100.23:80"; } ];
};
openwebui.loadBalancer.servers = [ { url = "http://192.168.100.33:8080"; } ];
code-server.loadBalancer.servers = [ { url = "http://192.168.100.31:4444"; } ];

View File

@@ -2,7 +2,7 @@
hostPort = 9005;
subdomain = "auth2";
subdomain = "auth";
name = "authentik";
@@ -33,9 +33,6 @@ in {
'';
};
######################################################################################
# Containers
virtualisation.oci-containers.containers."authentik-postgresql" = {
image = "docker.io/library/postgres:16-alpine";
environment = {
@@ -91,7 +88,7 @@ in {
};
environmentFiles = [ config.sops.templates."authentik.env".path ];
labels = {
"traefik.http.routers.${name}.entrypoints" = "localsecure";
"traefik.http.routers.${name}.entrypoints" = "websecure,localsecure";
"traefik.http.routers.${name}.rule" = "Host(`${subdomain}.esotericbytes.com`)";
"traefik.http.routers.${name}.service" = "${name}";
"traefik.http.routers.${name}.tls.certResolver" = "cloudflare";
@@ -212,7 +209,7 @@ in {
RemainAfterExit = true;
};
script = ''
docker volume inspect authentik_database || docker volume create authentik_database --driver=local
docker volume inspect authentik_database || docker volume create authentik_database --driver=btrfs
'';
partOf = [ "docker-compose-authentik-root.target" ];
wantedBy = [ "docker-compose-authentik-root.target" ];

View File

@@ -0,0 +1,36 @@
{ config, lib, pkgs, ... }: let
hostPort = 9006;
subdomain = "vpn";
name = "netbird";
in {
options.sysconfig.docker.netbird.enable = with lib; mkOption {
type = with types; bool;
default = false;
};
config = lib.mkIf (config.sysconfig.docker.netbird.enable && config.sysconfig.docker.enable) {
networking.firewall.interfaces = {
"ve-traefik" = {
allowedTCPPorts = [ hostPort ];
};
};
sops.secrets = {
"netbird/pass" = {};
"netbird/secret_key" = {};
};
sops.templates."netbird.env" = {
content = ''
PG_PASS=${config.sops.placeholder."netbird/pass"}
SECRET_KEY=${config.sops.placeholder."netbird/secret_key"}
'';
};
};
}

View File

@@ -0,0 +1,86 @@
{ config, lib, pkgs, ... }: {
options.sysconfig.docker.traefik.enable = with lib; mkOption {
type = with types; bool;
default = false;
};
config = lib.mkIf (config.sysconfig.docker.traefik.enable && config.sysconfig.docker.enable) {
sops.secrets = {
"traefik/cf_email" = {};
"traefik/cf_api_key" = {};
};
sops.templates."traefik.env" = {
content = ''
CF_API_EMAIL=${config.sops.placeholder."traefik/cf_email"}
CF_DNS_API_TOKEN=${config.sops.placeholder."traefik/cf_api_key"}
'';
};
virtualisation.oci-containers.containers.traefik = {
image = "traefik:3.6";
environment = {
};
environmentFiles = [ config.sops.templates."traefik.env".path ];
volumes = [
"vol_traefik:/etc/traefik/data"
"/run/docker.sock:/var/run/docker.sock"
];
networks = [
"docker-main"
];
log-driver = "journald";
};
systemd.services."docker-traefik" = {
serviceConfig = {
Restart = lib.mkOverride 90 "always";
RestartMaxDelaySec = lib.mkOverride 90 "1m";
RestartSec = lib.mkOverride 90 "100ms";
RestartSteps = lib.mkOverride 90 9;
};
after = [
"docker-network-authentik_default.service"
"docker-volume-vol_traefik.service"
];
requires = [
"docker-network-authentik_default.service"
"docker-volume-vol_traefik.service"
];
partOf = [
"docker-compose-traefik-root.target"
];
wantedBy = [
"docker-compose-traefik-root.target"
];
};
# Volumes
systemd.services."docker-volume-vol_traefik" = {
path = [ pkgs.docker ];
serviceConfig = {
Type = "oneshot";
RemainAfterExit = true;
};
script = ''
docker volume inspect vol_traefik || docker volume create vol_traefik --driver=btrfs
'';
partOf = [ "docker-compose-traefik-root.target" ];
wantedBy = [ "docker-compose-traefik-root.target" ];
};
# 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-traefik-root" = {
wantedBy = [ "multi-user.target" ];
};
};
}