+zammad-hr
This commit is contained in:
238
hosts/AZ-CLD-1/services/containers/zammad-hr.nix
Normal file
238
hosts/AZ-CLD-1/services/containers/zammad-hr.nix
Normal file
@@ -0,0 +1,238 @@
|
||||
{
|
||||
config,
|
||||
lib,
|
||||
pkgs,
|
||||
...
|
||||
}: let
|
||||
# Instance identifier - macht es einfach, später eine zweite Instanz zu erstellen
|
||||
instanceName = "hr";
|
||||
serviceName = "zammad-${instanceName}";
|
||||
|
||||
portUtils = import ../../../../lib/port-utils.nix {inherit lib;};
|
||||
servicePort = portUtils.getPort serviceName "AZ-CLD-1";
|
||||
elasticsearchPort = portUtils.getPort "${serviceName}-elasticsearch" "AZ-CLD-1";
|
||||
|
||||
envFileProd = config.age.secrets."${serviceName}-env-prod".path;
|
||||
envFileCommon = config.age.secrets."${serviceName}-env".path;
|
||||
|
||||
# Zammad version
|
||||
zammadVersion = "6.5.2-22";
|
||||
zammadImage = "ghcr.io/zammad/zammad:${zammadVersion}";
|
||||
|
||||
# IP-Basis für diese Instanz (HR: .30-.38, später IT: .40-.48)
|
||||
ipBase = "10.89.0";
|
||||
ipOffset = 30; # HR startet bei .30, IT würde bei .40 starten
|
||||
|
||||
# Shared environment variables
|
||||
sharedEnvironment = {
|
||||
MEMCACHE_SERVERS = "${serviceName}-memcached:11211";
|
||||
POSTGRESQL_DB = "zammad_${instanceName}";
|
||||
POSTGRESQL_HOST = "10.89.0.1"; # Host PostgreSQL
|
||||
POSTGRESQL_USER = "zammad_${instanceName}";
|
||||
POSTGRESQL_PORT = "5432";
|
||||
POSTGRESQL_OPTIONS = "?pool=50";
|
||||
REDIS_URL = "redis://${serviceName}-redis:6379";
|
||||
TZ = "Europe/Berlin";
|
||||
BACKUP_DIR = "/var/tmp/zammad";
|
||||
BACKUP_TIME = "03:00";
|
||||
HOLD_DAYS = "10";
|
||||
ELASTICSEARCH_ENABLED = "true";
|
||||
ELASTICSEARCH_HOST = "${serviceName}-elasticsearch";
|
||||
ELASTICSEARCH_PORT = "9200";
|
||||
ELASTICSEARCH_NAMESPACE = "zammad_${instanceName}";
|
||||
NGINX_PORT = "8080";
|
||||
};
|
||||
in {
|
||||
virtualisation.oci-containers = {
|
||||
containers."${serviceName}-elasticsearch" = {
|
||||
image = "elasticsearch:8.19.6";
|
||||
autoStart = true;
|
||||
volumes = ["${serviceName}_elasticsearch:/usr/share/elasticsearch/data"];
|
||||
environment = {
|
||||
"discovery.type" = "single-node";
|
||||
"xpack.security.enabled" = "false";
|
||||
ES_JAVA_OPTS = "-Xms1g -Xmx1g";
|
||||
};
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString ipOffset}"
|
||||
"--network=web"
|
||||
];
|
||||
ports = ["127.0.0.1:${toString elasticsearchPort}:9200"];
|
||||
};
|
||||
|
||||
containers."${serviceName}-memcached" = {
|
||||
image = "memcached:1.6.39-alpine";
|
||||
autoStart = true;
|
||||
cmd = ["memcached" "-m" "256M"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 1)}"
|
||||
"--network=web"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-redis" = {
|
||||
image = "redis:7.4.6-alpine";
|
||||
autoStart = true;
|
||||
volumes = ["${serviceName}_redis:/data"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 2)}"
|
||||
"--network=web"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-init" = {
|
||||
image = zammadImage;
|
||||
autoStart = false;
|
||||
cmd = ["zammad-init"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = ["${serviceName}_storage:/opt/zammad/storage"];
|
||||
dependsOn = ["${serviceName}-memcached" "${serviceName}-redis"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 3)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
"--user=0:0"
|
||||
"--restart=on-failure"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-railsserver" = {
|
||||
image = zammadImage;
|
||||
autoStart = true;
|
||||
cmd = ["zammad-railsserver"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = ["${serviceName}_storage:/opt/zammad/storage"];
|
||||
dependsOn = ["${serviceName}-memcached" "${serviceName}-redis" "${serviceName}-elasticsearch"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 4)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-scheduler" = {
|
||||
image = zammadImage;
|
||||
autoStart = true;
|
||||
cmd = ["zammad-scheduler"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = ["${serviceName}_storage:/opt/zammad/storage"];
|
||||
dependsOn = ["${serviceName}-memcached" "${serviceName}-redis"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 5)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-websocket" = {
|
||||
image = zammadImage;
|
||||
autoStart = true;
|
||||
cmd = ["zammad-websocket"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = ["${serviceName}_storage:/opt/zammad/storage"];
|
||||
dependsOn = ["${serviceName}-memcached" "${serviceName}-redis"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 6)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-nginx" = {
|
||||
image = zammadImage;
|
||||
autoStart = true;
|
||||
cmd = ["zammad-nginx"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = ["${serviceName}_storage:/opt/zammad/storage"];
|
||||
dependsOn = ["${serviceName}-railsserver"];
|
||||
ports = ["127.0.0.1:${toString servicePort}:8080"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 7)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
];
|
||||
};
|
||||
|
||||
containers."${serviceName}-backup" = {
|
||||
image = zammadImage;
|
||||
autoStart = true;
|
||||
cmd = ["zammad-backup"];
|
||||
environment = sharedEnvironment;
|
||||
environmentFiles = [envFileCommon envFileProd];
|
||||
volumes = [
|
||||
"${serviceName}_backup:/var/tmp/zammad"
|
||||
"${serviceName}_storage:/opt/zammad/storage:ro"
|
||||
"/var/backup/${serviceName}:/var/tmp/zammad:rw"
|
||||
];
|
||||
dependsOn = ["${serviceName}-memcached" "${serviceName}-redis"];
|
||||
extraOptions = [
|
||||
"--ip=${ipBase}.${toString (ipOffset + 8)}"
|
||||
"--network=web"
|
||||
"--add-host=postgres:10.89.0.1"
|
||||
"--user=0:0"
|
||||
];
|
||||
};
|
||||
};
|
||||
|
||||
# Backup retention service
|
||||
systemd.services."${serviceName}-backup-cleanup" = {
|
||||
serviceConfig = {
|
||||
Type = "oneshot";
|
||||
User = "root";
|
||||
Group = "root";
|
||||
};
|
||||
script = ''
|
||||
set -euo pipefail
|
||||
|
||||
BACKUP_DIR="/var/backup/${serviceName}"
|
||||
HOLD_DAYS=10
|
||||
|
||||
echo "Starting ${serviceName} backup cleanup at $(date)"
|
||||
|
||||
# Ensure backup directory exists
|
||||
mkdir -p "$BACKUP_DIR"
|
||||
chown root:root "$BACKUP_DIR"
|
||||
chmod 750 "$BACKUP_DIR"
|
||||
|
||||
# Remove backups older than HOLD_DAYS
|
||||
${pkgs.findutils}/bin/find "$BACKUP_DIR" -type f -name "*.gz" -mtime +$HOLD_DAYS -delete
|
||||
|
||||
echo "Current backups:"
|
||||
ls -lah "$BACKUP_DIR" || echo "No backups found"
|
||||
|
||||
echo "${serviceName} backup cleanup completed at $(date)"
|
||||
'';
|
||||
};
|
||||
|
||||
systemd.timers."${serviceName}-backup-cleanup" = {
|
||||
wantedBy = ["timers.target"];
|
||||
timerConfig = {
|
||||
OnCalendar = "*-*-* 04:00:00";
|
||||
RandomizedDelaySec = "30m";
|
||||
Persistent = true;
|
||||
};
|
||||
};
|
||||
|
||||
# Traefik configuration
|
||||
services.traefik.dynamicConfigOptions.http = {
|
||||
services.${serviceName}.loadBalancer.servers = [
|
||||
{
|
||||
url = "http://localhost:${toString servicePort}/";
|
||||
}
|
||||
];
|
||||
|
||||
routers.${serviceName} = {
|
||||
rule = "Host(`hr-ticket.az-gruppe.com`)"; # HR-spezifische Domain
|
||||
tls = {
|
||||
certResolver = "ionos";
|
||||
};
|
||||
service = serviceName;
|
||||
entrypoints = "websecure";
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user