1 # FoundationDB {#module-services-foundationdb}
3 *Source:* {file}`modules/services/databases/foundationdb.nix`
5 *Upstream documentation:* <https://apple.github.io/foundationdb/>
7 *Maintainer:* Austin Seipp
9 *Available version(s):* 7.1.x
11 FoundationDB (or "FDB") is an open source, distributed, transactional
14 ## Configuring and basic setup {#module-services-foundationdb-configuring}
16 To enable FoundationDB, add the following to your
17 {file}`configuration.nix`:
20 services.foundationdb.enable = true;
21 services.foundationdb.package = pkgs.foundationdb71; # FoundationDB 7.1.x
25 The {option}`services.foundationdb.package` option is required, and
26 must always be specified. Due to the fact FoundationDB network protocols and
27 on-disk storage formats may change between (major) versions, and upgrades
28 must be explicitly handled by the user, you must always manually specify
29 this yourself so that the NixOS module will use the proper version. Note
30 that minor, bugfix releases are always compatible.
32 After running {command}`nixos-rebuild`, you can verify whether
33 FoundationDB is running by executing {command}`fdbcli` (which is
34 added to {option}`environment.systemPackages`):
36 $ sudo -u foundationdb fdbcli
37 Using cluster file `/etc/foundationdb/fdb.cluster'.
39 The database is available.
41 Welcome to the fdbcli. For help, type `help'.
44 Using cluster file `/etc/foundationdb/fdb.cluster'.
47 Redundancy mode - single
48 Storage engine - memory
52 FoundationDB processes - 1
54 Memory availability - 5.4 GB per process on machine with least available
55 Fault Tolerance - 0 machines
56 Server time - 04/20/18 15:21:14
63 You can also write programs using the available client libraries. For
64 example, the following Python program can be run in order to grab the
65 cluster status, as a quick example. (This example uses
66 {command}`nix-shell` shebang support to automatically supply the
67 necessary Python modules).
69 a@link> cat fdb-status.py
70 #! /usr/bin/env nix-shell
71 #! nix-shell -i python -p python pythonPackages.foundationdb71
82 return str(tr['\xff\xff/status/json'])
84 obj = json.loads(get_status(db))
85 print('FoundationDB available: %s' % obj['client']['database_status']['available'])
87 if __name__ == "__main__":
89 a@link> chmod +x fdb-status.py
90 a@link> ./fdb-status.py
91 FoundationDB available: True
95 FoundationDB is run under the {command}`foundationdb` user and group
96 by default, but this may be changed in the NixOS configuration. The systemd
97 unit {command}`foundationdb.service` controls the
98 {command}`fdbmonitor` process.
100 By default, the NixOS module for FoundationDB creates a single SSD-storage
101 based database for development and basic usage. This storage engine is
102 designed for SSDs and will perform poorly on HDDs; however it can handle far
103 more data than the alternative "memory" engine and is a better default
104 choice for most deployments. (Note that you can change the storage backend
105 on-the-fly for a given FoundationDB cluster using
108 Furthermore, only 1 server process and 1 backup agent are started in the
109 default configuration. See below for more on scaling to increase this.
111 FoundationDB stores all data for all server processes under
112 {file}`/var/lib/foundationdb`. You can override this using
113 {option}`services.foundationdb.dataDir`, e.g.
116 services.foundationdb.dataDir = "/data/fdb";
120 Similarly, logs are stored under {file}`/var/log/foundationdb`
121 by default, and there is a corresponding
122 {option}`services.foundationdb.logDir` as well.
124 ## Scaling processes and backup agents {#module-services-foundationdb-scaling}
126 Scaling the number of server processes is quite easy; simply specify
127 {option}`services.foundationdb.serverProcesses` to be the number of
128 FoundationDB worker processes that should be started on the machine.
130 FoundationDB worker processes typically require 4GB of RAM per-process at
131 minimum for good performance, so this option is set to 1 by default since
132 the maximum amount of RAM is unknown. You're advised to abide by this
133 restriction, so pick a number of processes so that each has 4GB or more.
135 A similar option exists in order to scale backup agent processes,
136 {option}`services.foundationdb.backupProcesses`. Backup agents are
137 not as performance/RAM sensitive, so feel free to experiment with the number
138 of available backup processes.
140 ## Clustering {#module-services-foundationdb-clustering}
142 FoundationDB on NixOS works similarly to other Linux systems, so this
143 section will be brief. Please refer to the full FoundationDB documentation
144 for more on clustering.
146 FoundationDB organizes clusters using a set of
147 *coordinators*, which are just specially-designated
148 worker processes. By default, every installation of FoundationDB on NixOS
149 will start as its own individual cluster, with a single coordinator: the
150 first worker process on {command}`localhost`.
152 Coordinators are specified globally using the
153 {command}`/etc/foundationdb/fdb.cluster` file, which all servers and
154 client applications will use to find and join coordinators. Note that this
155 file *can not* be managed by NixOS so easily:
156 FoundationDB is designed so that it will rewrite the file at runtime for all
157 clients and nodes when cluster coordinators change, with clients
158 transparently handling this without intervention. It is fundamentally a
159 mutable file, and you should not try to manage it in any way in NixOS.
161 When dealing with a cluster, there are two main things you want to do:
163 - Add a node to the cluster for storage/compute.
164 - Promote an ordinary worker to a coordinator.
166 A node must already be a member of the cluster in order to properly be
167 promoted to a coordinator, so you must always add it first if you wish to
170 To add a machine to a FoundationDB cluster:
172 - Choose one of the servers to start as the initial coordinator.
173 - Copy the {command}`/etc/foundationdb/fdb.cluster` file from this
174 server to all the other servers. Restart FoundationDB on all of these
175 other servers, so they join the cluster.
176 - All of these servers are now connected and working together in the
177 cluster, under the chosen coordinator.
179 At this point, you can add as many nodes as you want by just repeating the
180 above steps. By default there will still be a single coordinator: you can
181 use {command}`fdbcli` to change this and add new coordinators.
183 As a convenience, FoundationDB can automatically assign coordinators based
184 on the redundancy mode you wish to achieve for the cluster. Once all the
185 nodes have been joined, simply set the replication policy, and then issue
186 the {command}`coordinators auto` command
188 For example, assuming we have 3 nodes available, we can enable double
189 redundancy mode, then auto-select coordinators. For double redundancy, 3
190 coordinators is ideal: therefore FoundationDB will make
191 *every* node a coordinator automatically:
194 fdbcli> configure double ssd
195 fdbcli> coordinators auto
198 This will transparently update all the servers within seconds, and
199 appropriately rewrite the {command}`fdb.cluster` file, as well as
200 informing all client processes to do the same.
202 ## Client connectivity {#module-services-foundationdb-connectivity}
204 By default, all clients must use the current {command}`fdb.cluster`
205 file to access a given FoundationDB cluster. This file is located by default
206 in {command}`/etc/foundationdb/fdb.cluster` on all machines with the
207 FoundationDB service enabled, so you may copy the active one from your
208 cluster to a new node in order to connect, if it is not part of the cluster.
210 ## Client authorization and TLS {#module-services-foundationdb-authorization}
212 By default, any user who can connect to a FoundationDB process with the
213 correct cluster configuration can access anything. FoundationDB uses a
214 pluggable design to transport security, and out of the box it supports a
215 LibreSSL-based plugin for TLS support. This plugin not only does in-flight
216 encryption, but also performs client authorization based on the given
217 endpoint's certificate chain. For example, a FoundationDB server may be
218 configured to only accept client connections over TLS, where the client TLS
219 certificate is from organization *Acme Co* in the
220 *Research and Development* unit.
222 Configuring TLS with FoundationDB is done using the
223 {option}`services.foundationdb.tls` options in order to control the
224 peer verification string, as well as the certificate and its private key.
226 Note that the certificate and its private key must be accessible to the
227 FoundationDB user account that the server runs under. These files are also
228 NOT managed by NixOS, as putting them into the store may reveal private
231 After you have a key and certificate file in place, it is not enough to
232 simply set the NixOS module options -- you must also configure the
233 {command}`fdb.cluster` file to specify that a given set of
234 coordinators use TLS. This is as simple as adding the suffix
235 {command}`:tls` to your cluster coordinator configuration, after the
236 port number. For example, assuming you have a coordinator on localhost with
237 the default configuration, simply specifying:
240 XXXXXX:XXXXXX@127.0.0.1:4500:tls
243 will configure all clients and server processes to use TLS from now on.
245 ## Backups and Disaster Recovery {#module-services-foundationdb-disaster-recovery}
247 The usual rules for doing FoundationDB backups apply on NixOS as written in
248 the FoundationDB manual. However, one important difference is the security
249 profile for NixOS: by default, the {command}`foundationdb` systemd
250 unit uses *Linux namespaces* to restrict write access to
251 the system, except for the log directory, data directory, and the
252 {command}`/etc/foundationdb/` directory. This is enforced by default
253 and cannot be disabled.
255 However, a side effect of this is that the {command}`fdbbackup`
256 command doesn't work properly for local filesystem backups: FoundationDB
257 uses a server process alongside the database processes to perform backups
258 and copy the backups to the filesystem. As a result, this process is put
259 under the restricted namespaces above: the backup process can only write to
260 a limited number of paths.
262 In order to allow flexible backup locations on local disks, the FoundationDB
263 NixOS module supports a
264 {option}`services.foundationdb.extraReadWritePaths` option. This
265 option takes a list of paths, and adds them to the systemd unit, allowing
266 the processes inside the service to write (and read) the specified
269 For example, to create backups in {command}`/opt/fdb-backups`, first
270 set up the paths in the module options:
274 services.foundationdb.extraReadWritePaths = [ "/opt/fdb-backups" ];
278 Restart the FoundationDB service, and it will now be able to write to this
279 directory (even if it does not yet exist.) Note: this path
280 *must* exist before restarting the unit. Otherwise,
281 systemd will not include it in the private FoundationDB namespace (and it
282 will not add it dynamically at runtime).
284 You can now perform a backup:
287 $ sudo -u foundationdb fdbbackup start -t default -d file:///opt/fdb-backups
288 $ sudo -u foundationdb fdbbackup status -t default
291 ## Known limitations {#module-services-foundationdb-limitations}
293 The FoundationDB setup for NixOS should currently be considered beta.
294 FoundationDB is not new software, but the NixOS compilation and integration
295 has only undergone fairly basic testing of all the available functionality.
297 - There is no way to specify individual parameters for individual
298 {command}`fdbserver` processes. Currently, all server processes
299 inherit all the global {command}`fdbmonitor` settings.
300 - Ruby bindings are not currently installed.
301 - Go bindings are not currently installed.
303 ## Options {#module-services-foundationdb-options}
305 NixOS's FoundationDB module allows you to configure all of the most relevant
306 configuration options for {command}`fdbmonitor`, matching it quite
307 closely. A complete list of options for the FoundationDB module may be found
308 [here](#opt-services.foundationdb.enable). You should
309 also read the FoundationDB documentation as well.
311 ## Full documentation {#module-services-foundationdb-full-docs}
313 FoundationDB is a complex piece of software, and requires careful
314 administration to properly use. Full documentation for administration can be
315 found here: <https://apple.github.io/foundationdb/>.