mirror of
https://github.com/rubenhensen/k8scd.git
synced 2026-09-17 02:12:55 +02:00
Add nix-infra-machine
This commit is contained in:
@@ -0,0 +1,234 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
let
|
||||
appName = "n8n-pod";
|
||||
defaultPort = 5678;
|
||||
|
||||
cfg = config.infrastructure.${appName};
|
||||
|
||||
dataDir = "/var/lib/n8n-pod";
|
||||
execStartPreScript = pkgs.writeShellScript "preStart" ''
|
||||
${pkgs.coreutils}/bin/mkdir -p ${dataDir}
|
||||
${pkgs.coreutils}/bin/chown -R 1000:1000 ${dataDir}
|
||||
'';
|
||||
|
||||
# Build environment variables for the container
|
||||
containerEnv = {
|
||||
# Network settings
|
||||
N8N_PORT = toString defaultPort;
|
||||
N8N_LISTEN_ADDRESS = "0.0.0.0"; # Always bind to all interfaces inside container
|
||||
|
||||
# Execution settings
|
||||
EXECUTIONS_DATA_PRUNE = if cfg.executions.pruneData then "true" else "false";
|
||||
EXECUTIONS_DATA_MAX_AGE = toString cfg.executions.pruneDataMaxAge;
|
||||
EXECUTIONS_DATA_PRUNE_MAX_COUNT = toString cfg.executions.pruneDataMaxCount;
|
||||
} // (lib.optionalAttrs (cfg.webhookUrl != "") {
|
||||
WEBHOOK_URL = cfg.webhookUrl;
|
||||
}) // (lib.optionalAttrs (cfg.database.type == "postgresdb") {
|
||||
DB_TYPE = "postgresdb";
|
||||
DB_POSTGRESDB_HOST = cfg.database.postgresdb.host;
|
||||
DB_POSTGRESDB_PORT = toString cfg.database.postgresdb.port;
|
||||
DB_POSTGRESDB_DATABASE = cfg.database.postgresdb.database;
|
||||
DB_POSTGRESDB_USER = cfg.database.postgresdb.user;
|
||||
}) // (lib.optionalAttrs (cfg.database.type == "postgresdb" && cfg.database.postgresdb.ssl) {
|
||||
DB_POSTGRESDB_SSL_ENABLED = "true";
|
||||
}) // cfg.settings;
|
||||
|
||||
# Convert environment to list of "KEY=VALUE" strings
|
||||
envList = lib.mapAttrsToList (name: value: "${name}=${toString value}") containerEnv;
|
||||
in
|
||||
{
|
||||
options.infrastructure.${appName} = {
|
||||
enable = lib.mkEnableOption "infrastructure.n8n-pod oci";
|
||||
|
||||
image = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "n8n Docker image to use.";
|
||||
default = "docker.n8n.io/n8nio/n8n:latest";
|
||||
example = "docker.n8n.io/n8nio/n8n:1.70.0";
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# Network Configuration
|
||||
# ==========================================================================
|
||||
|
||||
bindToIp = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "IP address to bind n8n to on the host.";
|
||||
default = "127.0.0.1";
|
||||
example = "0.0.0.0";
|
||||
};
|
||||
|
||||
bindToPort = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description = "Port for n8n web interface on the host.";
|
||||
default = defaultPort;
|
||||
};
|
||||
|
||||
openFirewall = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "Open firewall for n8n.";
|
||||
default = false;
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# Webhook Configuration
|
||||
# ==========================================================================
|
||||
|
||||
webhookUrl = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
WEBHOOK_URL for n8n, used when running behind a reverse proxy.
|
||||
This is the external URL where webhooks can reach n8n.
|
||||
'';
|
||||
default = "";
|
||||
example = "https://n8n.example.com/";
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# Database Configuration
|
||||
# ==========================================================================
|
||||
database = {
|
||||
type = lib.mkOption {
|
||||
type = lib.types.enum [ "sqlite" "postgresdb" ];
|
||||
description = "Database type to use. SQLite is default, PostgreSQL recommended for production.";
|
||||
default = "sqlite";
|
||||
};
|
||||
|
||||
postgresdb = {
|
||||
host = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "PostgreSQL host. Use host IP for container access.";
|
||||
default = "host.containers.internal";
|
||||
example = "192.168.1.100";
|
||||
};
|
||||
|
||||
port = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description = "PostgreSQL port.";
|
||||
default = 5432;
|
||||
};
|
||||
|
||||
database = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "PostgreSQL database name.";
|
||||
default = "n8n";
|
||||
};
|
||||
|
||||
user = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = "PostgreSQL user.";
|
||||
default = "n8n";
|
||||
};
|
||||
|
||||
password = lib.mkOption {
|
||||
type = lib.types.str;
|
||||
description = ''
|
||||
PostgreSQL password. For production, consider using
|
||||
passwordFile or environment variable injection instead.
|
||||
'';
|
||||
default = "";
|
||||
example = "secretpassword";
|
||||
};
|
||||
|
||||
ssl = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "Enable SSL for PostgreSQL connection.";
|
||||
default = false;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# Execution Configuration
|
||||
# ==========================================================================
|
||||
|
||||
executions = {
|
||||
pruneData = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
description = "Enable automatic pruning of old execution data.";
|
||||
default = true;
|
||||
};
|
||||
|
||||
pruneDataMaxAge = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description = "Maximum age of execution data in hours before pruning.";
|
||||
default = 336; # 14 days
|
||||
};
|
||||
|
||||
pruneDataMaxCount = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
description = "Maximum number of executions to keep.";
|
||||
default = 10000;
|
||||
};
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# n8n Settings (pass-through as environment variables)
|
||||
# ==========================================================================
|
||||
|
||||
settings = lib.mkOption {
|
||||
type = lib.types.attrsOf lib.types.anything;
|
||||
description = ''
|
||||
Additional n8n configuration as environment variables.
|
||||
See https://docs.n8n.io/hosting/environment-variables/environment-variables/
|
||||
'';
|
||||
default = {};
|
||||
example = lib.literalExpression ''
|
||||
{
|
||||
GENERIC_TIMEZONE = "Europe/London";
|
||||
WORKFLOWS_DEFAULT_NAME = "My Workflow";
|
||||
N8N_METRICS = "true";
|
||||
}
|
||||
'';
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
# Configure podman backend
|
||||
infrastructure.oci-containers.backend = "podman";
|
||||
|
||||
infrastructure.oci-containers.containers.${appName} = {
|
||||
app = {
|
||||
name = appName;
|
||||
};
|
||||
image = cfg.image;
|
||||
autoStart = true;
|
||||
ports = [
|
||||
"${cfg.bindToIp}:${toString cfg.bindToPort}:${toString defaultPort}"
|
||||
];
|
||||
bindToIp = cfg.bindToIp;
|
||||
|
||||
# Mount data directory for persistence
|
||||
volumes = [
|
||||
"${dataDir}:/home/node/.n8n"
|
||||
];
|
||||
|
||||
# Environment variables
|
||||
environment = containerEnv;
|
||||
|
||||
# Run as node user (UID 1000 in official image)
|
||||
user = "1000:1000";
|
||||
|
||||
execHooks = {
|
||||
ExecStartPre = [
|
||||
"${execStartPreScript}"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# ==========================================================================
|
||||
# Firewall Configuration
|
||||
# ==========================================================================
|
||||
|
||||
networking.firewall.allowedTCPPorts = lib.mkIf cfg.openFirewall [ cfg.bindToPort ];
|
||||
|
||||
# ==========================================================================
|
||||
# Utilities
|
||||
# ==========================================================================
|
||||
|
||||
environment.systemPackages = with pkgs; [
|
||||
curl
|
||||
jq
|
||||
];
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user