about summary refs log tree commit diff
path: root/nix/hosts/corrino/www
diff options
context:
space:
mode:
Diffstat (limited to 'nix/hosts/corrino/www')
-rw-r--r--nix/hosts/corrino/www/ctf.emile.space.nix21
-rw-r--r--nix/hosts/corrino/www/git/cgit.nix6
-rw-r--r--nix/hosts/corrino/www/git/git.nix106
-rw-r--r--nix/hosts/corrino/www/goapp.emile.space.nix8
-rw-r--r--nix/hosts/corrino/www/grafana.emile.space.nix256
-rw-r--r--nix/hosts/corrino/www/hydra.emile.space.nix7
-rw-r--r--nix/hosts/corrino/www/irc.emile.space.nix345
-rw-r--r--nix/hosts/corrino/www/loki.emile.space.nix64
-rw-r--r--nix/hosts/corrino/www/mc.emile.space.nix5
-rw-r--r--nix/hosts/corrino/www/md.emile.space.nix35
-rw-r--r--nix/hosts/corrino/www/miniflux.emile.space.nix80
-rw-r--r--nix/hosts/corrino/www/photo/immich.nix39
-rw-r--r--nix/hosts/corrino/www/prometheus.emile.space.nix36
-rw-r--r--nix/hosts/corrino/www/promtail.emile.space.nix114
-rw-r--r--nix/hosts/corrino/www/s3.emile.space.nix105
-rw-r--r--nix/hosts/corrino/www/sb.emile.space.nix114
-rw-r--r--nix/hosts/corrino/www/social.emile.space.nix25
-rw-r--r--nix/hosts/corrino/www/tickets.emile.space.nix2
18 files changed, 586 insertions, 782 deletions
diff --git a/nix/hosts/corrino/www/ctf.emile.space.nix b/nix/hosts/corrino/www/ctf.emile.space.nix
index 28c9419..a6ebd05 100644
--- a/nix/hosts/corrino/www/ctf.emile.space.nix
+++ b/nix/hosts/corrino/www/ctf.emile.space.nix
@@ -7,18 +7,19 @@
 
     locations = {
       "/" = {
-        proxyPass = "http://127.0.0.1:${toString config.emile.ports.ctf}";
+        # proxyPass = "http://127.0.0.1:${toString config.emile.ports.ctf}";
+        proxyPass = "http://138.199.213.51";
       };
     };
   };
 
-  virtualisation.oci-containers = {
-    # backend = "docker";
-    containers = {
-      "ctfd" = {
-        image = "ctfd/ctfd";
-        ports = [ "${toString config.emile.ports.ctf}:8000" ];
-      };
-    };
-  };
+  # virtualisation.oci-containers = {
+  #   # backend = "docker";
+  #   containers = {
+  #     "ctfd" = {
+  #       image = "ctfd/ctfd";
+  #       ports = [ "${toString config.emile.ports.ctf}:8000" ];
+  #     };
+  #   };
+  # };
 }
diff --git a/nix/hosts/corrino/www/git/cgit.nix b/nix/hosts/corrino/www/git/cgit.nix
index 68304db..44f5996 100644
--- a/nix/hosts/corrino/www/git/cgit.nix
+++ b/nix/hosts/corrino/www/git/cgit.nix
@@ -630,7 +630,13 @@ in
     extraGroups = [ "gitea" ];
     home = "/var/lib/git";
     uid = lib.mkForce 127;
+    # shell = "${pkgs.git}/bin/git-shell";
+    #   openssh.authorizedKeys.keys = [
+    #     "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIPZi43zHEsoWaQomLGaftPE5k0RqVrZyiTtGqZlpWsew emile@caladan
+    # "
+    # ];
   };
+  
   users.groups.git = {
     gid = lib.mkForce 127;
   };
diff --git a/nix/hosts/corrino/www/git/git.nix b/nix/hosts/corrino/www/git/git.nix
deleted file mode 100644
index 3a2b9da..0000000
--- a/nix/hosts/corrino/www/git/git.nix
+++ /dev/null
@@ -1,106 +0,0 @@
-{
-  lib,
-  pkgs,
-  config,
-  ...
-}:
-
-let
-  cfg = config.services.gitea;
-in
-{
-  services.nginx.virtualHosts."git.emile.space" = {
-    forceSSL = true;
-    enableACME = true;
-
-    # TODO(emile): figure out why this doesn't work when enabled, has to do with authelia
-    # extraConfig = authelia-location;
-
-    locations = {
-      "/" = {
-        # proxyPass = "http://127.0.0.1:3000";
-        proxyPass = "http://127.0.0.1:${toString config.services.gitea.settings.server.HTTP_PORT}";
-
-        # TODO(emile): figure out why this doesn't work when enabled, has to do with authelia
-        # extraConfig = authelia-authrequest;
-      };
-    };
-  };
-
-  # auth via authelia
-  services.authelia.instances.main.settings.identity_providers.oidc.clients = [
-    {
-      id = "git";
-
-      # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      secret = "$pbkdf2-sha512$310000$4bi9wRkfcqnjbdmgt7rU.g$pQ2mC6GW4.BQwanGKKFhFyIx6Y.WY80xd/YpmlYOPnlnGBWpp0dSOTv6a/2yqSA5D.EuRkGCyeexSE5FdCK2TA";
-      public = false;
-      authorization_policy = "two_factor";
-      redirect_uris = [ "https://git.emile.space/user/oauth2/authelia/callback" ];
-      scopes = [
-        "openid"
-        "email"
-        "profile"
-      ];
-    }
-  ];
-
-  services.gitea = rec {
-    enable = true;
-
-    appName = "git.emile.space";
-
-    # unstable in order to use the 1.20... version
-    #package = pkgs.forgejo;
-    package = pkgs.unstable.forgejo;
-
-    stateDir = "/var/lib/gitea";
-    repositoryRoot = "${stateDir}/repositories";
-
-    settings = {
-      service.DISABLE_REGISTRATION = true;
-
-      DEFAULT = {
-        WORK_PATH = "/var/lib/gitea";
-      };
-
-      server = {
-        DOMAIN = pkgs.lib.mkForce "git.emile.space";
-        ROOT_URL = pkgs.lib.mkForce "https://git.emile.space";
-        HTTP_PORT = config.emile.ports.git;
-
-        #START_SSH_SERVER = true;
-        BUILTIN_SSH_SERVER_USER = "git";
-        SSH_USER = "gitea";
-        SSH_DOMAIN = "git.emile.space";
-
-        REPO_INDEXER_ENABLED = true;
-      };
-
-      indexer = {
-        REPO_INDEXER_ENABLED = true;
-        ISSUE_INDEXER_PATH = "${stateDir}/indexers/issues.bleve";
-        REPO_INDEXER_PATH = "${stateDir}/indexers/repos.bleve";
-        MAX_FILE_SIZE = 1048576;
-        REPO_INDEXER_INCLUDE = "";
-        REPO_INDEXER_EXCLUDE = "resources/bin/**";
-      };
-
-      #federation = {
-      #  enable = true;
-      #  share_user_statistics = true;
-      #  max_size = 4;
-      #};
-    };
-  };
-
-  users.users.git = {
-    isSystemUser = true;
-    useDefaultShell = true;
-    group = "git";
-    extraGroups = [ "gitea" ];
-    home = cfg.stateDir;
-    uid = 127;
-  };
-  users.groups.git = { };
-}
diff --git a/nix/hosts/corrino/www/goapp.emile.space.nix b/nix/hosts/corrino/www/goapp.emile.space.nix
index 361e95a..e31079e 100644
--- a/nix/hosts/corrino/www/goapp.emile.space.nix
+++ b/nix/hosts/corrino/www/goapp.emile.space.nix
@@ -12,12 +12,16 @@
     };
   };
 
