feat(core): initialize NaxOS declarative NixOS distribution, modules, and ISO installer
Test NaxOS Module Configurations / test-modules (push) Failing after 6m10s
Test NaxOS Module Configurations / test-modules (push) Failing after 6m10s
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.appEngine;
|
||||
in {
|
||||
options.services.naxos.appEngine = {
|
||||
enable = mkEnableOption "NaxOS Multi-Tier App Engine";
|
||||
|
||||
defaultRuntime = mkOption {
|
||||
type = types.enum [ "systemd" "docker" "k3s" ];
|
||||
default = "docker";
|
||||
description = "Default execution runtime for user workloads.";
|
||||
};
|
||||
|
||||
docker = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable Docker engine for containerized applications.";
|
||||
};
|
||||
storageDriver = mkOption {
|
||||
type = types.enum [ "zfs" "overlay2" "btrfs" ];
|
||||
default = "zfs";
|
||||
description = "Container storage driver. 'zfs' uses native copy-on-write datasets.";
|
||||
};
|
||||
dataRoot = mkOption {
|
||||
type = types.str;
|
||||
default = "/var/lib/docker";
|
||||
description = "Storage root for container images and layers.";
|
||||
};
|
||||
};
|
||||
|
||||
k3s = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = false;
|
||||
description = "Enable lightweight K3s single-node cluster for cloud-native orchestration.";
|
||||
};
|
||||
role = mkOption {
|
||||
type = types.enum [ "server" "agent" ];
|
||||
default = "server";
|
||||
description = "K3s node role.";
|
||||
};
|
||||
tokenFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to token file for K3s node join / cluster security.";
|
||||
};
|
||||
};
|
||||
|
||||
gpuAcceleration = {
|
||||
enable = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Enable hardware transcoding and machine learning acceleration.";
|
||||
};
|
||||
vendor = mkOption {
|
||||
type = types.enum [ "intel" "nvidia" "amd" "none" ];
|
||||
default = "intel";
|
||||
description = "Primary GPU hardware vendor.";
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# 1. Docker Runtime Configuration
|
||||
virtualisation.docker = mkIf cfg.docker.enable {
|
||||
enable = true;
|
||||
storageDriver = cfg.docker.storageDriver;
|
||||
daemon.settings = {
|
||||
data-root = cfg.docker.dataRoot;
|
||||
log-driver = "journald";
|
||||
};
|
||||
};
|
||||
|
||||
# OCI container backend compatibility
|
||||
virtualisation.oci-containers.backend = mkIf cfg.docker.enable "docker";
|
||||
|
||||
# 2. K3s Runtime Configuration
|
||||
services.k3s = mkIf cfg.k3s.enable {
|
||||
enable = true;
|
||||
role = cfg.k3s.role;
|
||||
tokenFile = cfg.k3s.tokenFile;
|
||||
extraFlags = toString [
|
||||
"--disable=traefik" # We manage ingress/reverse-proxy through NaxOS
|
||||
"--snapshotter=native"
|
||||
];
|
||||
};
|
||||
|
||||
# 3. Hardware Graphics Acceleration
|
||||
hardware.graphics = mkIf cfg.gpuAcceleration.enable {
|
||||
enable = true;
|
||||
extraPackages = mkIf (cfg.gpuAcceleration.vendor == "intel") (with pkgs; [
|
||||
intel-media-driver # Broadwell or newer
|
||||
intel-compute-runtime # OpenCL support
|
||||
vpl-gpu-rt # QSV support (11th Gen+)
|
||||
]);
|
||||
};
|
||||
|
||||
# 4. System packages for workload operations
|
||||
environment.systemPackages = with pkgs; [
|
||||
docker-compose
|
||||
lazydocker
|
||||
kubectl
|
||||
dive
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{ ... }:
|
||||
|
||||
{
|
||||
imports = [
|
||||
./immich.nix
|
||||
./nextcloud.nix
|
||||
./jellyfin.nix
|
||||
./paperless.nix
|
||||
./vaultwarden.nix
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.apps.immich;
|
||||
in {
|
||||
options.services.naxos.apps.immich = {
|
||||
enable = mkEnableOption "Immich Self-Hosted Photo & Video Hub";
|
||||
|
||||
runtime = mkOption {
|
||||
type = types.enum [ "systemd" "docker" ];
|
||||
default = "systemd";
|
||||
description = "Runtime to execute Immich (systemd for native bare-metal speed with NixOS package, docker for containerized).";
|
||||
};
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 2283;
|
||||
description = "Web interface and API port.";
|
||||
};
|
||||
|
||||
host = mkOption {
|
||||
type = types.str;
|
||||
default = "0.0.0.0";
|
||||
description = "Listen host.";
|
||||
};
|
||||
|
||||
mediaLocation = mkOption {
|
||||
type = types.str;
|
||||
default = "/tank/media/photos";
|
||||
description = "ZFS dataset or path where uploaded photos and videos are stored.";
|
||||
};
|
||||
|
||||
accelerationDevices = mkOption {
|
||||
type = types.listOf types.str;
|
||||
default = [ "/dev/dri/renderD128" ];
|
||||
description = "DRM render devices for hardware-accelerated transcoding.";
|
||||
};
|
||||
|
||||
machineLearningCPUQuota = mkOption {
|
||||
type = types.str;
|
||||
default = "200%";
|
||||
description = "CPU quota for machine learning service (200% = 2 full cores).";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Open port in firewall.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
# Systemd / Native NixOS Deployment
|
||||
services.immich = mkIf (cfg.runtime == "systemd") {
|
||||
enable = true;
|
||||
host = cfg.host;
|
||||
port = cfg.port;
|
||||
mediaLocation = cfg.mediaLocation;
|
||||
openFirewall = cfg.openFirewall;
|
||||
accelerationDevices = cfg.accelerationDevices;
|
||||
};
|
||||
|
||||
services.redis.servers.immich = mkIf (cfg.runtime == "systemd") {
|
||||
logLevel = "warning";
|
||||
};
|
||||
|
||||
systemd.services.immich-machine-learning = mkIf (cfg.runtime == "systemd") {
|
||||
serviceConfig = {
|
||||
CPUQuota = cfg.machineLearningCPUQuota;
|
||||
Nice = 19;
|
||||
};
|
||||
};
|
||||
|
||||
users.users.immich = mkIf (cfg.runtime == "systemd") {
|
||||
extraGroups = [ "video" "render" ];
|
||||
};
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.mediaLocation} 0750 immich immich -"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.apps.jellyfin;
|
||||
in {
|
||||
options.services.naxos.apps.jellyfin = {
|
||||
enable = mkEnableOption "Jellyfin Open-Source Media Streaming Server";
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Open port 8096 in firewall.";
|
||||
};
|
||||
|
||||
user = mkOption {
|
||||
type = types.str;
|
||||
default = "jellyfin";
|
||||
description = "Service user.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.jellyfin = {
|
||||
enable = true;
|
||||
openFirewall = cfg.openFirewall;
|
||||
user = cfg.user;
|
||||
};
|
||||
|
||||
users.users.${cfg.user}.extraGroups = [ "video" "render" ];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.apps.nextcloud;
|
||||
in {
|
||||
options.services.naxos.apps.nextcloud = {
|
||||
enable = mkEnableOption "Nextcloud Personal Cloud & Collaboration Platform";
|
||||
|
||||
hostName = mkOption {
|
||||
type = types.str;
|
||||
default = "cloud.local";
|
||||
description = "Domain / hostname for Nextcloud.";
|
||||
};
|
||||
|
||||
homeDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/tank/data/nextcloud";
|
||||
description = "Persistent data directory on ZFS storage.";
|
||||
};
|
||||
|
||||
adminpassFile = mkOption {
|
||||
type = types.nullOr types.str;
|
||||
default = null;
|
||||
description = "Path to file containing initial admin password.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.nextcloud = {
|
||||
enable = true;
|
||||
hostName = cfg.hostName;
|
||||
home = cfg.homeDir;
|
||||
config = {
|
||||
adminuser = "admin";
|
||||
adminpassFile = cfg.adminpassFile;
|
||||
dbtype = "sqlite";
|
||||
};
|
||||
caching.redis = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.apps.paperless;
|
||||
in {
|
||||
options.services.naxos.apps.paperless = {
|
||||
enable = mkEnableOption "Paperless-ngx Document Archiving System";
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 28981;
|
||||
description = "Web interface port.";
|
||||
};
|
||||
|
||||
mediaDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/tank/data/paperless/media";
|
||||
description = "Directory where archived documents and OCR results are stored.";
|
||||
};
|
||||
|
||||
consumptionDir = mkOption {
|
||||
type = types.str;
|
||||
default = "/tank/scans";
|
||||
description = "Ingestion directory where scanner uploads incoming documents.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Open port in firewall.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.paperless = {
|
||||
enable = true;
|
||||
port = cfg.port;
|
||||
mediaDir = cfg.mediaDir;
|
||||
consumptionDir = cfg.consumptionDir;
|
||||
settings = {
|
||||
PAPERLESS_OCR_LANGUAGE = "deu+eng";
|
||||
PAPERLESS_CONSUMER_POLLING = 30;
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
|
||||
systemd.tmpfiles.rules = [
|
||||
"d ${cfg.mediaDir} 0750 paperless paperless -"
|
||||
"d ${cfg.consumptionDir} 0775 paperless users -"
|
||||
];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
with lib;
|
||||
|
||||
let
|
||||
cfg = config.services.naxos.apps.vaultwarden;
|
||||
in {
|
||||
options.services.naxos.apps.vaultwarden = {
|
||||
enable = mkEnableOption "Vaultwarden Password & Secret Vault";
|
||||
|
||||
port = mkOption {
|
||||
type = types.port;
|
||||
default = 8222;
|
||||
description = "Web interface port.";
|
||||
};
|
||||
|
||||
openFirewall = mkOption {
|
||||
type = types.bool;
|
||||
default = true;
|
||||
description = "Open port in firewall.";
|
||||
};
|
||||
};
|
||||
|
||||
config = mkIf cfg.enable {
|
||||
services.vaultwarden = {
|
||||
enable = true;
|
||||
config = {
|
||||
ROCKET_PORT = cfg.port;
|
||||
ROCKET_ADDRESS = "0.0.0.0";
|
||||
};
|
||||
};
|
||||
|
||||
networking.firewall.allowedTCPPorts = mkIf cfg.openFirewall [ cfg.port ];
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user