{ flake, config, pkgs, lib, ... }: let psCfg = config.pub-solar; xdg = config.home-manager.users."${psCfg.user.name}".xdg; backupDir = "/var/lib/invoiceplane/backup"; in { age.secrets."invoiceplane-db-password" = { file = "${flake.self}/secrets/invoiceplane-db-password.age"; mode = "400"; owner = "invoiceplane"; }; age.secrets."invoiceplane-db-secrets.env" = { file = "${flake.self}/secrets/invoiceplane-db-secrets.env.age"; mode = "400"; }; security.acme.certs = { "invoicing.b12f.io" = {}; }; services.nginx.virtualHosts = { "invoicing.b12f.io" = { forceSSL = true; useACMEHost = "invoicing.b12f.io"; extraConfig = "include /etc/nginx/conf-available/authelia-location.conf;"; locations."/".extraConfig = '' include /etc/nginx/conf-available/proxy.conf; include /etc/nginx/conf-available/authelia-authrequest.conf; ''; }; }; services.invoiceplane.webserver = "nginx"; services.invoiceplane.sites."invoicing.b12f.io" = { enable = true; database = { user = "invoiceplane"; name = "invoiceplane"; passwordFile = config.age.secrets."invoiceplane-db-password".path; host = "127.0.0.1"; port = 3306; createLocally = false; }; extraConfig = '' SETUP_COMPLETED=true DISABLE_SETUP=true IP_URL=https://invoicing.b12f.io ''; poolConfig = { "pm" = "dynamic"; "pm.max_children" = 32; "pm.max_requests" = 500; "pm.max_spare_servers" = 4; "pm.min_spare_servers" = 2; "pm.start_servers" = 2; "php_admin_value[error_log]" = "/var/lib/invoiceplane/invoicing.b12f.io/logs/php-error.log"; "php_admin_flag[display_errors]" = "off"; "php_admin_flag[log_errors]" = "on"; "catch_workers_output" = "yes"; }; }; virtualisation = { oci-containers = { backend = "docker"; containers."invoiceplane-db" = { image = "mariadb:11"; autoStart = true; ports = [ "127.0.0.1:3306:3306" ]; volumes = [ "/var/lib/invoiceplane/db:/var/lib/mysql" ]; environmentFiles = [ config.age.secrets."invoiceplane-db-secrets.env".path ]; }; }; }; systemd.tmpfiles.rules = [ "d '${backupDir}' 0700 root root - -" ]; services.restic.backups = { invoiceplane = { paths = [ backupDir "/var/lib/invoiceplane/invoicing.b12f.io" ]; initialize = true; passwordFile = config.age.secrets."restic-password".path; # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ repository = "rclone:cloud.pub.solar:/backups/InvoicePlane"; backupPrepareCommand = '' PW=$(cat ${config.age.secrets."invoiceplane-db-password".path}) ${pkgs.docker-client}/bin/docker exec -t invoiceplane-db mariadb-dump --all-databases --password=$PW --user=invoiceplane > "${backupDir}/postgres.sql" ''; rcloneConfigFile = config.age.secrets."rclone-pie.conf".path; }; }; }