+  age.secrets.goapp_oidc_client_secret.owner = "authelia-main";
+  age.secrets.goapp_oidc_client_secret.group = "authelia-main";
+  
   services.authelia.instances.main.settings.identity_providers.oidc.clients = [
     {
-      id = "goapp";
+      client_id = "goapp";
 
       # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      secret = "$pbkdf2-sha512$310000$LPXJRoGR9RyTcaT6cADljg$FK8RV5CnKj5ano4fXmRzzvXcX/00F7k/G6nd67t.8iewpwyq8FntV4JgYZSV8AynYMxz1qnL4j3BzITLCM0KgQ";
+      client_secret = "{{ secret \"${config.age.secrets.goapp_oidc_client_secret.path}\" }}";
+
       public = false;
       authorization_policy = "two_factor";
       redirect_uris = [
diff --git a/nix/hosts/corrino/www/grafana.emile.space.nix b/nix/hosts/corrino/www/grafana.emile.space.nix
index f8674a2..2caa4d4 100644
--- a/nix/hosts/corrino/www/grafana.emile.space.nix
+++ b/nix/hosts/corrino/www/grafana.emile.space.nix
@@ -3,145 +3,143 @@
 {
   systemd.services.grafana.serviceConfig.EnvironmentFile = config.age.secrets.grafana_env_vars.path;
 
-  services = {
-    nginx.virtualHosts = {
-      "grafana.emile.space" = {
-        addSSL = true;
-        enableACME = true;
-        locations."/" = {
-          proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}/";
-          proxyWebsockets = true;
-        };
+  
+  services.nginx.virtualHosts = {
+    "grafana.emile.space" = {
+      addSSL = true;
+      enableACME = true;
+      locations."/" = {
+        proxyPass = "http://${toString config.services.grafana.settings.server.http_addr}:${toString config.services.grafana.settings.server.http_port}/";
+        proxyWebsockets = true;
       };
     };
+  };
 
-    authelia.instances.main.settings.identity_providers.oidc.clients = [
-      {
-        id = "Grafana";
-
-        # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-        secret = "$pbkdf2-sha512$310000$S.RE0jcmr7Sn/tjJDNxV/A$1tsYhQ/YEcVfE4JyzszHemrcUqy.84Fb6xVSmz87if5C9N46Mz2lRWB5l8s4EIrLsiumPnt4HQMkYZ4MoovJzA";
-        public = false;
-        authorization_policy = "two_factor";
-        redirect_uris = [ "https://grafana.emile.space/login/generic_oauth" ];
-        scopes = [
-          "openid"
-          "email"
-          "profile"
-          "groups"
-        ];
-        grant_types = [
-          "refresh_token"
-          "authorization_code"
-        ];
-        response_types = [ "code" ];
-        response_modes = [
-          "form_post"
-          "query"
-          "fragment"
-        ];
-      }
-    ];
-
-    grafana = {
-      enable = true;
-      settings = {
-        server = {
-          http_addr = "127.0.0.1";
-          http_port = config.emile.ports.grafana;
-          domain = "grafana.emile.space";
-          root_url = "https://grafana.emile.space/";
-        };
+  age.secrets.grafana_oidc_client_secret.owner = "authelia-main";
+  age.secrets.grafana_oidc_client_secret.group = "authelia-main";
 
-        "auth.generic_oauth" =
-          let
-            sso = "https://sso.emile.space/api/oidc";
-          in
-          {
-            enabled = true;
-            client_id = "Grafana";
-
-            # [auth.generic_oauth]
-            # client_secret = ... 
-            #   set in env var as 
-            #   GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET 
-            client_secret = "set in env var this is just a placeholder";
-
-            use_refresh_token = true;
-            token_url = "${sso}/token";
-            auth_url = "${sso}/authorization";
-            api_url = "${sso}/userinfo";
-
-            scopes = [
-              "openid"
-              "email"
-              "profile"
-              "groups"
-            ];
-
-            email_attribute_path = "email";
-            login_attribute_path = "preferred_username";
-            name_attribute_path = "name";
-
-            role_attribute_path = "contains(groups[*], 'grafana_server_admin') && 'GrafanaAdmin' || contains(groups[*], 'grafana_admin') && 'Admin' || contains(groups[*], 'grafana_editor') && 'Editor' || 'Viewer'";
-
-          };
+  services.authelia.instances.main.settings.identity_providers.oidc.clients = [
+    {
+      client_id = "Grafana";
+
+      # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
+      client_secret = "{{ secret \"${config.age.secrets.grafana_oidc_client_secret.path}\" }}";
+
+      public = false;
+      authorization_policy = "two_factor";
+      redirect_uris = [ "https://grafana.emile.space/login/generic_oauth" ];
+      scopes = [
+        "openid"
+        "email"
+        "profile"
+        "groups"
+      ];
+      grant_types = [
+        "refresh_token"
+        "authorization_code"
+      ];
+      response_types = [ "code" ];
+      response_modes = [
+        "form_post"
+        "query"
+        "fragment"
+      ];
+    }
+  ];
+
+  services.grafana = {
+    enable = true;
+    settings = {
+      server = {
+        http_addr = "127.0.0.1";
+        http_port = config.emile.ports.grafana;
+        domain = "grafana.emile.space";
+        root_url = "https://grafana.emile.space/";
       };
 
-      provision = {
-        dashboards.settings = { };
-        datasources.settings = {
-          deleteDatasources = [
-            { name = "Prometheus"; orgId = 1; }  
-            { name = "Lampadas"; orgId = 1; }  
-          ];
-          datasources = [
-            {
-              url = "http://localhost:${toString config.services.prometheus.port}";
-              type = "prometheus";
-              name = "Prometheus Corrino";
-              editable = false;
-              access = "proxy"; # server = "proxy", browser = "direct"
-            }
-            {
-              url = "http://lampadas:9009";
-              type = "prometheus";
-              name = "Prometheus Lampadas";
-              editable = false;
-              access = "proxy"; # server = "proxy", browser = "direct"
-            }
-            # {
-            #   name = "loki";
-            #   url = "http://${config.services.loki.configuration.common.instance_addr}:${toString config.services.loki.configuration.server.http_listen_port}";
-            #   type = "loki";
-            # }
+      "auth.generic_oauth" =
+        let
+          sso = "https://sso.emile.space/api/oidc";
+        in
+        {
+          enabled = true;
+          client_id = "Grafana";
+
+          # [auth.generic_oauth]
+          # client_secret = ... 
+          #   set in env var as 
+          #   GF_AUTH_GENERIC_OAUTH_CLIENT_SECRET 
+          client_secret = "set in env var this is just a placeholder";
+
+          use_refresh_token = true;
+          token_url = "${sso}/token";
+          auth_url = "${sso}/authorization";
+          api_url = "${sso}/userinfo";
+
+          scopes = [
+            "openid"
+            "email"
+            "profile"
+            "groups"
           ];
+
+          email_attribute_path = "email";
+          login_attribute_path = "preferred_username";
+          name_attribute_path = "name";
+
+          role_attribute_path = "contains(groups[*], 'grafana_server_admin') && 'GrafanaAdmin' || contains(groups[*], 'grafana_admin') && 'Admin' || contains(groups[*], 'grafana_editor') && 'Editor' || 'Viewer'";
+
         };
+    };
 
-        # TODO(emile): finish setting up the grafana notifier filling out the settings section
-        # notifiers = [
-        #   {
-        #     uid = "2ad1c1d1-bcd9-4cb8-8897-c89c5820ffb1";
-        #     type = "email";
-        #     settings = {};
-        #     org_name = "Main Org.";
-        #     org_id = 1;
-        #     name = "email";
-        #     id_default = true;
-        #     frequency = "5m";
-        #     disable_resolve_message = false;
-        #   }
-        # ];
-
-        # TODO(emile): finish setting up the alerting stuff within here
-        # alerting = {
-        #   templates.settings = { };
-        #   rules.settings = {};
-        #   policies.settings = {};
-        #   muteTimings.settings = {};
-        #   contactPoints.settings = {};
-        # };
+    provision = {
+      dashboards.settings = { };
+      datasources.settings = {
+        deleteDatasources = [
+          { name = "Prometheus"; orgId = 1; }  
+          { name = "Lampadas"; orgId = 1; }  
+        ];
+        datasources = [
+          {
+            url = "http://localhost:${toString config.services.prometheus.port}";
+            type = "prometheus";
+            name = "Prometheus Corrino";
+            editable = false;
+            access = "proxy"; # server = "proxy", browser = "direct"
+          }
+          {
+            url = "http://lampadas:9009";
+            type = "prometheus";
+            name = "Prometheus Lampadas";
+            editable = false;
+            access = "proxy"; # server = "proxy", browser = "direct"
+          }
+        ];
       };
+
+      # TODO(emile): finish setting up the grafana notifier filling out the settings section
+      # notifiers = [
+      #   {
+      #     uid = "2ad1c1d1-bcd9-4cb8-8897-c89c5820ffb1";
+      #     type = "email";
+      #     settings = {};
+      #     org_name = "Main Org.";
+      #     org_id = 1;
+      #     name = "email";
+      #     id_default = true;
+      #     frequency = "5m";
+      #     disable_resolve_message = false;
+      #   }
+      # ];
+
+      # TODO(emile): finish setting up the alerting stuff within here
+      # alerting = {
+      #   templates.settings = { };
+      #   rules.settings = {};
+      #   policies.settings = {};
+      #   muteTimings.settings = {};
+      #   contactPoints.settings = {};
+      # };
     };
   };
 }
diff --git a/nix/hosts/corrino/www/hydra.emile.space.nix b/nix/hosts/corrino/www/hydra.emile.space.nix
index a5cdb53..fe70bf4 100644
--- a/nix/hosts/corrino/www/hydra.emile.space.nix
+++ b/nix/hosts/corrino/www/hydra.emile.space.nix
@@ -21,9 +21,10 @@
   services.hydra = {
     enable = true;
 
-    package = pkgs.hydra_unstable.overrideAttrs (old: {
-      patches = (if old ? patches then old.patches else [ ]) ++ [ ./hydra.patch ];
-    });
+    #package = pkgs.hydra_unstable.overrideAttrs (old: {
+    #  patches = (if old ? patches then old.patches else [ ]) ++ [ ./hydra.patch ];
+    #});
+    package = pkgs.hydra;
 
     listenHost = "*";
     port = config.emile.ports.hydra;
diff --git a/nix/hosts/corrino/www/irc.emile.space.nix b/nix/hosts/corrino/www/irc.emile.space.nix
index ac00445..7653cb4 100644
--- a/nix/hosts/corrino/www/irc.emile.space.nix
+++ b/nix/hosts/corrino/www/irc.emile.space.nix
@@ -1,155 +1,198 @@
-{ config, ... }:
+{ config, pkgs, ... }:
 
 {
+  ##############################################################################
+  # Client
+  ##############################################################################
+  # gamja web client
+  # https://codeberg.org/emersion/gamja
+  #
+  # nah, let's just use the commaond line "senpai" client, from the same person
+
+  ##############################################################################
+  # Bouncer
+  ##############################################################################
+  # soju bouncer
+  # https://soju.im
+
+  # services.soju = {
+  #   enable = true;
+  #   listen = [ "127.0.0.1:${toString config.emile.ports.irc.bouncer}" ];
+
+  #   hostName = "irc.emile.space";
+  #   httpOrigins = [ "127.0.0.1" "irc.emile.space" ];
+
+  #   # tlsCertificateKey = "/var/lib/acme/irc.emile.space/key.pem";
+  #   # tlsCertificate = "/var/lib/acme/irc.emile.space/cert.pem";
+  # };
+
+  # services.soju = {
+  #   enable = true;
+  #   package = pkgs.soju;
+  #   listen = [ "127.0.0.1:${toString config.emile.ports.irc.bouncer}" ];
+  #   adminSocket.enable = true;
+  #   # tlsCertificateKey = "/var/lib/acme/irc.emile.space/key.pem";
+  #   # tlsCertificate = "/var/lib/acme/irc.emile.space/cert.pem";
+  #   httpOrigins = [ "127.0.0.1" "irc.emile.space" ];
+  #   hostName = "irc.emile.space";
+  #   extraConfig = "";
+  #   enableMessageLogging = true;
+  #   acceptProxyIP = [];
+  # };
+
+  ##############################################################################
+  # Server
+  ##############################################################################
+
   # Create a tls cert for the irc server
-  security.acme.certs = {
-    "irc.emile.space" = {
-      webroot = "/var/lib/acme/acme-challenge/";
-      email = "acme@emile.space";
-      postRun = "cp fullchain.pem /home/ergo/ && cp key.pem /home/ergo && chown ergo:ergo /home/ergo/*.pem && systemctl reload ergo.service";
-    };
-  };
-
-  # Allow ergo to access the created cert
-  # The systemd server runs using a dynamic user, so the below inserts the .pem files
-  #   into "/run/credentials/ergochat.service/key.pem"
-  systemd.services.ergochat.serviceConfig = {
-    LoadCredential = [
-      "fullchain.pem:/var/lib/acme/irc.emile.space/fullchain.pem"
-      "key.pem:/var/lib/acme/irc.emile.space/key.pem"
-    ];
-  };
-
-  # allow connections to the port from the "outside"
-  networking.firewall.allowedTCPPorts = [ config.emile.ports.irc.ssl ];
-
-  services.ergochat = {
-    enable = true;
-
-    # https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml
-    settings = {
-      accounts = {
-        authentication-enabled = true;
-        multiclient = {
-          allowed-by-default = true;
-          always-on = "opt-out";
-          auto-away = "opt-out";
-          enabled = true;
-        };
-        registration = {
-          enabled = true;
-          allow-before-connect = true;
-          bcrypt-cost = 4;
-          email-verification = {
-            enabled = false;
-          };
-          throttling = {
-            duration = "10m";
-            enabled = true;
-            max-attempts = 30;
-          };
-        };
-      };
-      channels = {
-        default-modes = "+ntC";
-        registration = {
-          enabled = true;
-        };
-      };
-      datastore = {
-        autoupgrade = true;
-        path = "/var/lib/ergo/ircd.db";
-      };
-      history = {
-        enabled = true;
-        autoreplay-on-join = 0;
-        autoresize-window = "3d";
-        channel-length = 2048;
-        chathistory-maxmessages = 100;
-        client-length = 256;
-        restrictions = {
-          expire-time = "1w";
-          grace-period = "1h";
-          query-cutoff = "none";
-        };
-        retention = {
-          allow-individual-delete = false;
-          enable-account-indexing = false;
-        };
-        tagmsg-storage = {
-          default = false;
-          whitelist = [
-            "+draft/react"
-            "+react"
-          ];
-        };
-        znc-maxmessages = 2048;
-      };
-      limits = {
-        awaylen = 390;
-        channellen = 64;
-        identlen = 20;
-        kicklen = 390;
-        nicklen = 32;
-        topiclen = 390;
-      };
-      network = {
-        name = "emilespace";
-      };
-      server = {
-        casemapping = "permissive";
-        check-ident = false;
-        enforce-utf = true;
-        forward-confirm-hostnames = false;
-        ip-cloaking = {
-          enabled = false;
-        };
-        ip-limits = {
-          count = false;
-          throttle = false;
-        };
-        listeners = {
-          # sts only port
-          ":6667".sts-only = true;
-
-          # loopback listeners
-          # "127.0.0.1:6668" = {};
-          # "[::]:6668" = {};
-
-          ":${toString config.emile.ports.irc.ssl}" = {
-            tls = {
-              cert = "/run/credentials/ergochat.service/fullchain.pem";
-              key = "/run/credentials/ergochat.service/key.pem";
-            };
-
-            # for cloud load balancers setting a PROXY header, NOT reverse proxies...
-            proxy = false;
-
-            min-tls-version = 1.2;
-          };
-        };
-        lookup-hostnames = false;
-        max-sendq = "1M";
-        name = "emile.space";
-        relaymsg = {
-          enabled = false;
-        };
-        sts = {
-          enabled = true; # redirect from plain to tls if supported
-
-          # how long clients should be forced to use TLS for.
-          # (Emile): no clue why, can I set something like \infty here?
-          duration = "12m";
-
-        };
-      };
-      logging = [
-        {
-          method = "stderr";
-          type = "* -userinput -useroutput";
-          level = "debug";
-        }
-      ];
-    };
-  };
+  # security.acme.certs = {
+  #   "irc.emile.space" = {
+  #     webroot = "/var/lib/acme/acme-challenge/";
+  #     email = "acme@emile.space";
+  #     # postRun = "cp fullchain.pem /home/ergo/ && cp key.pem /home/ergo && chown ergo:ergo /home/ergo/*.pem && systemctl reload ergo.service";
+  #   };
+  # };
+
+  # # Allow ergo to access the created cert
+  # # The systemd server runs using a dynamic user, so the below inserts the .pem files
+  # #   into "/run/credentials/ergochat.service/key.pem"
+  # systemd.services.ergochat.serviceConfig = {
+  #   LoadCredential = [
+  #     "fullchain.pem:/var/lib/acme/irc.emile.space/fullchain.pem"
+  #     "key.pem:/var/lib/acme/irc.emile.space/key.pem"
+  #   ];
+  # };
+
+  # # allow connections to the port from the "outside"
+  # networking.firewall.allowedTCPPorts = [ config.emile.ports.irc.ssl ];
+
+  # services.ergochat = {
+  #   enable = true;
+
+  #   # https://raw.githubusercontent.com/ergochat/ergo/master/default.yaml
+  #   settings = {
+  #     accounts = {
+  #       authentication-enabled = true;
+  #       multiclient = {
+  #         allowed-by-default = true;
+  #         always-on = "opt-out";
+  #         auto-away = "opt-out";
+  #         enabled = true;
+  #       };
+  #       registration = {
+  #         enabled = true;
+  #         allow-before-connect = true;
+  #         bcrypt-cost = 4;
+  #         email-verification = {
+  #           enabled = false;
+  #         };
+  #         throttling = {
+  #           duration = "10m";
+  #           enabled = true;
+  #           max-attempts = 30;
+  #         };
+  #       };
+  #     };
+  #     channels = {
+  #       default-modes = "+ntC";
+  #       registration = {
+  #         enabled = true;
+  #       };
+  #     };
+  #     datastore = {
+  #       autoupgrade = true;
+  #       path = "/var/lib/ergo/ircd.db";
+  #     };
+  #     history = {
+  #       enabled = true;
+  #       autoreplay-on-join = 0;
+  #       autoresize-window = "3d";
+  #       channel-length = 2048;
+  #       chathistory-maxmessages = 100;
+  #       client-length = 256;
+  #       restrictions = {
+  #         expire-time = "1w";
+  #         grace-period = "1h";
+  #         query-cutoff = "none";
+  #       };
+  #       retention = {
+  #         allow-individual-delete = false;
+  #         enable-account-indexing = false;
+  #       };
+  #       tagmsg-storage = {
+  #         default = false;
+  #         whitelist = [
+  #           "+draft/react"
+  #           "+react"
+  #         ];
+  #       };
+  #       znc-maxmessages = 2048;
+  #     };
+  #     limits = {
+  #       awaylen = 390;
+  #       channellen = 64;
+  #       identlen = 20;
+  #       kicklen = 390;
+  #       nicklen = 32;
+  #       topiclen = 390;
+  #     };
+  #     network = {
+  #       name = "emilespace";
+  #     };
+  #     server = {
+  #       casemapping = "permissive";
+  #       check-ident = false;
+  #       enforce-utf = true;
+  #       forward-confirm-hostnames = false;
+  #       ip-cloaking = {
+  #         enabled = false;
+  #       };
+  #       ip-limits = {
+  #         count = false;
+  #         throttle = false;
+  #       };
+  #       listeners = {
+  #         # sts only port
+  #         ":6667".sts-only = true;
+
+  #         # loopback listeners
+  #         # "127.0.0.1:6668" = {};
+  #         # "[::]:6668" = {};
+
+  #         ":${toString config.emile.ports.irc.ssl}" = {
+  #           tls = {
+  #             cert = "/run/credentials/ergochat.service/fullchain.pem";
+  #             key = "/run/credentials/ergochat.service/key.pem";
+  #           };
+
+  #           # for cloud load balancers setting a PROXY header, NOT reverse proxies...
+  #           proxy = false;
+
+  #           min-tls-version = 1.2;
+  #         };
+  #       };
+  #       lookup-hostnames = false;
+  #       max-sendq = "1M";
+  #       name = "emile.space";
+  #       relaymsg = {
+  #         enabled = false;
+  #       };
+  #       sts = {
+  #         enabled = true; # redirect from plain to tls if supported
+
+  #         # how long clients should be forced to use TLS for.
+  #         # (Emile): no clue why, can I set something like \infty here?
+  #         duration = "12m";
+
+  #       };
+  #     };
+  #     logging = [
+  #       {
+  #         method = "stderr";
+  #         type = "* -userinput -useroutput";
+  #         level = "debug";
+  #       }
+  #     ];
+  #   };
+  # };
 }
diff --git a/nix/hosts/corrino/www/loki.emile.space.nix b/nix/hosts/corrino/www/loki.emile.space.nix
deleted file mode 100644
index e5bfe24..0000000
--- a/nix/hosts/corrino/www/loki.emile.space.nix
+++ /dev/null
@@ -1,64 +0,0 @@
-{ config, ... }:
-
-{
-  services = {
-    loki = {
-      enable = false;
-      configuration = {
-        auth_enabled = false;
-        server = {
-          http_listen_port = config.emile.ports.loki;
-        };
-
-        limits_config = {
-          reject_old_samples = false;
-          reject_old_samples_max_age = "7d";
-          max_global_streams_per_user = 100000;
-          max_streams_per_user = 100000;
-
-          retention_period = "10m";
-        };
-
-        compactor = {
-          retention_enabled = true;
-          delete_request_store = "tsdb";
-        };
-
-        common = {
-          instance_addr = "127.0.0.1";
-          ring = {
-            instance_addr = "127.0.0.1";
-            kvstore.store = "inmemory";
-          };
-          replication_factor = 1;
-          path_prefix = "/tmp/loki";
-        };
-
-        # limits_config.allow_structured_metadata = false;
-
-        schema_config.configs = [
-          {
-            from = "2023-05-09";
-            store = "tsdb";
-            object_store = "filesystem";
-            schema = "v13";
-            index = {
-              prefix = "index_";
-              period = "24h";
-            };
-          }
-          {
-            from = "2024-10-18";
-            store = "tsdb";
-            object_store = "filesystem";
-            schema = "v13";
-            index = {
-              prefix = "index_";
-              period = "24h";
-            };
-          }
-        ];
-      };
-    };
-  };
-}
diff --git a/nix/hosts/corrino/www/mc.emile.space.nix b/nix/hosts/corrino/www/mc.emile.space.nix
index 8250a1d..1a081bc 100644
--- a/nix/hosts/corrino/www/mc.emile.space.nix
+++ b/nix/hosts/corrino/www/mc.emile.space.nix
@@ -134,10 +134,13 @@
     addons = {};
   };
 
+  services.restic.backups."corrino" = {
+    paths = [ "/var/lib/minecraft" ];
+  };
+
   services.restic.backups."minecraft" = {
     repository = "/mnt/storagebox-bx11/minecraft";
     paths = [ "/var/lib/minecraft" ];
-    timerConfig = null;
     passwordFile = config.age.secrets.restic_password.path;
     initialize = true;
     pruneOpts = [
diff --git a/nix/hosts/corrino/www/md.emile.space.nix b/nix/hosts/corrino/www/md.emile.space.nix
index d94c06c..1ee46fd 100644
--- a/nix/hosts/corrino/www/md.emile.space.nix
+++ b/nix/hosts/corrino/www/md.emile.space.nix
@@ -11,13 +11,16 @@
     };
   };
 
+  age.secrets.hedgedoc_oidc_client_secret.owner = "authelia-main";
+  age.secrets.hedgedoc_oidc_client_secret.group = "authelia-main";
+  
   # auth via authelia
   services.authelia.instances.main.settings.identity_providers.oidc.clients = [
     {
       client_id = "HedgeDoc";
 
       # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      client_secret = "$pbkdf2-sha512$310000$l4Kyec7Q9oY2GAhWA/xMig$P/MYFmulfgsDNyyiclUzd6le0oSiOvqCIvl4op5DkXtVTxLWlMA3ZwhJ6Z7u.OfIREuEM2htH6asxWPhBhkpNQ";
+      client_secret = "{{ secret \"${config.age.secrets.hedgedoc_oidc_client_secret.path}\" }}";
       public = false;
       authorization_policy = "two_factor";
       redirect_uris = [ "https://md.emile.space/auth/oauth2/callback" ];
@@ -85,10 +88,13 @@
     };
   };
 
+  services.restic.backups."corrino" = {
+    paths = [ "/var/lib/hedgedoc" ];
+  };
+
   services.restic.backups."hedgedoc" = {
     repository = "/mnt/storagebox-bx11/hedgedoc";
     paths = [ "/var/lib/hedgedoc" ];
-    timerConfig = null;
     passwordFile = config.age.secrets.restic_password.path;
     initialize = true;
     pruneOpts = [
@@ -98,29 +104,4 @@
       "--keep-yearly 75"
     ];
   };
-
-  # backups
-  # services.restic.backups."hedgedoc" = {
-  #   user = "u331921";
-  #   timerConfig = {
-  #     OnCalendar = "daily";
-  #     Persistent = true;
-  #   };
-  #   # repository = "stfp:u331921@u331921.your-storagebox-de:23/restic";
-  #   repository = "/mnt/storagebox-bx11/backup/hedgedoc";
-  #   initialize = true; # initializes the repo, don't set if you want manual control
-  #   passwordFile = config.age.secrets.restic_password.path;
-  #   paths = [ "/var/lib/hedgedoc/" ];
-  #   pruneOpts = [
-  #     "--keep-daily 7"
-  #     "--keep-weekly 5"
-  #     "--keep-monthly 12"
-  #     "--keep-yearly 75"
-  #   ];
-
-  #   # extraOpts = [
-  #   #   "sftp.command='ssh backup@192.168.1.100 -i /home/user/.ssh/id_rsa -s sftp'"
-  #   # ];
-  # };
-
 }
diff --git a/nix/hosts/corrino/www/miniflux.emile.space.nix b/nix/hosts/corrino/www/miniflux.emile.space.nix
index f5b9817..90cb8f2 100644
--- a/nix/hosts/corrino/www/miniflux.emile.space.nix
+++ b/nix/hosts/corrino/www/miniflux.emile.space.nix
@@ -11,39 +11,48 @@
 		};
 	};
 
+	# oidc not working and I can't bother to continue debugging it now
+	# 
+	# Apr 12 15:37:38 corrino authelia[3693799]: {"level":"error","method":"POST","msg":"Access Request failed with error: Client authentication failed (e.g., unknown client, no client authentication included, or unsupported authentication method). The request was determined to be using 'token_endpoint_auth_method' method 'none', however the OAuth 2.0 client registration does not allow this method. The registered client with id 'miniflux' is configured to only support 'token_endpoint_auth_method' method 'client_secret_basic'. Either the Authorization Server client registration will need to have the 'token_endpoint_auth_method' updated to 'none' or the Relying Party will need to be configured to use 'client_secret_basic'.
+	#
+  # age.secrets.miniflux_oidc_client_secret.owner = "authelia-main";
+  # age.secrets.miniflux_oidc_client_secret.group = "authelia-main";
+	# 
   # auth via authelia
-  services.authelia.instances.main.settings.identity_providers.oidc.clients = [
-    {
-      id = "miniflux";
+  # services.authelia.instances.main.settings.identity_providers.oidc.clients = [
+  #   {
+  #     client_id = "miniflux";
 
-      # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      secret = "$pbkdf2-sha512$310000$rlOuqUDGc/kl3bw7JgcSpg$4COyNudsu/7L8qhnxfcQld5Fy.ru/JUp7RCI7dCHZMtzxRnhckW8A7uz3Xeuc7.BjCIwc4GdWusPt6.TiH6Kpw";
-      public = false;
-      authorization_policy = "two_factor";
-      redirect_uris = [ "https://miniflux.emile.space/oauth2/oidc/callback" ];
-      scopes = [
-        "openid"
-        "email"
-        "profile"
-      ];
-      grant_types = [
-        "refresh_token"
-        "authorization_code"
-      ];
-      response_types = [ "code" ];
-      response_modes = [
-        "form_post"
-        "query"
-        "fragment"
-      ];
-      token_endpoint_auth_method = "client_secret_post";
-    }
-  ];
+  #     # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
+	#     client_secret = "{{ secret \"${config.age.secrets.miniflux_oidc_client_secret.path}\" }}";
+  #     public = false;
+  #     authorization_policy = "two_factor";
+  #     redirect_uris = [ "https://miniflux.emile.space/oauth2/oidc/callback" ];
+  #     scopes = [
+  #       "openid"
+  #       "email"
+  #       "profile"
+  #     ];
+  #     # grant_types = [
+  #     #   "refresh_token"
+  #     #   "authorization_code"
+  #     # ];
+  #     # response_types = [ "code" ];
+  #     # response_modes = [
+  #     #   "form_post"
+  #     #   "query"
+  #     #   "fragment"
+  #     # ];
+  #     # token_endpoint_auth_method = "client_secret_post";
+  #     # token_endpoint_auth_method = "none";
+  #   }
+  # ];
 
 	services.miniflux = {
 		enable = true;
 		package = pkgs.miniflux;
 		config = {
+		  LISTEN_ADDR = "[::1]:${toString config.emile.ports.miniflux}";
 			BASE_URL = "https://miniflux.emile.space";
 
 			# Cleanup job frequency to remove old sessions and archive entries.
@@ -53,21 +62,20 @@
 			# MAINTENANCE_MODE = 1;
 			# MAINTENANCE_MESSAGE = "updating foo";
 			
-			OAUTH2_CLIENT_ID = "miniflux";
-			OAUTH2_CLIENT_SECRET_FILE = config.age.secrets.miniflux_oidc_secret.path;
-			OAUTH2_OIDC_DISCOVERY_ENDPOINT = "sso.emile.space";
-			OAUTH2_OIDC_PROVIDER_NAME = "authelia";
-			OAUTH2_PROVIDER = "oidc";
-			OAUTH2_REDIRECT_URL = "https://miniflux.emile.space/oauth2/oidc/callback";
+			# DISABLE_LOCAL_AUTH = "true";
+			# OAUTH2_CLIENT_ID = "miniflux";
+			# OAUTH2_USER_CREATION = 1;
+			# OAUTH2_CLIENT_SECRET_FILE = config.age.secrets.miniflux_oidc_secret.path;
+			# OAUTH2_OIDC_DISCOVERY_ENDPOINT = "https://sso.emile.space";
+			# OAUTH2_OIDC_PROVIDER_NAME = "authelia";
+			# OAUTH2_PROVIDER = "oidc";
+			# OAUTH2_REDIRECT_URL = "https://miniflux.emile.space/oauth2/oidc/callback";
 			
-		  LISTEN_ADDR = "[::1]:${toString config.emile.ports.miniflux}";
+			LOG_LEVEL = "debug";
 		};
 		createDatabaseLocally = true;
 
 		# File containing the ADMIN_USERNAME and ADMIN_PASSWORD (length >= 6) in the format of an EnvironmentFile=, as described by systemd.exec(5).
 		adminCredentialsFile = config.age.secrets.miniflux_admin_file.path;
 	};
-	
-
-
 }
diff --git a/nix/hosts/corrino/www/photo/immich.nix b/nix/hosts/corrino/www/photo/immich.nix
index 92a3a64..3e1bf48 100644
--- a/nix/hosts/corrino/www/photo/immich.nix
+++ b/nix/hosts/corrino/www/photo/immich.nix
@@ -6,6 +6,15 @@
     forceSSL = true;
     enableACME = true;
     locations = {
+      # # immich private proxy
+      # "/share" = {
+      #   proxyPass = "http://${config.services.immich.host}:${toString config.services.immich-public-proxy.port}";
+      # };
+      # "/share/*" = {
+      #   proxyPass = "http://${config.services.immich.host}:${toString config.services.immich-public-proxy.port}";
+      # };
+
+      # immich
       "/" = {
         proxyPass = "http://${config.services.immich.host}:${toString config.services.immich.port}";
         proxyWebsockets = true;
@@ -13,13 +22,17 @@
     };
   };
 
+  age.secrets.immich_oidc_client_secret.owner = "authelia-main";
+  age.secrets.immich_oidc_client_secret.group = "authelia-main";
+
   # auth via authelia
   services.authelia.instances.main.settings.identity_providers.oidc.clients = [
     {
-      id = "Immich";
+      client_id = "Immich";
 
       # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      secret = "$pbkdf2-sha512$310000$iCgyAKjoYH9UKADProvbgw$LjrYkX1MjjtSXWDkxDjyp3NkLLuLVvKVwy3o8/Rw.8Z8b6yCkPWdBCothuCMlaGcgfG/zLWM6lRV4BrXVZpkig";
+      client_secret = "{{ secret \"${config.age.secrets.immich_oidc_client_secret.path}\" }}";
+
       public = false;
       authorization_policy = "two_factor";
       redirect_uris = [
@@ -43,15 +56,14 @@
       #  "fragment"
       #];
 
-      token_endpoint_auth_method = "client_secret_basic";
+      # token_endpoint_auth_method = "client_secret_basic";
 
       # might be needed since the upgrade to nixos-24.11 and the resulting
       # 4.37.5 -> 4.38.17 upgrade
-      # token_endpoint_auth_method = "client_secret_post";
+      token_endpoint_auth_method = "client_secret_post";
     }
   ];
 
-
   services.immich = {
     enable = true;
     package = pkgs.immich;
@@ -59,7 +71,7 @@
     secretsFile = config.age.secrets.immich_secrets_file.path;
 
     host = "127.0.0.1";
-    port = config.emile.ports.immich;
+    port = config.emile.ports.photo.immich;
 
     machine-learning = {
       enable = false;
@@ -68,4 +80,19 @@
       };
     };
   };
+
+  # services.immich-public-proxy = {
+  #   enable = true;
+  #   package = pkgs.immich-public-proxy;
+  #   settings = {
+  #     downloadOriginalPhoto = true;
+  #     showGalleryTitle = true;
+  #     allowDownloadAll = 1;
+  #     showHomePage = true;
+  #     showMetadata = true;
+  #   };
+  #   port = config.emile.ports.photo.immich-public-proxy;
+  #   openFirewall = false;
+  #   immichUrl = "photo.emile.space";
+  # };
 }
diff --git a/nix/hosts/corrino/www/prometheus.emile.space.nix b/nix/hosts/corrino/www/prometheus.emile.space.nix
index 898f3b2..ec13dfa 100644
--- a/nix/hosts/corrino/www/prometheus.emile.space.nix
+++ b/nix/hosts/corrino/www/prometheus.emile.space.nix
@@ -38,15 +38,43 @@
           enable = true;
           port = config.emile.ports.prometheus.exporter.nginx;
         };
+        restic = {
+          enable = true;
+          # repository = "sftp:u331921@u331921.your-storagebox.de:/home/backup";
+          repository = "/mnt/storagebox-bx11/corrino";
+          port = config.emile.ports.prometheus.exporter.restic;
+          passwordFile = config.age.secrets.restic_password.path;
+        };
       };
       scrapeConfigs = [
         {
           job_name = "corrino";
           static_configs = [
-            { targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.node.port}" ]; }
-            { targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}" ]; }
-            { targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.smartctl.port}" ]; }
-            { targets = [ "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}" ]; }
+            {
+              targets = [
+                "127.0.0.1:${toString config.services.prometheus.exporters.node.port}"
+              ];
+            }
+            {
+              targets = [
+                "127.0.0.1:${toString config.services.prometheus.exporters.systemd.port}"
+              ];
+            }
+            {
+              targets = [
+                "127.0.0.1:${toString config.services.prometheus.exporters.smartctl.port}"
+              ];
+            }
+            {
+              targets = [
+                "127.0.0.1:${toString config.services.prometheus.exporters.nginx.port}"
+              ];
+            }
+            {
+              targets = [
+                "127.0.0.1:${toString config.services.prometheus.exporters.restic.port}"
+              ];
+            }
           ];
         }
         {
diff --git a/nix/hosts/corrino/www/promtail.emile.space.nix b/nix/hosts/corrino/www/promtail.emile.space.nix
deleted file mode 100644
index 654414c..0000000
--- a/nix/hosts/corrino/www/promtail.emile.space.nix
+++ /dev/null
@@ -1,114 +0,0 @@
-{ config, ... }:
-
-{
-  # allow the promtail user to read the nginx access files
-  users.users.promtail.extraGroups = [ "nginx" ];
-
-  services = {
-    promtail = {
-      enable = true;
-      configuration = {
-        server = {
-          http_listen_port = config.emile.ports.promtail;
-          grpc_listen_port = 0;
-        };
-        positions.filename = "/tmp/positions.yml";
-        clients = [{
-          url = "http://localhost:${toString config.services.loki.configuration.server.http_listen_port}/loki/api/v1/push";
-        }];
-        scrape_configs = [
-
-          # systemd
-          {
-            job_name = "journal";
-            journal = {
-              max_age = "12h";
-              labels = {
-                job = "systemd-journal";
-                host = config.networking.hostName;
-              };
-            };
-            relabel_configs = [
-              {
-                source_labels = [ "__journal__systemd_unit" ];
-                target_label = "unit";
-              }
-            ];
-          }
-
-          # nginx error log
-          {
-            job_name = "nginx-error-logs";
-            static_configs = [{
-              targets = [ "localhost" ];
-              labels = {
-                job = "nginx-error-logs";
-                host = "corrino";
-                __path__ = "/var/log/nginx/*error.log";
-              };
-            }];
-          }
-
-          # nginx
-          {
-            job_name = "nginx";
-            static_configs = [
-              {
-                targets = [ "localhost" ];
-                labels = {
-                  job = "nginx";
-                  host = "corrino";
-                  __path__ = "/var/log/nginx/*access.log";
-                };   
-              }
-            ];
-            pipeline_stages = [
-              # {
-              #   regex = {
-              #     expression = "(?:[0-9]{1,3}\.){3}([0-9]{1,3})";
-              #     replace = "***";
-              #   };
-              # }
-              {
-                regex = {
-                  expression = ''(?P<remote_addr>.+) - - \[(?P<time_local>.+)\] "(?P<method>.+) (?P<url>.+) (HTTP\/(?P<version>\d.\d))" (?P<status>\d{3}) (?P<body_bytes_sent>\d+) (["](?P<http_referer>(\-)|(.+))["]) (["](?P<http_user_agent>.+)["])'';
-                };
-              }
-              {
-                labels = {
-                  remote_addr = null;
-                  time_local = null;
-                  method = null;
-                  url = null;
-                  status = null;
-                  body_bytes_sent = null;
-                  http_referer = null;
-                  http_user_agent = null;
-                };
-              }
-              {
-                timestamp = {
-                  source = "time_local";
-                  format = "02/Jan/2006:15:04:05 -0700";
-                };
-              }
-              {
-                drop = {
-                  source = "url";
-                  expression = ''/(_matrix|.well-known|notifications|api|identity).*'';
-                };
-              }
-              {
-                drop = {
-                  source = "url";
-                  expression = ''grafana.*'';
-                };
-              }
-            ];
-          }
-
-        ];
-      };
-    };
-  };
-}
diff --git a/nix/hosts/corrino/www/s3.emile.space.nix b/nix/hosts/corrino/www/s3.emile.space.nix
index b4646ad..ae33542 100644
--- a/nix/hosts/corrino/www/s3.emile.space.nix
+++ b/nix/hosts/corrino/www/s3.emile.space.nix
@@ -1,12 +1,21 @@
-{ config, ... }:
+{ config, pkgs, ... }:
 
 {
+  security.acme.certs."s3.emile.space" = {
+    group = "nginx";
+    domain = "s3.emile.space";
+    extraDomainNames = [
+      "*.s3.emile.space"
+      "*.s3-web.emile.space"
+    ];
+  };
+
   services.nginx.virtualHosts."s3.emile.space" = {
     forceSSL = true;
     enableACME = true;
     locations = {
       "/" = {
-        proxyPass = "http://[::1]:${toString config.emile.ports.minio.s3}";
+        proxyPass = "http://[::1]:${toString config.emile.ports.garage.s3}";
       };
     };
   };
@@ -16,24 +25,96 @@
     enableACME = true;
     locations = {
       "/" = {
-        proxyPass = "http://[::1]:${toString config.emile.ports.minio.web}";
+        proxyPass = "http://[::1]:${toString config.emile.ports.garage.web}";
       };
     };
   };
 
-  services.minio = {
+  services.garage = {
     enable = true;
-    region = "eu-north-1-hel-1a"; # corrino is in the helsinki hetzner dc
+    package = pkgs.garage_1_x;
+    settings = {
+      data_dir = [
+        { capacity = "50G"; path = "/var/lib/garage/data"; }
+      ];
 
-    listenAddress = "[::1]:${toString config.emile.ports.minio.s3}";
+      db_engine = "sqlite";
+      replication_factor = 3;
 
-    browser = true;
-    consoleAddress = "[::1]:${toString config.emile.ports.minio.web}";
+      s3_api = {
+        s3_region = "garage";
+        api_bind_addr = "[::]:${toString config.emile.ports.garage.s3}";
+        root_domain = "s3.emile.space";
+      };
+      s3_web = {
+        bind_addr = "[::]:${toString config.emile.ports.garage.web}";
+        root_domain = "s3-web.emile.space";
+        index = "index.html";
+      };
+      admin = {
+        api_bind_addr = "[::]:${toString config.emile.ports.garage.admin}";
+        # metrics_token = config.age.secrets.garage_admin_metrics_secret.path;
+        # admin_token = config.age.secrets.garage_admin_token_secret.path;
+      };
 
-    dataDir = [ "/minio/data" ];
-    configDir = "/minio/config";
+      # rpc_secret_file = config.age.secrets.garage_rpc_secret.path;
+      rpc_bind_addr = "[::]:${toString config.emile.ports.garage.rpc}";
+      rpc_bind_outgoing = false;
+      rpc_public_addr = "[fc00:1::1]:${toString config.emile.ports.garage.rpc}";
+    };
 
-    rootCredentialsFile = config.age.secrets.minio_root_credz.path;
-    # accessKey
+    environmentFile = config.age.secrets.garage_env.path;
   };
+#         metrics_token = config.age.secrets.garage_admin_metrics_secret.path;
+#         admin_token = config.age.secrets.garage_admin_token_secret.path;
+#       rpc_secret_file = config.age.secrets.garage_rpc_secret.path;
+
+# nix/hosts/corrino/secrets/garage_admin_metrics_secret.age
+# nix/hosts/corrino/secrets/garage_admin_token_secret.age  
+# nix/hosts/corrino/secrets/garage_admin_token.age         
+# nix/hosts/corrino/secrets/garage_metrics_token.age       
+# nix/hosts/corrino/secrets/garage_rpc_secret.age
+  
+  # services.garage = {
+  #   enable = true;
+  #   package = pkgs.garage_1_x;
+  #   settings = {
+  #     db_engine = "sqlite";
+  #     replication_factor = 2;
+
+  #     data_dir = [
+  #       { capacity = "50G"; path = dataDir; }
+  #     ];
+
+  #     compression_level = 1;
+
+  #     rpc_secret_file = config.age.secrets.garage_rpc_secret.path;
+  #     rpc_bind_addr = "[::]:${toString config.emile.ports.garage.rpc}";
+  #     rpc_bind_outgoing = false;
+  #     rpc_public_addr = "[fc00:1::1]:${toString config.emile.ports.garage.rpc}";
+
+  #     allow_world_readable_secrets = false;
+
+  #     s3_api = {
+  #       api_bind_addr = "[::]:${toString config.emile.ports.garage.s3}";
+  #       s3_region = "garage";
+  #       root_domain = "s3.emile.space";
+  #     };
+
+  #     s3_web = {
+  #       bind_addr = "[::]:${toString config.emile.ports.garage.web}";
+  #       root_domain = "s3-web.emile.space";
+  #       add_host_to_metrics = true;
+  #     };
+
+  #     admin = {
+  #       api_bind_addr = "[::]:${toString config.emile.ports.garage.admin}";
+  #       metrics_token = config.age.secrets.garage_admin_metrics_secret.path;
+  #       admin_token = config.age.secrets.garage_admin_token_secret.path;
+  #       trace_sink = "http://localhost:4317";
+  #     };
+
+  #   };
+  #   logLevel = "trace"; # info
+  # };
 }
diff --git a/nix/hosts/corrino/www/sb.emile.space.nix b/nix/hosts/corrino/www/sb.emile.space.nix
deleted file mode 100644
index 0522e25..0000000
--- a/nix/hosts/corrino/www/sb.emile.space.nix
+++ /dev/null
@@ -1,114 +0,0 @@
-{ config, pkgs, ... }:
-
-{
-  services.nginx.virtualHosts."sb.emile.space" = {
-    forceSSL = true;
-    enableACME = true;
-    locations = {
-      "/" = {
-        proxyPass = "http://${config.services.silverbullet.listenAddress}:${toString config.services.silverbullet.listenPort}";
-        extraConfig = ''
-          ## Send a subrequest to Authelia to verify if the user is authenticated and has permission to access the resource.
-          auth_request /internal/authelia/authz;
-
-          ## Save the upstream metadata response headers from Authelia to variables.
-          auth_request_set $user $upstream_http_remote_user;
-          auth_request_set $groups $upstream_http_remote_groups;
-          auth_request_set $name $upstream_http_remote_name;
-          auth_request_set $email $upstream_http_remote_email;
-
-          ## Inject the metadata response headers from the variables into the request made to the backend.
-          proxy_set_header Remote-User $user;
-          proxy_set_header Remote-Groups $groups;
-          proxy_set_header Remote-Email $email;
-          proxy_set_header Remote-Name $name;
-
-          ## Configure the redirection when the authz failure occurs. Lines starting with 'Modern Method' and 'Legacy Method'
-          ## should be commented / uncommented as pairs. The modern method uses the session cookies configuration's authelia_url
-          ## value to determine the redirection URL here. It's much simpler and compatible with the mutli-cookie domain easily.
-
-          ## Modern Method: Set the $redirection_url to the Location header of the response to the Authz endpoint.
-          auth_request_set $redirection_url $upstream_http_location;
-
-          ## Modern Method: When there is a 401 response code from the authz endpoint redirect to the $redirection_url.
-          error_page 401 =302 $redirection_url;
-
-          ## Legacy Method: Set $target_url to the original requested URL.
-          ## This requires http_set_misc module, replace 'set_escape_uri' with 'set' if you don't have this module.
-          # set $target_url $scheme://$http_host$request_uri;
-
-          ## Legacy Method: When there is a 401 response code from the authz endpoint redirect to the portal with the 'rd'
-          ## URL parameter set to $target_url. This requires users update 'auth.example.com/' with their external authelia URL.
-          # error_page 401 =302 https://sso.emile.space/?rd=$target_url;
-        '';
-      };
-      "/internal/authelia/authz" = {
-        extraConfig = ''
-          ## Essential Proxy Configuration
-          internal;
-          proxy_pass https://sso.emile.space/api/authz/auth-request;
-
-          ## Headers
-          ## The headers starting with X-* are required.
-          proxy_set_header X-Original-Method $request_method;
-          proxy_set_header X-Original-URL $scheme://$http_host$request_uri;
-          proxy_set_header X-Forwarded-For $remote_addr;
-          proxy_set_header Content-Length "";
-          proxy_set_header Connection "";
-
-          ## Basic Proxy Configuration
-          proxy_pass_request_body off;
-          proxy_next_upstream error timeout invalid_header http_500 http_502 http_503; # Timeout if the real server is dead
-          proxy_redirect http:// $scheme://;
-          proxy_http_version 1.1;
-          proxy_cache_bypass $cookie_session;
-          proxy_no_cache $cookie_session;
-          proxy_buffers 4 32k;
-          client_body_buffer_size 128k;
-
-          ## Advanced Proxy Configuration
-          send_timeout 5m;
-          proxy_read_timeout 240;
-          proxy_send_timeout 240;
-          proxy_connect_timeout 240;
-        '';
-      };
-    };
-  };
-
-  # auth via authelia
-  # services.authelia.instances.main.settings.identity_providers.oidc.clients = [
-  #   {
-  #     id = "silverbullet";
-
-  #     # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-  #     secret = "$pbkdf2-sha512$310000$mxk7uITQOZNYEqeinigQnw$wsF2S6RPL2zVRg1X0bAuINh8Lu5PuA/2/FYJSy3i/Ig5vtCzaIFb0xYEcus4jkqTIgyp3aBxtgSzAKjQKC.QKg";
-  #     public = false;
-  #     authorization_policy = "two_factor";
-  #     redirect_uris = [ "https://md.emile.space/auth/oauth2/callback" ];
-  #     scopes = [
-  #       "openid"
-  #       "email"
-  #       "profile"
-  #     ];
-  #     grant_types = [
-  #       "refresh_token"
-  #       "authorization_code"
-  #     ];
-  #     response_types = [ "code" ];
-  #     response_modes = [
-  #       "form_post"
-  #       "query"
-  #       "fragment"
-  #     ];
-  #     token_endpoint_auth_method = "client_secret_post";
-  #   }
-  # ];
-
-  services.silverbullet = {
-    enable = true;
-    spaceDir = "/var/lib/silverbullet";
-    listenPort = 3000;
-    listenAddress = "[::1]";
-  };
-}
diff --git a/nix/hosts/corrino/www/social.emile.space.nix b/nix/hosts/corrino/www/social.emile.space.nix
index 210f0be..d9d30f7 100644
--- a/nix/hosts/corrino/www/social.emile.space.nix
+++ b/nix/hosts/corrino/www/social.emile.space.nix
@@ -38,13 +38,17 @@
     };
   };
 
+  age.secrets.gotosocial_oidc_client_secret.owner = "authelia-main";
+  age.secrets.gotosocial_oidc_client_secret.group = "authelia-main";
+  
   # auth via authelia
   services.authelia.instances.main.settings.identity_providers.oidc.clients = [
     {
-      id = "gotosocial";
+      client_id = "gotosocial";
 
       # ; nix run nixpkgs#authelia -- crypto hash generate pbkdf2 --variant sha512 --random --random.length 72 --random.charset rfc3986
-      secret = "$pbkdf2-sha512$310000$oDpZ5FuO965TbjPoophJXw$dbkAwWFvLN1h1Zh9US2ZOE5ilPRdEHMdGF/x0uorou2UqURrXF0KQmXxsV38F2yYMS7u/ecramKlvfMwsqHOcg";
+      client_secret = "{{ secret \"${config.age.secrets.gotosocial_oidc_client_secret.path}\" }}";
+
       public = false;
       authorization_policy = "two_factor";
       redirect_uris = [ "https://social.emile.space/auth/callback" ];
@@ -93,4 +97,21 @@
       Restart = "on-failure";
     };
   };
+
+  services.restic.backups."corrino" = {
+    paths = [ "/var/lib/gotosocial" ];
+  };
+
+  services.restic.backups."gotosocial" = {
+    repository = "/mnt/storagebox-bx11/gotosocial";
+    paths = [ "/var/lib/gotosocial" ];
+    passwordFile = config.age.secrets.restic_password.path;
+    initialize = true;
+    pruneOpts = [
+      "--keep-daily 7"
+      "--keep-weekly 5"
+      "--keep-monthly 12"
+      "--keep-yearly 75"
+    ];
+  };
 }
diff --git a/nix/hosts/corrino/www/tickets.emile.space.nix b/nix/hosts/corrino/www/tickets.emile.space.nix
index fb12961..08f23d3 100644
--- a/nix/hosts/corrino/www/tickets.emile.space.nix
+++ b/nix/hosts/corrino/www/tickets.emile.space.nix
@@ -18,7 +18,7 @@
       enable = true;
       package = pkgs.pretix;
       plugins = with config.services.pretix.package.plugins; [
-        passbook
+        # passbook
         pages
       ];
       user = "pretix";