{ flake, config, pkgs, lib, ... }: let psCfg = config.pub-solar; xdg = config.home-manager.users."${psCfg.user.name}".xdg; backupDir = "/var/lib/firefly/backup"; in { age.secrets."firefly-secrets.env" = { file = "${flake.self}/secrets/firefly-secrets.env"; mode = "600"; }; age.secrets."firefly-db-secrets.env" = { file = "${flake.self}/secrets/firefly-db-secrets.env"; mode = "600"; }; age.secrets."firefly-importer-secrets.env" = { file = "${flake.self}/secrets/firefly-importer-secrets.env"; mode = "600"; }; services.caddy = { enable = true; extraConfig = '' firefly.b12f.io:80 { reverse_proxy localhost:8080 } firefly-importer.b12f.io:80 { reverse_proxy localhost:8081 } ''; }; systemd.services."docker-network-firefly" = let docker = config.virtualisation.oci-containers.backend; dockerBin = "${pkgs.${docker}}/bin/${docker}"; in { serviceConfig.Type = "oneshot"; before = ["docker-firefly.service"]; script = '' ${dockerBin} network inspect firefly >/dev/null 2>&1 || ${dockerBin} network create firefly --subnet 172.20.0.0/24 ''; }; virtualisation = { oci-containers = { backend = "docker"; containers."firefly" = { image = "fireflyiii/core:latest"; autoStart = true; volumes = [ "/var/lib/firefly/upload:/var/www/html/storage/upload" ]; extraOptions = [ "--network=firefly" ]; environmentFiles = [ ./.env.firefly config.age.secrets."firefly-secrets.env".path ]; ports = [ "8080:8080" ]; dependsOn = [ "firefly-db" ]; }; containers."firefly-db" = { image = "postgres:16"; autoStart = true; volumes = [ "/var/lib/firefly/db:/var/lib/postgresql/data" ]; extraOptions = [ "--network=firefly" ]; environmentFiles = [ ./.env.firefly-importer config.age.secrets."firefly-db-secrets.env".path ]; }; containers."firefly-importer" = { image = "fireflyiii/data-importer:latest"; autoStart = true; extraOptions = [ "--network=firefly" ]; ports = [ "8081:8080" ]; environment = { FIREFLY_III_URL = "http://firefly.b12f.io/"; }; environmentFiles = [ config.age.secrets."firefly-importer-secrets.env".path ]; dependsOn = [ "firefly" ]; }; # containers."cron" = { # image = "alpine"; # autoStart = true; # command = ''sh -c "echo \"0 3 * * * wget -qO- http://firefly:8080/api/v1/cron/REPLACEME\" | crontab - && crond -f -L /dev/stdout"''; # extraOptions = [ "--network=firefly" ]; # }; }; }; systemd.tmpfiles.rules = [ "d '${backupDir}' 0700 root root - -" ]; age.secrets."rclone-pie.conf" = { file = "${flake.self}/secrets/rclone-pie.conf"; path = "/root/.config/rclone/rclone.conf"; mode = "600"; }; age.secrets."restic-password.age" = { file = "${flake.self}/secrets/restic-password.age"; mode = "600"; }; services.restic.backups = { firefly = { paths = [ backupDir "/var/lib/firefly/upload" ]; initialize = true; passwordFile = config.age.secrets."restic-password.age".path; # See https://www.hosting.de/blog/verschluesselte-backups-mit-rclone-und-restic-in-nextcloud/ repository = "rclone:cloud.pub.solar:/backups/FireflyIII"; backupPrepareCommand = '' ${pkgs.docker-client}/bin/docker exec -t firefly-db pg_dumpall -c -U firefly > "${backupDir}/postgres.sql" ''; rcloneConfigFile = config.age.secrets."rclone-pie.conf".path; }; }; }