commit 1b9b6a61cc84c8023b5d134ff6d9e735413201c4
parent df3ab6bc39105825bb7eb00be47b3bd3f7c5372d
Author: mtmn <miro@haravara.org>
Date: Mon, 4 May 2026 12:41:29 +0200
feat: add syncthing
Diffstat:
6 files changed, 116 insertions(+), 0 deletions(-)
diff --git a/hosts/nixaran/configuration.nix b/hosts/nixaran/configuration.nix
Binary files differ.
diff --git a/modules/services/filestash.nix b/modules/services/filestash.nix
Binary files differ.
diff --git a/modules/services/storage-box.nix b/modules/services/storage-box.nix
@@ -69,6 +69,10 @@ in {
(lib.optionals config.services.haravara.monitoring.enable [
"d ${cfg.mountPoint}/nixaran/victoriametrics - - - -"
])
+ (lib.optionals config.services.haravara.syncthing.enable [
+ "d ${cfg.mountPoint}/nixaran/syncthing 0750 syncthing storage-users -"
+ "d ${cfg.mountPoint}/nixaran/syncthing/mobius 0750 syncthing storage-users -"
+ ])
(lib.optionals config.services.haravara.seaweedfs.enable [
"d ${cfg.mountPoint}/seanix 0755 seaweedfs storage-users -"
"d ${cfg.mountPoint}/seanix/master 0755 seaweedfs storage-users -"
@@ -141,6 +145,12 @@ in {
victoriametrics.after = ["var-lib-victoriametrics.mount"];
victoriametrics.requires = ["var-lib-victoriametrics.mount"];
})
+ (lib.mkIf config.services.haravara.syncthing.enable {
+ syncthing.after = [mountUnit];
+ syncthing.requires = [mountUnit];
+ syncthing-s3-sync.after = [mountUnit];
+ syncthing-s3-sync.requires = [mountUnit];
+ })
];
};
}
diff --git a/modules/services/syncthing.nix b/modules/services/syncthing.nix
@@ -0,0 +1,105 @@
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}: let
+ cfg = config.services.haravara.syncthing;
+
+ s3SyncScript = pkgs.writeShellScript "syncthing-s3-sync" ''
+ export RCLONE_CONFIG_SEAWEEDFS_TYPE=s3
+ export RCLONE_CONFIG_SEAWEEDFS_PROVIDER=Other
+ export RCLONE_CONFIG_SEAWEEDFS_ENDPOINT="${cfg.s3Endpoint}"
+ export RCLONE_CONFIG_SEAWEEDFS_FORCE_PATH_STYLE=true
+ export RCLONE_CONFIG_SEAWEEDFS_ACCESS_KEY_ID="$S3_ACCESS_KEY_ID"
+ export RCLONE_CONFIG_SEAWEEDFS_SECRET_ACCESS_KEY="$S3_SECRET_ACCESS_KEY"
+ exec ${lib.getExe pkgs.rclone} sync seaweedfs:mobius "${cfg.syncDir}" --create-empty-src-dirs
+ '';
+in {
+ options.services.haravara.syncthing = {
+ enable = lib.mkEnableOption "Syncthing with S3 archive sync";
+
+ domain = lib.mkOption {
+ type = lib.types.str;
+ description = "Domain for the Syncthing web GUI";
+ };
+
+ authLabel = lib.mkOption {
+ type = lib.types.nullOr lib.types.str;
+ default = null;
+ description = "Caddy auth snippet label";
+ };
+
+ guiPort = lib.mkOption {
+ type = lib.types.nullOr lib.types.str;
+ default = "8384";
+ description = "Port on which the web interface runs";
+ };
+
+ s3Endpoint = lib.mkOption {
+ type = lib.types.str;
+ default = "http://127.0.0.1:8333";
+ description = "SeaweedFS S3 endpoint URL";
+ };
+
+ s3CredentialsFile = lib.mkOption {
+ type = lib.types.path;
+ description = "Environment file with S3_ACCESS_KEY_ID and S3_SECRET_ACCESS_KEY";
+ };
+
+ syncDir = lib.mkOption {
+ type = lib.types.str;
+ description = "Local path where the mobius bucket is synced to and shared via Syncthing";
+ };
+
+ syncInterval = lib.mkOption {
+ type = lib.types.str;
+ default = "1h";
+ description = "How often to pull from S3 bucket";
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ services.syncthing = {
+ enable = true;
+ openDefaultPorts = true;
+ guiAddress = "127.0.0.1:${toString cfg.guiPort}";
+ settings = {
+ folders.mobius = {
+ path = cfg.syncDir;
+ label = "mobius";
+ type = "sendonly";
+ overrideDevices = false;
+ };
+ options.urAccepted = -1;
+ };
+ };
+
+ systemd.services.syncthing-s3-sync = {
+ description = "Pull s3://mobius into syncthing folder";
+ after = ["network-online.target" "syncthing.service"];
+ wants = ["network-online.target"];
+ serviceConfig = {
+ Type = "oneshot";
+ User = "syncthing";
+ EnvironmentFile = cfg.s3CredentialsFile;
+ ExecStart = s3SyncScript;
+ };
+ };
+
+ systemd.timers.syncthing-s3-sync = {
+ wantedBy = ["timers.target"];
+ timerConfig = {
+ OnActiveSec = "5m";
+ OnUnitActiveSec = cfg.syncInterval;
+ };
+ };
+
+ services.caddy.virtualHosts."${cfg.domain}".extraConfig = ''
+ ${lib.optionalString (cfg.authLabel != null) "import auth_${cfg.authLabel}"}
+ reverse_proxy 127.0.0.1:${toString cfg.guiPort} {
+ header_up Host 127.0.0.1:${toString cfg.guiPort}
+ }
+ '';
+ };
+}
diff --git a/secrets.nix b/secrets.nix
@@ -20,4 +20,5 @@ in {
"secrets/smtp-alerts-password.age".publicKeys = allKeys;
"secrets/radicale-htpasswd.age".publicKeys = allKeys;
"secrets/shirt-linkener-auth-token.age".publicKeys = allKeys;
+ "secrets/syncthing-s3-credentials.age".publicKeys = allKeys;
}
diff --git a/secrets/syncthing-s3-credentials.age b/secrets/syncthing-s3-credentials.age
Binary files differ.