summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorZacchaeus <eikcaz@zacchae.us>2025-02-16 12:56:16 -0500
committerLeo Famulari <leo@famulari.name>2025-02-17 01:12:37 -0500
commit651f8765b657e35baf85ac74a1f6b09ff71691cb (patch)
treef637707ec926695b60238108f9133395dfdf95ba /doc
parentad74dedb9f167c088d37a3a30d5d6fe841e9127b (diff)
services: syncthing: Add support for declarative configuration.
* gnu/services/syncthing.scm: (syncthing-config-file, syncthing-folder, syncthing-device, syncthing-folder-device): New records. (syncthing-service-type): Add special-files-service-type extension for the config file. (syncthing-files-service): Add service to create config file. * gnu/home/services/syncthing.scm: (home-syncthing-service-type): Extend home-files-services-type and re-exported more things from gnu/services/syncthing.scm. * doc/guix.texi: (syncthing-service-type): Document changes. Change-Id: I87eeba1ee1fdada8f29c2ee881fbc6bc4113dde9 Signed-off-by: Leo Famulari <leo@famulari.name>
Diffstat (limited to 'doc')
-rw-r--r--doc/guix.texi338
1 files changed, 335 insertions, 3 deletions
diff --git a/doc/guix.texi b/doc/guix.texi
index 51bb4b38b6..5c50e587f8 100644
--- a/doc/guix.texi
+++ b/doc/guix.texi
@@ -137,6 +137,7 @@ Copyright @copyright{} 2024 Sharlatan Hellseher@*
Copyright @copyright{} 2024 45mg@*
Copyright @copyright{} 2025 Sören Tempel@*
Copyright @copyright{} 2025 Rostislav Svoboda@*
+Copyright @copyright{} 2025 Zacchaeus@*
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3 or
@@ -22738,7 +22739,7 @@ client.
The @code{(gnu services syncthing)} module provides the following services:
@cindex syncthing
-You might want a syncthing daemon if you have files between two or more
+You might want a Syncthing daemon if you have files between two or more
computers and want to sync them in real time, safely protected from
prying eyes.
@@ -22784,12 +22785,343 @@ The group as which the Syncthing service is to be run.
This assumes that the specified group exists.
@item @code{home} (default: @var{#f})
-Common configuration and data directory. The default configuration
-directory is @file{$HOME} of the specified Syncthing @code{user}.
+Sets the @code{HOME} variable for the Syncthing daemon. The default is
+@file{$HOME} of the specified Syncthing @code{user}.
+@item @code{config-file} (default: @var{#f})
+Either a file-like object that resolves to a Syncthing configuration XML
+file, or a @code{syncthing-config-file} record (see below). If set to
+@code{#f}, Guix will not try to generate a config file, and Syncthing
+will generate a default configuration which will not be touched on
+reconfigure. Specifying this in a system service moves Syncthing's
+common configuration and data directory (@code{--home} in
+@uref{https://docs.syncthing.net/users/syncthing.html}) to
+@file{/var/lib/syncthing-<user>}.
+
+@end table
+@end deftp
+
+This section documents a subset of the Syncthing configuration
+options—specifically those related to Guix or those affecting how your
+computer will connect to other computers over the network (such as
+Syncthing relays or discovery servers). The configuration is fully
+documented in the upstream
+@uref{https://docs.syncthing.net/users/config.html, Syncthing config
+documentation}; camelCase there is converted to kebab-case here. If you
+are migrating from a Syncthing-managed configuration to one managed by
+Guix, you can check what changes were introduced by @code{diff}ing the
+respective @file{config.xml} files. Note that you will need to add
+whitespace with 4-space indentation to the file generated by Guix, using
+the @code{xmllint} program from the @code{libxml2} package like so:
+
+@example
+XMLLINT_INDENT=" " xmllint --format /path/to/new/config.xml | diff /path/to/old/config.xml -
+@end example
+
+When generating a configuration file through Guix, you can still
+temporarily modify Syncthing from the GUI or through @code{introducer}
+and @code{autoAcceptFolders} mechanisms, but such changes will be reset
+on reconfigure.
+
+@deftp {Data Type} syncthing-config-file
+Data type representing the configuration file read by the Syncthing
+daemon.
+
+@table @asis
+@item @code{folders} (default: @var{(list (syncthing-folder (id "default") (label "Default Folder") (path "~/Sync")))}
+The default here is the same as Syncthing's default. The value should
+be a list of @code{syncthing-folder}s.
+
+@item @code{devices} (default: @var{'()}
+This should be a list of @code{syncthing-device}s. Guix will
+automatically add any devices specified in any `folders' to this list.
+There are instances when you want to connect to a device despite not
+(initially) sharing any folders (such as a device with
+autoAcceptFolders). In such instances, you should specify those devices
+here. If multiple versions of the same device (as determined by
+comparing device ID) are discovered, the one in this list is
+prioritized. Otherwise, the first instance in the first folder is used.
+
+@item @code{gui-enabled} (default: @var{"true"})
+By default, any user on the computer can access the GUI and make changes
+to Syncthing. If you leave this enabled, you should probably set
+@code{gui-user} and @code{gui-password} (see below).
+
+@item @code{gui-tls} (default: @var{"false"})
+@item @code{gui-debugging} (default: @var{"false"})
+@item @code{gui-send-basic-auth-prompt} (default: @var{"false"})
+@item @code{gui-address} (default: @var{"127.0.0.1:8384"})
+@item @code{gui-user} (default: @var{#f})
+@item @code{gui-password} (default: @var{#f})
+A bcrypt hash of the GUI password. Remember that this will be globally
+exposed in @file{/gnu/store}.
+
+@item @code{gui-apikey} (default: @var{#f})
+You must specify this to use the Syncthing REST interface. This key is
+kept in @file{/gnu/store} and is accessible to all users of the system.
+
+@item @code{gui-theme} (default: @var{"default"})
+@item @code{ldap-enabled} (default: @var{#f})
+@item @code{ldap-address} (default: @var{""})
+@item @code{ldap-bind-dn} (default: @var{""})
+@item @code{ldap-transport} (default: @var{""})
+@item @code{ldap-insecure-skip-verify} (default: @var{""})
+@item @code{ldap-search-base-dn} (default: @var{""})
+@item @code{ldap-search-filter} (default: @var{""})
+@item @code{listen-address} (default: @var{"default"})
+@item @code{global-announce-server} (default: @var{"default"})
+@item @code{global-announce-enabled} (default: @var{"true"})
+Global discovery servers can be used to help connect devices at unknown
+IP addresses by storing the last known IP address.
+
+@item @code{local-announce-enabled} (default: @var{"true"})
+This makes devices find each other very easily on the same LAN. Often,
+this will allow you to just plug an Ethernet between two devices, or
+connect one device to the other's hotspot and start syncing.
+
+@item @code{local-announce-port} (default: @var{"21027"})
+@item @code{local-announce-mcaddr} (default: @var{"[ff12::8384]:21027"})
+@item @code{max-send-kbps} (default: @var{"0"})
+@item @code{max-recv-kbps} (default: @var{"0"})
+@item @code{reconnection-interval-s} (default: @var{"60"})
+@item @code{relays-enabled} (default: @var{"true"})
+This option allows your Syncthing instance to use a global network of
+@uref{https://docs.syncthing.net/users/relaying.html, relays} to enable
+syncing between devices when all other methods fail. As always,
+Syncthing traffic is encrypted in transport and the relays are unable to
+decrypt it.
+
+@item @code{relay-reconnect-interval-m} (default: @var{"10"})
+@item @code{start-browser} (default: @var{"true"})
+@item @code{nat-enabled} (default: @var{"true"})
+@item @code{nat-lease-minutes} (default: @var{"60"})
+@item @code{nat-renewal-minutes} (default: @var{"30"})
+@item @code{nat-timeout-seconds} (default: @var{"10"})
+@item @code{ur-accepted} (default: @var{"0"})
+Options whose names begin with `ur-' control usage reporting. Set to -1
+to disable, or to a positive value to enable. The default (0) disables
+reporting, but causes a usage reporting consent prompt to be displayed
+in the Syncthing GUI.
+
+@item @code{ur-seen} (default: @var{"0"})
+@item @code{ur-unique-id} (default: @var{""})
+@item @code{ur-url} (default: @var{"https://data.syncthing.net/newdata"})
+@item @code{ur-post-insecurely} (default: @var{"false"})
+@item @code{ur-initial-delay-s} (default: @var{"1800"})
+@item @code{auto-upgrade-interval-h} (default: @var{"12"})
+@item @code{upgrade-to-pre-releases} (default: @var{"false"})
+@item @code{keep-temporaries-h} (default: @var{"24"})
+@item @code{cache-ignored-files} (default: @var{"false"})
+@item @code{progress-update-interval-s} (default: @var{"5"})
+@item @code{limit-bandwidth-in-lan} (default: @var{"false"})
+@item @code{min-home-disk-free-unit} (default: @var{"%"})
+@item @code{min-home-disk-free} (default: @var{"1"})
+@item @code{releases-url} (default: @var{"https://upgrades.syncthing.net/meta.json"})
+@item @code{overwrite-remote-device-names-on-connect} (default: @var{"false"})
+@item @code{temp-index-min-blocks} (default: @var{"10"})
+@item @code{unacked-notification-id} (default: @var{"authenticationUserAndPassword"})
+@item @code{traffic-class} (default: @var{"0"})
+@item @code{set-low-priority} (default: @var{"true"})
+@item @code{max-folder-concurrency} (default: @var{"0"})
+@item @code{crash-reporting-url} (default: @var{"https://crash.syncthing.net/newcrash"})
+@item @code{crash-reporting-enabled} (default: @var{"true"})
+@item @code{stun-keepalive-start-s} (default: @var{"180"})
+@item @code{stun-keepalive-min-s} (default: @var{"20"})
+@item @code{stun-server} (default: @var{"default"})
+@item @code{database-tuning} (default: @var{"auto"})
+@item @code{max-concurrent-incoming-request-kib} (default: @var{"0"})
+@item @code{announce-lan-addresses} (default: @var{"true"})
+@item @code{send-full-index-on-upgrade} (default: @var{"false"})
+@item @code{connection-limit-enough} (default: @var{"0"})
+@item @code{connection-limit-max} (default: @var{"0"})
+@item @code{insecure-allow-old-tls-versions} (default: @var{"false"})
+@item @code{connection-priority-tcp-lan} (default: @var{"10"})
+@item @code{connection-priority-quic-lan} (default: @var{"20"})
+@item @code{connection-priority-tcp-wan} (default: @var{"30"})
+@item @code{connection-priority-quic-wan} (default: @var{"40"})
+@item @code{connection-priority-relay} (default: @var{"50"})
+@item @code{connection-priority-upgrade-threshold} (default: @var{"0"})
+@item @code{default-folder} (default: @var{(syncthing-folder (label ""))})
+@item @code{default-device} (default: @var{(syncthing-device (id ""))})
+@item @code{default-ignores} (default: @var{"")})
+Options whose names begin with `default-' above do not affect folders
+and devices added through the Guix configuration interface. They will,
+however, affect folders and devices that are added through the Syncthing
+GUI, by an @code{introducer}, or a device with
+@code{auto-accept-folders}.
+@end table
+@end deftp
+
+@deftp {Data Type} syncthing-folder
+Data type representing a folder to be synchronized.
+
+@table @asis
+@item @code{id} (default: @var{#f})
+This ID cannot match the ID of any other folder on this device. If left
+unspecified, it will default to the label (see below).
+
+@item @code{label}
+A human readable label for the folder.
+
+@item @code{path}
+The path at which to store this folder.
+
+@item @code{type} (default: @var{"sendreceive"})
+@item @code{rescan-interval-s} (default: @var{"3600"})
+@item @code{fs-watcher-enabled} (default: @var{"true"})
+@item @code{fs-watcher-delay-s} (default: @var{"10"})
+@item @code{ignore-perms} (default: @var{"false"})
+@item @code{auto-normalize} (default: @var{"true"})
+@item @code{devices} (default: @var{'()})
+This should be a list of other Syncthing devices. You do not need to
+specify the current device. Each device can be listed as a a
+@code{syncthing-device} record or a @code{syncthing-folder-device}
+record if you want files to be encrypted on disk. See below.
+
+@item @code{filesystem-type} (default: @var{"basic"})
+@item @code{min-disk-free-unit} (default: @var{"%"})
+@item @code{min-disk-free} (default: @var{"1"})
+@item @code{versioning-type} (default: @var{#f})
+@item @code{versioning-fs-path} (default: @var{""})
+@item @code{versioning-fs-type} (default: @var{"basic"})
+@item @code{versioning-cleanup-interval-s} (default: @var{"3600"})
+@item @code{versioning-cleanout-days} (default: @var{#f})
+@item @code{versioning-keep} (default: @var{#f})
+@item @code{versioning-max-age} (default: @var{#f})
+@item @code{versioning-command} (default: @var{#f})
+@item @code{copiers} (default: @var{"0"})
+@item @code{puller-max-pending-kib} (default: @var{"0"})
+@item @code{hashers} (default: @var{"0"})
+@item @code{order} (default: @var{"random"})
+@item @code{ignore-delete} (default: @var{"false"})
+@item @code{scan-progress-interval-s} (default: @var{"0"})
+@item @code{puller-pause-s} (default: @var{"0"})
+@item @code{max-conflicts} (default: @var{"10"})
+@item @code{disable-sparse-files} (default: @var{"false"})
+@item @code{disable-temp-indexes} (default: @var{"false"})
+@item @code{paused} (default: @var{"false"})
+@item @code{weak-hash-threshold-pct} (default: @var{"25"})
+@item @code{marker-name} (default: @var{".stfolder"})
+@item @code{copy-ownership-from-parent} (default: @var{"false"})
+@item @code{mod-time-window-s} (default: @var{"0"})
+@item @code{max-concurrent-writes} (default: @var{"2"})
+@item @code{disable-fsync} (default: @var{"false"})
+@item @code{block-pull-order} (default: @var{"standard"})
+@item @code{copy-range-method} (default: @var{"standard"})
+@item @code{case-sensitive-fs} (default: @var{"false"})
+@item @code{junctions-as-dirs} (default: @var{"false"})
+@item @code{sync-ownership} (default: @var{"false"})
+@item @code{send-ownership} (default: @var{"false"})
+@item @code{sync-xattrs} (default: @var{"false"})
+@item @code{send-xattrs} (default: @var{"false"})
+@item @code{xattr-filter-max-single-entry-size} (default: @var{"1024"})
+@item @code{xattr-filter-max-total-size} (default: @var{"4096")})
@end table
@end deftp
+@deftp {Data Type} syncthing-device
+Data type representing a device to synchronize folders with.
+
+@table @asis
+@item @code{id}
+A long hash representing the keys generated by Syncthing on the first
+launch. You can obtain this from the Syncthing GUI or by inspecting an
+existing Syncthing configuration file.
+
+@item @code{name} (default: @var{""})
+A human readable device name for viewing in the GUI or in Scheme.
+
+@item @code{compression} (default: @var{"metadata"})
+@item @code{introducer} (default: @var{"false"})
+@item @code{skip-introduction-removals} (default: @var{"false"})
+@item @code{introduced-by} (default: @var{""})
+@item @code{addresses} (default: @var{'("dynamic")})
+List of addresses at which to search for this device. When the special
+value ``dynamic'' is included, Syncthing will search for the device
+locally as well as via the Syncthing project's
+@uref{https://docs.syncthing.net/users/security.html#global-discovery,
+global discovery} servers.
+
+@item @code{paused} (default: @var{"false"})
+@item @code{auto-accept-folders} (default: @var{"false"})
+@item @code{max-send-kbps} (default: @var{"0"})
+@item @code{max-recv-kbps} (default: @var{"0"})
+@item @code{max-request-kib} (default: @var{"0"})
+@item @code{untrusted} (default: @var{"false"})
+@item @code{remote-gui-port} (default: @var{"0"})
+@item @code{num-connections} (default: @var{"0")})
+
+@end table
+@end deftp
+
+@deftp {Data Type} syncthing-folder-device
+This data type offers two folder-specific device options:
+@code{introduced-by} and @code{encryption-password}.
+
+@code{syncthing-folder-device} corresponds to the
+@uref{https://docs.syncthing.net/users/config.html#config-option-folder.device,
+`device'} option in the upstream `folder' element.
+
+If you don't need to use these options, then you can just use
+@code{syncthing-device} instead of @code{syncthing-folder-device} in the
+@code{devices} field of a @code{syncthing-folder} instance.
+
+@table @asis
+@item @code{device}
+The @code{syncthing-device} for which this configuration applies.
+
+@item @code{introduced-by} (default: @var{""})
+The name of the device that "introduced" our device to the device
+sharing this folder. This is only used when "introduced" devices are
+removed by the introducer. See
+@uref{https://docs.syncthing.net/users/introducer.html, Syncthing
+introductions}.
+
+@item @code{encryption-password} (default: @var{""})
+The password used to encrypt data that is synchronized to untrusted
+devices.
+
+Beware: specifying this field will include this password as plain text
+(not encrypted) and globally visible in @file{/gnu/store/}. If the
+encryption-password is non-empty, then it will be used as a password to
+encrypt file chunks as they are synchronized to untrusted devices. For
+more information on syncing to devices you don't totally trust, see
+Syncthing's documentation on
+@uref{https://docs.syncthing.net/users/untrusted.html, Untrusted
+(Encrypted) Devices}. Note that data transfer is always encrypted while
+in transport ("end-to-end encryption"), regardless of this setting.
+
+@end table
+@end deftp
+
+Here is a more complex example configuration for illustrative purposes:
+
+@lisp
+(service syncthing-service-type
+ (let ((laptop (syncthing-device (id "VHOD2D6-...-7XRMDEN")))
+ (desktop (syncthing-device (id "64SAZ37-...-FZJ5GUA")
+ (addresses '("tcp://example.com"))))
+ (bob-desktop (syncthing-device (id "KYIMEGO-...-FT77EAO"))))
+ (syncthing-configuration
+ (user "alice")
+ (config-file
+ (syncthing-config-file
+ (folders (list (syncthing-folder
+ (label "some-files")
+ (path "~/data")
+ (devices (list desktop laptop)))
+ (syncthing-folder
+ (label "critical-files")
+ (path "~/secrets")
+ (devices
+ (list desktop
+ laptop
+ (syncthing-folder-device
+ (device bob-desktop)
+ (encryption-password "mypassword"))))))))))))
+@end lisp
+
+
Furthermore, @code{(gnu services ssh)} provides the following services.
@cindex SSH
@cindex SSH server