Deploying on Linux
systemd
The following includes an example systemd unit for running TigerBeetle with Linux systems that use systemd. The unit is configured to start a single-node cluster, so you may need to adjust it for other cluster configurations.
See the Quick Start for an example of how to run a single- vs multi-node cluster.
tigerbeetle.service
[Unit]
Description=TigerBeetle Replica
Documentation=https://docs.tigerbeetle.com/
After=network-online.target
Wants=network-online.target systemd-networkd-wait-online.service
[Service]
AmbientCapabilities=CAP_IPC_LOCK
Environment=TIGERBEETLE_CACHE_GRID_SIZE=1GiB
Environment=TIGERBEETLE_ADDRESSES=3001
Environment=TIGERBEETLE_REPLICA_COUNT=1
Environment=TIGERBEETLE_REPLICA_INDEX=0
Environment=TIGERBEETLE_CLUSTER_ID=0
Environment=TIGERBEETLE_DATA_FILE=%S/tigerbeetle/0_0.tigerbeetle
DevicePolicy=closed
DynamicUser=true
LockPersonality=true
ProtectClock=true
ProtectControlGroups=true
ProtectHome=true
ProtectHostname=true
ProtectKernelLogs=true
ProtectKernelModules=true
ProtectKernelTunables=true
ProtectProc=noaccess
ProtectSystem=strict
RestrictAddressFamilies=AF_INET AF_INET6
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
StateDirectory=tigerbeetle
StateDirectoryMode=700
Type=exec
ExecStart=/usr/local/bin/tigerbeetle start --cache-grid=${TIGERBEETLE_CACHE_GRID_SIZE} --addresses=${TIGERBEETLE_ADDRESSES} ${TIGERBEETLE_DATA_FILE}
[Install]
WantedBy=multi-user.target
Adjusting
You can adjust multiple aspects of this systemd service. Each specific adjustment is listed below with instructions.
It is not recommended to adjust some values directly in the service file. When this is the case, the instructions will ask you to instead use systemd's drop-in file support. Here's how to do that:
- Install the service unit in systemd (usually by adding it to
/etc/systemd/system
). - Create a drop-in file to override the environment variables.
Run
systemctl edit tigerbeetle.service
. This will bring you to an editor with instructions. - Add your overrides.
Example:
[Service]
Environment=TIGERBEETLE_CACHE_GRID_SIZE=4GiB
Environment=TIGERBEETLE_ADDRESSES=0.0.0.0:3001
Pre-start script
You can place the following script in /usr/local/bin
.
This script is responsible for ensuring that a replica data file exists.
It will create a data file if it doesn't exist.
tigerbeetle-pre-start.sh
#!/bin/sh
set -eu
if ! test -e "${TIGERBEETLE_DATA_FILE}"; then
/usr/local/bin/tigerbeetle format --cluster="${TIGERBEETLE_CLUSTER_ID}" --replica="${TIGERBEETLE_REPLICA_INDEX}" --replica-count="${TIGERBEETLE_REPLICA_COUNT}" "${TIGERBEETLE_DATA_FILE}"
fi
The script assumes that /bin/sh
exists and points to a POSIX-compliant shell, and the test
utility is either built-in or in the script's search path.
If this is not the case, adjust the script's shebang.
Add the following line to tigerbeetle.service
before ExecStart
.
ExecStartPre=/usr/local/bin/tigerbeetle-pre-start.sh
The service then executes the tigerbeetle-pre-start.sh
script before starting TigerBeetle.
TigerBeetle executable
The tigerbeetle
executable is assumed to be installed in /usr/local/bin
.
If this is not the case, adjust both tigerbeetle.service
and tigerbeetle-pre-start.sh
to use the correct location.
Environment variables
This service uses environment variables to provide default values for a simple single-node cluster. To configure a different cluster structure, or a cluster with different values, adjust the values in the environment variables. It is not recommended to change these default values directly in the service file, because it may be important to revert to the default behavior later. Instead, use systemd's drop-in file support.
State directory and replica data file path
This service configures a state directory, which means that systemd will make sure the directory is created before the service starts, and the directory will have the correct permissions.
This is especially important because the service uses systemd's dynamic user capabilities.
systemd forces the state directory to be in /var/lib
, which means that this service will have its replica data file at /var/lib/tigerbeetle/
.
It is not recommended to adjust the state directory directly in the service file, because it may be important to revert to the default behavior later.
Instead, use systemd's drop-in file support.
If you do so, remember to also adjust the TIGERBEETLE_DATA_FILE
environment variable, because it also hardcodes the tigerbeetle
state directory value.
Due to systemd's dynamic user capabilities, the replica data file path will not be owned by any existing user of the system.
Hardening configurations
Some hardening configurations are enabled for added security when running the service. It is not recommended to change these, since they have additional implications on all other configurations and values defined in this service file. If you wish to change those, you are expected to understand those implications and make any other adjustments accordingly.
Development mode
The service was created assuming it'll be used in a production scenario.
In case you want to use this service for development as well, you may need to adjust the ExecStart
line to include the --development
flag if your development environment doesn't support Direct IO, or if you require smaller cache sizes and/or batch sizes due to memory constraints.
Memory Locking
TigerBeetle requires RLIMIT_MEMLOCK
to be set high enough to:
- initialize io_uring, which requires memory shared with the kernel to be locked, as well as
- lock all allocated memory, and so prevent the kernel from swapping any pages to disk, which would not only affect performance but also bypass TigerBeetle's storage fault-tolerance.
If the required memory cannot be locked, then the environment should be modified either by (in order of preference):
- giving the local
tigerbeetle
binary theCAP_IPC_LOCK
capability (sudo setcap "cap_ipc_lock=+ep" ./tigerbeetle
), or - raising the global
memlock
value under/etc/security/limits.conf
, or else - disabling swap (io_uring may still require an RLIMIT increase).
Memory locking is disabled for development environments when using the --development
flag.
For Linux running under Docker, refer to Allowing MEMLOCK.