> ## Documentation Index
> Fetch the complete documentation index at: https://flox.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flox and systemd

> Run Flox environment services as persistent systemd units.

Flox environments have a built-in concept of [services](/concepts/services).
Flox environment services are managed by invoking the `flox services`
category of sub-commands such as [`flox services status`](/man/flox-services-status).
In some scenarios, you may want to register Flox services to be run and managed
by the operating system's systemd.
For example, systemd can auto-start services when the host is booting
or when a service crashes.

This tutorial shows how to create and use systemd services with Flox
by creating unit files manually.
You will learn how to run a Flox environment service as both a
**systemd user unit** and a **systemd system unit**.

## Prerequisites

* A Linux system with systemd support.
  This tutorial was tested on Ubuntu 24.04 and 26.04.
* Flox installed in multi-user mode.
  This tutorial was tested on Flox 1.11.0.

## Constraints

* The systemd service that invokes Flox cannot run as root.
* The service cannot listen on a port with a value less than 1024.
* The UID for the user running the systemd service should be >= 1000
  for logs to function properly.
  See [flox#2e789b5](https://github.com/flox/flox/commit/2e789b55de153b80a23367b236334ffbe84d6289) for details.
* Logs may not function properly if the process forks.
  See [flox#9b1e750](https://github.com/flox/flox/commit/9b1e7504fd5dd482d9afeda1e21ecfe8d1f86593) for details.

## Run a Flox environment service as a systemd user unit

In this section you will set up a Redis service from a FloxHub environment
and run it as a systemd user unit.

### Create the Redis environment locally

Pull the `flox/redis` environment from FloxHub into your home directory:

```bash theme={null}
flox pull flox/redis -d ~/redis
```

### Test the environment with Flox services

Before creating the systemd unit,
verify that the environment works:

```console theme={null}
$ cd ~/redis
$ flox activate -s
$ flox services status
$ redis-cli -p $REDIS_PORT ping
$ exit
```

### Create the systemd user service

Create the systemd user unit file:

```bash theme={null}
mkdir -p ~/.config/systemd/user/
cat > ~/.config/systemd/user/redis.service << 'EOF'
[Unit]
Description=Redis Server (Flox)

[Service]
ExecStart=flox activate -d %h/redis -c 'redis-server --bind $REDIS_HOST --port $REDIS_PORT --daemonize no --dir $REDIS_DATA'

[Install]
WantedBy=default.target
EOF
```

By default, systemd user units only run while the user is logged in.
Enabling **lingering** allows the service to start at boot without a login session.
If you only need the service to run while you are logged in,
you can skip this step.

```bash theme={null}
sudo loginctl enable-linger $USER
```

Load, enable, and start the service:

```bash theme={null}
systemctl --user daemon-reload &&
systemctl --user enable redis.service &&
systemctl --user start redis.service
```

Verify the service is running:

```bash theme={null}
systemctl --user status redis.service
```

Verify Redis is responding:

```bash theme={null}
flox activate -d ~/redis -c 'redis-cli -p "$REDIS_PORT" ping'
# should respond PONG
```

### User unit cleanup

To stop and fully remove the systemd user unit:

```bash theme={null}
systemctl --user stop redis.service
systemctl --user disable redis.service
rm ~/.config/systemd/user/redis.service
systemctl --user daemon-reload
```

## Run a Flox environment service as a systemd system unit

For services that should run under a dedicated system user rather than
your personal account,
you can create a system-level systemd unit instead.

### Create a dedicated Redis user and environment

```bash theme={null}
sudo useradd --system --create-home --shell /usr/sbin/nologin redis &&
sudo -u redis flox pull flox/redis -d /home/redis/redis
```

### Create the system unit file

Since the `redis` user has no login session,
user units will not work.
Create a system unit instead:

```bash theme={null}
sudo tee /etc/systemd/system/redis.service << 'EOF'
[Unit]
Description=Redis Server (Flox)

[Service]
User=redis
ExecStart=flox activate -d /home/redis/redis -c 'redis-server --bind $REDIS_HOST --port $REDIS_PORT --daemonize no --dir $REDIS_DATA'

[Install]
WantedBy=multi-user.target
EOF
```

<Note>
  **Note**

  Enable lingering is not needed for system units.
  System units start at boot automatically.
</Note>

### Load, enable, and start

```bash theme={null}
sudo systemctl daemon-reload &&
sudo systemctl enable redis.service &&
sudo systemctl start redis.service
```

### Verify

```bash theme={null}
sudo systemctl status redis.service
```

```bash theme={null}
flox activate -d ~/redis -c 'redis-cli -p $REDIS_PORT ping'
# should respond PONG
```

<Note>
  **Note**

  Key differences from the user unit approach:
  the system unit goes in `/etc/systemd/system/`,
  uses `multi-user.target`,
  requires `sudo`,
  and no lingering is needed.
</Note>

### System unit cleanup

To stop and fully remove the systemd system unit:

```bash theme={null}
sudo systemctl stop redis.service
sudo systemctl disable redis.service
sudo rm /etc/systemd/system/redis.service
sudo systemctl daemon-reload
```

## Where to next?

* [Learn more about services](/concepts/services)

* [Sharing environments](/tutorials/sharing-environments)
