Compare commits
13 Commits
8c800ad0d3
...
7cfd1bb245
| Author | SHA1 | Date | |
|---|---|---|---|
| 7cfd1bb245 | |||
| 85a6517609 | |||
| d55756f8f8 | |||
| 18beb41cd8 | |||
| 78f01cf111 | |||
| c582d89715 | |||
| 4270b15f9d | |||
| a62bc660c5 | |||
| 973fd78c1b | |||
| 7e62883e66 | |||
| feccc2c3e0 | |||
| 0b02de0957 | |||
| 721838df2b |
@@ -15,6 +15,8 @@ let
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
|
sops = false;
|
||||||
|
db = false;
|
||||||
paths = [{
|
paths = [{
|
||||||
path="${serverCfg.configPath}/example/";
|
path="${serverCfg.configPath}/example/";
|
||||||
mode = "0444";
|
mode = "0444";
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ let
|
|||||||
NEXTCLOUD_DOMAIN = "${serverCfg.containers.nextcloud.subdomain or "nextcloud"}.${serverCfg.hostDomain}";
|
NEXTCLOUD_DOMAIN = "${serverCfg.containers.nextcloud.subdomain or "nextcloud"}.${serverCfg.hostDomain}";
|
||||||
AUTHENTIK_DOMAIN = "${containerCfg.subdomain}.${serverCfg.hostDomain}";
|
AUTHENTIK_DOMAIN = "${containerCfg.subdomain}.${serverCfg.hostDomain}";
|
||||||
COOKIE_DOMAIN = "${serverCfg.hostDomain}";
|
COOKIE_DOMAIN = "${serverCfg.hostDomain}";
|
||||||
|
AUTHENTIK_LDAP_DC_DOMAIN = "dc=ldap," + (lib.concatMapStringsSep "," (x: "dc=${x}") (lib.splitString "." serverCfg.hostDomain));
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
in {
|
in {
|
||||||
@@ -29,19 +30,20 @@ in {
|
|||||||
port = 9000;
|
port = 9000;
|
||||||
secret = name;
|
secret = name;
|
||||||
extraEnv = {
|
extraEnv = {
|
||||||
"AUTHENTIK_REDIS__HOST" = builder.host;
|
AUTHENTIK_REDIS__HOST = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__HOST" = builder.host;
|
AUTHENTIK_POSTGRESQL__HOST = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__USER" = "authentik_user";
|
AUTHENTIK_POSTGRESQL__USER = "authentik_user";
|
||||||
"AUTHENTIK_POSTGRESQL__NAME" = "authentik_db";
|
AUTHENTIK_POSTGRESQL__NAME = "authentik_db";
|
||||||
"AUTHENTIK_EMAIL__HOST" = serverCfg.mailDomain;
|
AUTHENTIK_POSAUTHENTIK_POSTGRESQL__SSLMODE = "false";
|
||||||
"AUTHENTIK_EMAIL__PORT" = "587";
|
AUTHENTIK_EMAIL__HOST = serverCfg.mailDomain;
|
||||||
"AUTHENTIK_EMAIL__USERNAME" = "noreply@${serverCfg.hostDomain}";
|
AUTHENTIK_EMAIL__PORT = "587";
|
||||||
"AUTHENTIK_EMAIL__USE_TLS" = "true";
|
AUTHENTIK_EMAIL__USERNAME = "noreply@${serverCfg.hostDomain}";
|
||||||
"AUTHENTIK_EMAIL__USE_SSL" = "false";
|
AUTHENTIK_EMAIL__USE_TLS = "true";
|
||||||
"AUTHENTIK_EMAIL__TIMEOUT" = "10";
|
AUTHENTIK_EMAIL__USE_SSL = "false";
|
||||||
"AUTHENTIK_EMAIL__FROM" = "sso@noreply.${serverCfg.hostDomain}";
|
AUTHENTIK_EMAIL__TIMEOUT = "10";
|
||||||
"AUTHENTIK_DISABLE_UPDATE_CHECK" = "true";
|
AUTHENTIK_EMAIL__FROM = "sso@noreply.${serverCfg.hostDomain}";
|
||||||
"AUTHENTIK_POSTGRESQL__SSLMODE" = "disable";
|
AUTHENTIK_DISABLE_UPDATE_CHECK = "true";
|
||||||
|
AUTHENTIK_POSTGRESQL__SSLMODE = "disable";
|
||||||
};
|
};
|
||||||
overrides = {
|
overrides = {
|
||||||
cmd = [ "server" ];
|
cmd = [ "server" ];
|
||||||
@@ -58,12 +60,13 @@ in {
|
|||||||
image = "ghcr.io/goauthentik/server:${version}";
|
image = "ghcr.io/goauthentik/server:${version}";
|
||||||
secret = "authentik";
|
secret = "authentik";
|
||||||
extraEnv = {
|
extraEnv = {
|
||||||
"AUTHENTIK_REDIS__HOST" = builder.host;
|
AUTHENTIK_REDIS__HOST = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__HOST" = builder.host;
|
AUTHENTIK_POSTGRESQL__HOST = builder.host;
|
||||||
"AUTHENTIK_POSTGRESQL__USER" = "authentik_user";
|
AUTHENTIK_POSTGRESQL__USER = "authentik_user";
|
||||||
"AUTHENTIK_POSTGRESQL__NAME" = "authentik_db";
|
AUTHENTIK_POSTGRESQL__NAME = "authentik_db";
|
||||||
"AUTHENTIK_DISABLE_UPDATE_CHECK" = "true";
|
AUTHENTIK_POSAUTHENTIK_POSTGRESQL__SSLMODE = "false";
|
||||||
"AUTHENTIK_POSTGRESQL__SSLMODE" = "disable";
|
AUTHENTIK_DISABLE_UPDATE_CHECK = "true";
|
||||||
|
AUTHENTIK_POSTGRESQL__SSLMODE = "disable";
|
||||||
};
|
};
|
||||||
overrides = {
|
overrides = {
|
||||||
cmd = [ "worker" ];
|
cmd = [ "worker" ];
|
||||||
@@ -74,8 +77,20 @@ in {
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
|
||||||
|
|
||||||
|
ldap = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
image = "ghcr.io/goauthentik/ldap:${version}";
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
"AUTHENTIK_HOST" = "http://${builder.host}:9000";
|
||||||
|
"AUTHENTIK_INSECURE" = "false";
|
||||||
|
};
|
||||||
|
overrides = {
|
||||||
|
ports = [ "389:3389" "636:6636" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
setup = {
|
setup = {
|
||||||
trigger = "worker";
|
trigger = "worker";
|
||||||
@@ -85,6 +100,7 @@ in {
|
|||||||
|
|
||||||
$AK apply_blueprint /blueprints/custom/authentik.yaml
|
$AK apply_blueprint /blueprints/custom/authentik.yaml
|
||||||
$AK apply_blueprint /blueprints/custom/traefik.yaml
|
$AK apply_blueprint /blueprints/custom/traefik.yaml
|
||||||
|
$AK apply_blueprint /blueprints/custom/ldap.yaml
|
||||||
${lib.optionalString (serverCfg.containers ? nextcloud) ''$AK apply_blueprint /blueprints/custom/nextcloud.yaml''}
|
${lib.optionalString (serverCfg.containers ? nextcloud) ''$AK apply_blueprint /blueprints/custom/nextcloud.yaml''}
|
||||||
|
|
||||||
echo "Completed Authentik Setup"
|
echo "Completed Authentik Setup"
|
||||||
|
|||||||
@@ -1,3 +1,95 @@
|
|||||||
{...}:{
|
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
||||||
|
let
|
||||||
|
serverCfg = config.syscfg.server;
|
||||||
|
|
||||||
|
# Ensure the package is available (Nixpkgs includes frigate)
|
||||||
|
frigatePkg = pkgs.frigate;
|
||||||
|
|
||||||
|
image = pkgs.dockerTools.streamLayeredImage {
|
||||||
|
name = "frigate";
|
||||||
|
tag = frigatePkg.version;
|
||||||
|
contents = [
|
||||||
|
pkgs.bashInteractive
|
||||||
|
frigatePkg
|
||||||
|
pkgs.ffmpeg # Explicitly included for video stream processing
|
||||||
|
];
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "${frigatePkg}/bin/frigate" ];
|
||||||
|
Cmd = [ "start" ];
|
||||||
|
ExposedPorts = {
|
||||||
|
"5000/tcp" = {}; # Web UI / API
|
||||||
|
"8554/tcp" = {}; # RTSP Feeds
|
||||||
|
"8555/tcp" = {}; # WebRTC
|
||||||
|
};
|
||||||
|
Env = [
|
||||||
|
"FRIGATE_RTSP_PASSWORD=secret" # Base fallback, overridden by envFile/sops
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
sops = true; # Enabled to safeguard sensitive camera RTSP stream credentials
|
||||||
|
db = false; # Internal SQLite is used by default in Frigate
|
||||||
|
|
||||||
|
paths = [
|
||||||
|
{
|
||||||
|
path = "${serverCfg.configPath}/frigate/";
|
||||||
|
mode = "0755";
|
||||||
|
}
|
||||||
|
{
|
||||||
|
path = "/var/lib/frigate/storage/";
|
||||||
|
mode = "0755"; # Dedicated path for heavy video recordings and media
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
server = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
imageStream = image;
|
||||||
|
port = 5000;
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
PLUS_API_KEY = ""; # Optional: For Frigate Plus users
|
||||||
|
};
|
||||||
|
overrides = {
|
||||||
|
cmd = [ ];
|
||||||
|
volumes = [
|
||||||
|
"${serverCfg.configPath}/frigate:/config"
|
||||||
|
"/var/lib/frigate/storage:/media/frigate"
|
||||||
|
"/dev/bus/usb:/dev/bus/usb" # Passes Google Coral USB TPU to the container
|
||||||
|
"/dev/dri:/dev/dri" # Passes Intel/AMD GPU for hardware video decoding
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
setup = {
|
||||||
|
trigger = "server";
|
||||||
|
envFile = config.sops.secrets."FRIGATE_ENV".path;
|
||||||
|
script = pkgs.writeShellScript "setup-frigate" ''
|
||||||
|
mkdir -p "${serverCfg.configPath}/frigate"
|
||||||
|
mkdir -p "/var/lib/frigate/storage"
|
||||||
|
|
||||||
|
# Bootstrap a standard configuration layout if missing
|
||||||
|
if [ ! -f "${serverCfg.configPath}/frigate/config.yml" ]; then
|
||||||
|
cat <<EOF > "${serverCfg.configPath}/frigate/config.yml"
|
||||||
|
mqtt:
|
||||||
|
enabled: False # Set to True and define host if connecting to Home Assistant
|
||||||
|
|
||||||
|
database:
|
||||||
|
path: /config/frigate.db
|
||||||
|
|
||||||
|
cameras:
|
||||||
|
dummy_camera: # Replace with your actual RTSP stream details
|
||||||
|
enabled: false
|
||||||
|
ffmpeg:
|
||||||
|
inputs:
|
||||||
|
- path: rtsp://127.0.0.1:554/live
|
||||||
|
roles:
|
||||||
|
- detect
|
||||||
|
detect:
|
||||||
|
enabled: false
|
||||||
|
EOF
|
||||||
|
fi
|
||||||
|
'';
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,43 @@
|
|||||||
{...}:{
|
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
||||||
|
let
|
||||||
|
serverCfg = config.syscfg.server;
|
||||||
|
image = pkgs.dockerTools.streamLayeredImage {
|
||||||
|
name = pkgs.home-assistant.name;
|
||||||
|
tag = pkgs.home-assistant.version;
|
||||||
|
contents = [ ];
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "${pkgs.home-assistant}/bin/hass" ];
|
||||||
|
ExposedPorts = {
|
||||||
|
"8123/tcp" = {};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
sops = true;
|
||||||
|
db = false;
|
||||||
|
|
||||||
|
paths = [{
|
||||||
|
path = "${serverCfg.configPath}/homeassistant/";
|
||||||
|
mode = "0755";
|
||||||
|
}];
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
server = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
imageStream = image;
|
||||||
|
port = 8123;
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
TZ = config.time.timeZone or "UTC";
|
||||||
|
};
|
||||||
|
overrides = {
|
||||||
|
cmd = [ "--config" "/config" ];
|
||||||
|
volumes = [
|
||||||
|
"${serverCfg.configPath}/homeassistant/:/config"
|
||||||
|
"/run/dbus:/run/dbus:ro" # Required for Bluetooth/mDNS service discovery
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,3 +1,57 @@
|
|||||||
{...}:{
|
{ config, containerCfg, pkgs, lib, builder, name,... }:
|
||||||
|
let
|
||||||
|
serverCfg = config.syscfg.server;
|
||||||
|
|
||||||
|
immichServerImage = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "ghcr.io/immich-app/immich-server";
|
||||||
|
imageDigest = "sha256:d5cb251d7c3bcbb8e5bb974c8de53f3e1f0efcb71e21bde1b66df872a0a2df3d";
|
||||||
|
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||||
|
};
|
||||||
|
immichMachineLearningImage = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "ghcr.io/immich-app/immich-machine-learning";
|
||||||
|
imageDigest = "sha256:4a25fdcd11c13bc33e8b4e7eef118bc23dbd4df012012ec6d7fb1eeef872ad4d";
|
||||||
|
sha256 = "0000000000000000000000000000000000000000000000000000";
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
sops = false;
|
||||||
|
db = true;
|
||||||
|
|
||||||
|
paths = [{
|
||||||
|
path = "${serverCfg.configPath}/immich/cache";
|
||||||
|
mode = "0750";
|
||||||
|
}{
|
||||||
|
path = "${serverCfg.dataPath}/immich/";
|
||||||
|
mode = "0750";
|
||||||
|
}];
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
server = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
imageStream = immichServerImage;
|
||||||
|
port = 2283;
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
DB_URL = "postgresql://immich_user:\${DB_PASS}@${builder.host}/immich_db";
|
||||||
|
IMMICH_MACHINE_LEARNING_URL = "http://immich-ml:3003";
|
||||||
|
REDIS_HOSTNAME = builder.host;
|
||||||
|
};
|
||||||
|
overrides = {
|
||||||
|
volumes = [
|
||||||
|
"${serverCfg.dataPath}/immich:/usr/src/upload"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
immich-ml = builder.mkContainer {
|
||||||
|
imageStream = immichMachineLearningImage;
|
||||||
|
port = 3003;
|
||||||
|
overrides = {
|
||||||
|
volumes = [
|
||||||
|
"${serverCfg.configPath}/immich/cache:/cache"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
45
modules/server/containers/apps/influx.nix
Normal file
45
modules/server/containers/apps/influx.nix
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
||||||
|
let
|
||||||
|
serverCfg = config.syscfg.server;
|
||||||
|
influxPkg = pkgs.influxdb2;
|
||||||
|
|
||||||
|
image = pkgs.dockerTools.streamLayeredImage {
|
||||||
|
name = influxPkg.name;
|
||||||
|
tag = influxPkg.version;
|
||||||
|
contents = [ ];
|
||||||
|
config = {
|
||||||
|
Entrypoint = [ "${influxPkg}/bin/influxd" ];
|
||||||
|
ExposedPorts = {
|
||||||
|
"8086/tcp" = {}; # Combined Engine and UI port
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in {
|
||||||
|
sops = true; # Highly recommended for initial admin passwords and setup tokens
|
||||||
|
db = false; # Using InfluxDB directly as the primary database
|
||||||
|
|
||||||
|
paths = [{
|
||||||
|
path = "${serverCfg.configPath}/influxdb/";
|
||||||
|
mode = "0700"; # Strict database permissions
|
||||||
|
}];
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
server = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
imageStream = image;
|
||||||
|
port = 8086;
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
INFLUXD_CONFIG_PATH = "var/lib/influxdb2/config";
|
||||||
|
INFLUXD_BOLT_PATH = "/var/lib/influxdb2/influxdb.bolt";
|
||||||
|
INFLUXD_ENGINE_PATH = "/var/lib/influxdb2/engine";
|
||||||
|
};
|
||||||
|
overrides = {
|
||||||
|
volumes = [
|
||||||
|
"${serverCfg.configPath}/influxdb/:/var/lib/influxdb2"
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,3 +1,47 @@
|
|||||||
{...}:{
|
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
||||||
|
let
|
||||||
|
serverCfg = config.syscfg.server;
|
||||||
|
|
||||||
|
invidiousImage = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "quay.io/invidious/invidious";
|
||||||
|
imageDigest = "sha256:7b5cfca1b369cbb87a6c983a54d588cb375ff60c6d71b3e1f0e2f59265f2a1b9"; # Pin tag digest
|
||||||
|
sha256 = lib.fakeSha256;
|
||||||
|
};
|
||||||
|
companionImage = pkgs.dockerTools.pullImage {
|
||||||
|
imageName = "quay.io/invidious/inv-sig-helper";
|
||||||
|
imageDigest = "sha256:2d150b07b1406b3a0c25a5f1e8e25d6b46efbb12dbfde6125026bc9812a647ad";
|
||||||
|
sha256 = lib.fakeSha256;
|
||||||
|
};
|
||||||
|
|
||||||
|
in {
|
||||||
|
sops = true;
|
||||||
|
db = true;
|
||||||
|
|
||||||
|
containers = {
|
||||||
|
server = builder.mkContainer {
|
||||||
|
subdomain = containerCfg.subdomain;
|
||||||
|
imageStream = invidiousImage;
|
||||||
|
port = 3000;
|
||||||
|
secret = name;
|
||||||
|
extraEnv = {
|
||||||
|
INVIDIOUS_DATABASE_URL = "postgres://invidious_user:\${DB_PASS}@${builder.host}/invidious_db";
|
||||||
|
INVIDIOUS_HMAC_KEY = "\${HMAC_KEY}";
|
||||||
|
INVIDIOUS_COMPANION_URL = "http://invidious-companion:12999";
|
||||||
|
INVIDIOUS_PO_TOKEN = "\${PO_TOKEN}";
|
||||||
|
INVIDIOUS_VISITOR_DATA = "\${VISITOR_DATA}";
|
||||||
|
INVIDIOUS_PORT = "3000";
|
||||||
|
INVIDIOUS_COMPANION_KEY = "\${INVIDIOUS_KEY}";
|
||||||
|
INVIDIOUS_DOMAIN = "${containerCfg.subdomain}.${serverCfg.hostDomain}";
|
||||||
|
#registration_enabled: false
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
companion = builder.mkContainer {
|
||||||
|
imageStream = companionImage;
|
||||||
|
port = 12999;
|
||||||
|
overrides = {
|
||||||
|
cmd = [ "--tcp" "0.0.0.0:12999" ];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
}
|
}
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
{ config, containerCfg, pkgs, lib, builder, name, ... }:
|
||||||
let
|
let
|
||||||
serverCfg = config.syscfg.server;
|
serverCfg = config.syscfg.server;
|
||||||
image = pkgs.dockerTools.streamLayeredImage {
|
image = pkgs.dockerTools.streamLayeredImage { # pkgs.dockerTools.buildImage{#
|
||||||
name = pkgs.jellyfin.name;
|
name = pkgs.jellyfin.name;
|
||||||
tag = pkgs.jellyfin.version;
|
tag = pkgs.jellyfin.version;
|
||||||
contents = [
|
contents = [
|
||||||
@@ -12,12 +12,7 @@ let
|
|||||||
ExposedPorts = { "8096/tcp" = { }; };
|
ExposedPorts = { "8096/tcp" = { }; };
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
#LDAP_DC_DOMAIN = "dc=ldap,dc=helcel,dc=net"
|
|
||||||
#HOST=...
|
|
||||||
#LDAP_BIND_USER=ldap-sa
|
|
||||||
#LDAP_BIND_PASSWORD=...
|
|
||||||
#LDAP_GROUP=flix
|
|
||||||
#LDAP_ADMIN=admin
|
|
||||||
in {
|
in {
|
||||||
paths = [
|
paths = [
|
||||||
{
|
{
|
||||||
@@ -34,6 +29,7 @@ in {
|
|||||||
server = builder.mkContainer {
|
server = builder.mkContainer {
|
||||||
subdomain = containerCfg.subdomain;
|
subdomain = containerCfg.subdomain;
|
||||||
imageStream = image;
|
imageStream = image;
|
||||||
|
# imageFile = image;
|
||||||
port = 8096;
|
port = 8096;
|
||||||
# secret = name;
|
# secret = name;
|
||||||
extraEnv = {
|
extraEnv = {
|
||||||
@@ -52,7 +48,7 @@ in {
|
|||||||
"--logdir" "/config/log"
|
"--logdir" "/config/log"
|
||||||
];
|
];
|
||||||
volumes = [
|
volumes = [
|
||||||
"${serverCfg.dataPath}:/media:ro"
|
"${serverCfg.dataPath}/media:/media:ro"
|
||||||
"${serverCfg.configPath}/jellyfin:/config"
|
"${serverCfg.configPath}/jellyfin:/config"
|
||||||
];
|
];
|
||||||
# If you have an Intel/AMD GPU for transcoding, add the device:
|
# If you have an Intel/AMD GPU for transcoding, add the device:
|
||||||
@@ -60,4 +56,13 @@ in {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#LDAP_DC_DOMAIN = "dc=ldap,dc=helcel,dc=net"
|
||||||
|
#HOST=...
|
||||||
|
#LDAP_BIND_USER=ldap-sa
|
||||||
|
#LDAP_BIND_PASSWORD=...
|
||||||
|
#LDAP_GROUP=flix
|
||||||
|
#LDAP_ADMIN=admin
|
||||||
}
|
}
|
||||||
@@ -8,7 +8,7 @@ let
|
|||||||
contents = with pkgs; [ cacert openssl ];
|
contents = with pkgs; [ cacert openssl ];
|
||||||
config = {
|
config = {
|
||||||
Cmd = [ "${appPkg}/${binaryPath}" "-nobrowser" "-data=/config" ];
|
Cmd = [ "${appPkg}/${binaryPath}" "-nobrowser" "-data=/config" ];
|
||||||
Env = [ "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1" ];
|
Env = [ "DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1" "HOME=/tmp" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -22,12 +22,13 @@ let
|
|||||||
};
|
};
|
||||||
|
|
||||||
sharedVolumes = [
|
sharedVolumes = [
|
||||||
"${serverCfg.mediaPath or "/mnt/media"}:/media" # Fast hardlinking requires a single shared root
|
"${serverCfg.dataPath}/media:/media" # Fast hardlinking requires a single shared root
|
||||||
"${serverCfg.configPath}/servarr:/config-root"
|
"${serverCfg.configPath}/servarr:/config-root"
|
||||||
];
|
];
|
||||||
in {
|
in {
|
||||||
sops = true;
|
sops = true;
|
||||||
paths = [
|
paths = [
|
||||||
|
{ path = "${serverCfg.dataPath}/media/"; mode = "0755"; }
|
||||||
{ path = "${serverCfg.configPath}/servarr/prowlarr"; mode = "0755"; }
|
{ path = "${serverCfg.configPath}/servarr/prowlarr"; mode = "0755"; }
|
||||||
{ path = "${serverCfg.configPath}/servarr/radarr"; mode = "0755"; }
|
{ path = "${serverCfg.configPath}/servarr/radarr"; mode = "0755"; }
|
||||||
{ path = "${serverCfg.configPath}/servarr/sonarr"; mode = "0755"; }
|
{ path = "${serverCfg.configPath}/servarr/sonarr"; mode = "0755"; }
|
||||||
@@ -40,6 +41,9 @@ in {
|
|||||||
imageStream = images.prowlarr;
|
imageStream = images.prowlarr;
|
||||||
port = 9696;
|
port = 9696;
|
||||||
secret = name;
|
secret = name;
|
||||||
|
extraOptions = [
|
||||||
|
"--tmpfs=/tmp:rw,noexec,nosuid,size=512m"
|
||||||
|
];
|
||||||
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/prowlarr:/config" ];
|
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/prowlarr:/config" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,6 +53,9 @@ in {
|
|||||||
imageStream = images.radarr;
|
imageStream = images.radarr;
|
||||||
port = 7878;
|
port = 7878;
|
||||||
secret = name;
|
secret = name;
|
||||||
|
extraOptions = [
|
||||||
|
"--tmpfs=/tmp:rw,noexec,nosuid,size=512m"
|
||||||
|
];
|
||||||
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/radarr:/config" ];
|
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/radarr:/config" ];
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -58,6 +65,9 @@ in {
|
|||||||
imageStream = images.sonarr;
|
imageStream = images.sonarr;
|
||||||
port = 8989;
|
port = 8989;
|
||||||
secret = name;
|
secret = name;
|
||||||
|
extraOptions = [
|
||||||
|
"--tmpfs=/tmp:rw,noexec,nosuid,size=512m"
|
||||||
|
];
|
||||||
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/sonarr:/config" ];
|
overrides.volumes = sharedVolumes ++ [ "${serverCfg.configPath}/servarr/sonarr:/config" ];
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ let
|
|||||||
else subdomain;
|
else subdomain;
|
||||||
base = {
|
base = {
|
||||||
image = if imageStream != null then "${imageStream.imageName}:${imageStream.imageTag}"
|
image = if imageStream != null then "${imageStream.imageName}:${imageStream.imageTag}"
|
||||||
else image;
|
else if imageFile != null then "${imageFile.imageName}:${imageFile.imageTag}" else image;
|
||||||
imageStream = imageStream;
|
imageStream = imageStream;
|
||||||
imageFile = imageFile;
|
imageFile = imageFile;
|
||||||
|
|
||||||
|
|||||||
41
modules/server/containers/data/authentik/ldap.yaml
Normal file
41
modules/server/containers/data/authentik/ldap.yaml
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
version: 1
|
||||||
|
metadata:
|
||||||
|
name: Pre-configured LDAP Outpost
|
||||||
|
entries:
|
||||||
|
# 1. Define the LDAP Provider
|
||||||
|
- model: authentik_providers_ldap.ldapprovider
|
||||||
|
identifiers:
|
||||||
|
name: ldap-provider
|
||||||
|
attrs:
|
||||||
|
base_dn: "DC=ldap,@AUTHENTIK_LDAP_DC_DOMAIN@"
|
||||||
|
search_group: null
|
||||||
|
authorization_flow:
|
||||||
|
!Find [
|
||||||
|
authentik_flows.flow,
|
||||||
|
[slug, default-provider-authorization-implicit-consent],
|
||||||
|
]
|
||||||
|
invalidation_flow:
|
||||||
|
!Find [authentik_flows.flow, [slug, default-provider-invalidation-flow]]
|
||||||
|
|
||||||
|
# 2. Define the Token with a static Key
|
||||||
|
- model: authentik_core.token
|
||||||
|
identifiers:
|
||||||
|
identifier: ldap-outpost-static-token
|
||||||
|
attrs:
|
||||||
|
intent: api
|
||||||
|
# MANDATORY: Explicitly set your long, secure pre-shared token here
|
||||||
|
key: !Env AUTHENTIK_LDAP
|
||||||
|
user: 1 # Assigns to default akadmin user
|
||||||
|
|
||||||
|
# 3. Define the Outpost linking the Provider and the Token
|
||||||
|
- model: authentik_outposts.outpost
|
||||||
|
identifiers:
|
||||||
|
name: LDAP Outpost
|
||||||
|
attrs:
|
||||||
|
type: ldap
|
||||||
|
providers:
|
||||||
|
- !Find [authentik_providers_ldap.ldapprovider, [name, ldap-provider]]
|
||||||
|
token:
|
||||||
|
!Find [authentik_core.token, [identifier, ldap-outpost-static-token]]
|
||||||
|
config:
|
||||||
|
log_level: info
|
||||||
@@ -15,14 +15,13 @@ in{
|
|||||||
lib.mapAttrs' (cName: cCfg: lib.nameValuePair "${appName}-${cName}" cCfg) app.containers
|
lib.mapAttrs' (cName: cCfg: lib.nameValuePair "${appName}-${cName}" cCfg) app.containers
|
||||||
) config.syscfg.server.loadedContainers;
|
) config.syscfg.server.loadedContainers;
|
||||||
allPathConfigs = lib.concatMap (app: app.paths) appsList;
|
allPathConfigs = lib.concatMap (app: app.paths) appsList;
|
||||||
|
allSetupConfigs = lib.concatMap (app: if app.setup?script then [({name = app.name; envFile="";} // app.setup)] else []) appsList;
|
||||||
allCronsConfigs = lib.concatMap (app: app.cron) appsList;
|
allCronsConfigs = lib.concatMap (app: app.cron) appsList;
|
||||||
in{
|
in{
|
||||||
|
|
||||||
virtualisation.oci-containers = {
|
virtualisation.oci-containers = {
|
||||||
backend = "podman";
|
backend = "podman";
|
||||||
containers = mergedContainers;
|
containers = mergedContainers;
|
||||||
};
|
};
|
||||||
|
|
||||||
system.activationScripts.container-setup-dirs = {
|
system.activationScripts.container-setup-dirs = {
|
||||||
deps = [ "users" "groups" ];
|
deps = [ "users" "groups" ];
|
||||||
text = lib.concatStringsSep "\n" (map (cfg:
|
text = lib.concatStringsSep "\n" (map (cfg:
|
||||||
@@ -48,25 +47,23 @@ in{
|
|||||||
'';
|
'';
|
||||||
startAt = "weekly";
|
startAt = "weekly";
|
||||||
};
|
};
|
||||||
} // lib.listToAttrs (lib.concatMap (containerSet:
|
} // lib.listToAttrs (lib.concatMap (e: [{
|
||||||
if containerSet.setup.script != null then [{
|
name = "${e.name}-setup";
|
||||||
name = "${containerSet.name}-setup";
|
|
||||||
value = {
|
value = {
|
||||||
description = "Run ${containerSet.name} setup";
|
description = "Run ${e.name} setup";
|
||||||
after = [ "podman-${containerSet.name}-${containerSet.setup.trigger}.service" ];
|
after = [ "podman-${e.name}-${e.trigger}.service" ];
|
||||||
wants = [ "podman-${containerSet.name}-${containerSet.setup.trigger}.service" ];
|
wants = [ "podman-${e.name}-${e.trigger}.service" ];
|
||||||
wantedBy = [ "multi-user.target" ];
|
wantedBy = [ "multi-user.target" ];
|
||||||
serviceConfig = {
|
serviceConfig = {
|
||||||
Type = "oneshot";
|
Type = "oneshot";
|
||||||
TimeoutStartSec = "360s";
|
TimeoutStartSec = "360s";
|
||||||
EnvironmentFile = if (containerSet.setup ? envFile) then containerSet.setup.envFile else [ ];
|
EnvironmentFile = e.envFile;
|
||||||
ExecStart = "${containerSet.setup.script}";
|
ExecStart = e.script;
|
||||||
RemainAfterExit = true;
|
RemainAfterExit = true;
|
||||||
User = "root";
|
User = "root";
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
}] else []
|
}]) allSetupConfigs );
|
||||||
) appsList);
|
|
||||||
|
|
||||||
services.cron = {
|
services.cron = {
|
||||||
enable = true;
|
enable = true;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ AUTHENTIK: |
|
|||||||
POSTGRES_PASSWORD=...
|
POSTGRES_PASSWORD=...
|
||||||
AUTHENTIK_SECRET_KEY=...
|
AUTHENTIK_SECRET_KEY=...
|
||||||
AUTHENTIK_EMAIL__PASSWORD=...
|
AUTHENTIK_EMAIL__PASSWORD=...
|
||||||
|
AUTHENTIK_TOKEN=...
|
||||||
NEXTCLOUD: |
|
NEXTCLOUD: |
|
||||||
DB_PASSWORD=...
|
DB_PASSWORD=...
|
||||||
POSTGRES_PASSWORD=...
|
POSTGRES_PASSWORD=...
|
||||||
|
|||||||
Reference in New Issue
Block a user