1 { config, lib, pkgs, ... }:
6 cfg = config.services.resilio;
8 resilioSync = pkgs.resilio-sync;
10 sharedFoldersRecord = map (entry: {
11 secret = entry.secret;
12 dir = entry.directory;
14 use_relay_server = entry.useRelayServer;
15 use_tracker = entry.useTracker;
16 use_dht = entry.useDHT;
18 search_lan = entry.searchLAN;
19 use_sync_trash = entry.useSyncTrash;
20 known_hosts = entry.knownHosts;
23 configFile = pkgs.writeText "config.json" (builtins.toJSON ({
24 device_name = cfg.deviceName;
25 storage_path = cfg.storagePath;
26 listening_port = cfg.listeningPort;
28 check_for_updates = cfg.checkForUpdates;
29 use_upnp = cfg.useUpnp;
30 download_limit = cfg.downloadLimit;
31 upload_limit = cfg.uploadLimit;
32 lan_encrypt_data = cfg.encryptLAN;
33 } // optionalAttrs (cfg.directoryRoot != "") { directory_root = cfg.directoryRoot; }
34 // optionalAttrs cfg.enableWebUI {
35 webui = { listen = "${cfg.httpListenAddr}:${toString cfg.httpListenPort}"; } //
36 (optionalAttrs (cfg.httpLogin != "") { login = cfg.httpLogin; }) //
37 (optionalAttrs (cfg.httpPass != "") { password = cfg.httpPass; }) //
38 (optionalAttrs (cfg.apiKey != "") { api_key = cfg.apiKey; });
39 } // optionalAttrs (sharedFoldersRecord != []) {
40 shared_folders = sharedFoldersRecord;
50 description = lib.mdDoc ''
51 If enabled, start the Resilio Sync daemon. Once enabled, you can
52 interact with the service through the Web UI, or configure it in your
57 deviceName = mkOption {
60 default = config.networking.hostName;
61 defaultText = literalExpression "config.networking.hostName";
62 description = lib.mdDoc ''
63 Name of the Resilio Sync device.
67 listeningPort = mkOption {
71 description = lib.mdDoc ''
72 Listening port. Defaults to 0 which randomizes the port.
76 checkForUpdates = mkOption {
79 description = lib.mdDoc ''
80 Determines whether to check for updates and alert the user
88 description = lib.mdDoc ''
89 Use Universal Plug-n-Play (UPnP)
93 downloadLimit = mkOption {
97 description = lib.mdDoc ''
98 Download speed limit. 0 is unlimited (default).
102 uploadLimit = mkOption {
106 description = lib.mdDoc ''
107 Upload speed limit. 0 is unlimited (default).
111 httpListenAddr = mkOption {
115 description = lib.mdDoc ''
116 HTTP address to bind to.
120 httpListenPort = mkOption {
123 description = lib.mdDoc ''
124 HTTP port to bind on.
128 httpLogin = mkOption {
130 example = "allyourbase";
132 description = lib.mdDoc ''
133 HTTP web login username.
137 httpPass = mkOption {
139 example = "arebelongtous";
141 description = lib.mdDoc ''
142 HTTP web login password.
146 encryptLAN = mkOption {
149 description = lib.mdDoc "Encrypt LAN data.";
152 enableWebUI = mkOption {
155 description = lib.mdDoc ''
156 Enable Web UI for administration. Bound to the specified
157 `httpListenAddress` and
162 storagePath = mkOption {
164 default = "/var/lib/resilio-sync/";
165 description = lib.mdDoc ''
166 Where BitTorrent Sync will store it's database files (containing
167 things like username info and licenses). Generally, you should not
168 need to ever change this.
175 description = lib.mdDoc "API key, which enables the developer API.";
178 directoryRoot = mkOption {
182 description = lib.mdDoc "Default directory to add folders in the web UI.";
185 sharedFolders = mkOption {
187 type = types.listOf (types.attrsOf types.anything);
189 [ { secret = "AHMYFPCQAHBM7LQPFXQ7WV6Y42IGUXJ5Y";
190 directory = "/home/user/sync_test";
191 useRelayServer = true;
202 description = lib.mdDoc ''
203 Shared folder list. If enabled, web UI must be
204 disabled. Secrets can be generated using `rslsync --generate-secret`.
205 Note that this secret will be
206 put inside the Nix store, so it is realistically not very
209 If you would like to be able to modify the contents of this
210 directories, it is recommended that you make your user a
211 member of the `rslsync` group.
213 Directories in this list should be in the
214 `rslsync` group, and that group must have
215 write access to the directory. It is also recommended that
216 `chmod g+s` is applied to the directory
217 so that any sub directories created will also belong to
218 the `rslsync` group. Also,
219 `setfacl -d -m group:rslsync:rwx` and
220 `setfacl -m group:rslsync:rwx` should also
221 be applied so that the sub directories are writable by
228 config = mkIf cfg.enable {
230 [ { assertion = cfg.deviceName != "";
231 message = "Device name cannot be empty.";
233 { assertion = cfg.enableWebUI -> cfg.sharedFolders == [];
234 message = "If using shared folders, the web UI cannot be enabled.";
236 { assertion = cfg.apiKey != "" -> cfg.enableWebUI;
237 message = "If you're using an API key, you must enable the web server.";
241 users.users.rslsync = {
242 description = "Resilio Sync Service user";
243 home = cfg.storagePath;
245 uid = config.ids.uids.rslsync;
249 users.groups.rslsync = {};
251 systemd.services.resilio = with pkgs; {
252 description = "Resilio Sync Service";
253 wantedBy = [ "multi-user.target" ];
254 after = [ "network.target" ];
256 Restart = "on-abort";
260 ${resilioSync}/bin/rslsync --nodaemon --config ${configFile}