Skip to content

Systemd Deployment

This guide shows how to run the rs-ibed server directly on a Linux host with systemd.

  • A Linux host with systemd
  • The rs-ibed binary installed somewhere stable such as /opt/rs-ibed/rs-ibed
  • A config.toml file
  • Writable storage directories for uploads, cache, and optionally SQLite data

The server binary is rs-ibed. If your config file is not in the working directory, start it with --config /path/to/config.toml.

By default, RS-IBED reads secrets from environment variables using the IMG_ prefix:

  • IMG_AUTH_TOKEN
  • IMG_JWT_SECRET
  • IMG_DATABASE_URL

If you changed server.env_prefix in config.toml, rename these variables to match.

Create a working directory that contains your config file and writable data paths. The checked-in sample config uses ./data/uploads and ./data/cache, so those paths resolve relative to the service working directory.

Terminal window
sudo mkdir -p /opt/rs-ibed/data/uploads
sudo mkdir -p /opt/rs-ibed/data/cache
sudo mkdir -p /opt/rs-ibed/data

If you use SQLite, make sure the parent directory of the database file is also writable. For example, this URL needs /opt/rs-ibed/data to exist and be writable:

Terminal window
export IMG_DATABASE_URL="sqlite:///opt/rs-ibed/data/image_host.db?mode=rwc"

Storing secrets in an environment file is usually cleaner than embedding them directly in the unit.

IMG_AUTH_TOKEN=replace-with-a-long-random-token
IMG_JWT_SECRET=replace-with-a-long-random-secret
IMG_DATABASE_URL=sqlite:///opt/rs-ibed/data/image_host.db?mode=rwc

Save that as /etc/rs-ibed/rs-ibed.env and restrict its permissions.

Create /etc/systemd/system/rs-ibed.service:

[Unit]
Description=RS-IBED image hosting service
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
WorkingDirectory=/opt/rs-ibed
ExecStart=/opt/rs-ibed/rs-ibed --config /opt/rs-ibed/config.toml
EnvironmentFile=/etc/rs-ibed/rs-ibed.env
# You can also use inline values instead of EnvironmentFile:
# Environment=IMG_AUTH_TOKEN=replace-me
# Environment=IMG_JWT_SECRET=replace-me
# Environment=IMG_DATABASE_URL=sqlite:///opt/rs-ibed/data/image_host.db?mode=rwc
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target

Reload the unit files, enable the service, and start it:

Terminal window
sudo systemctl daemon-reload
sudo systemctl enable --now rs-ibed

Check current status:

Terminal window
sudo systemctl status rs-ibed

Follow logs:

Terminal window
sudo journalctl -u rs-ibed -f
  • Set IMG_DATABASE_URL to a SQLite path such as sqlite:///opt/rs-ibed/data/image_host.db?mode=rwc
  • Keep the SQLite database file on persistent storage
  • Keep uploads and cache on persistent storage too, otherwise image files and generated variants will disappear after cleanup or restart
  • Set IMG_DATABASE_URL to a PostgreSQL URL such as postgres://ibed:[email protected]:5432/ibed
  • On startup, the app connects to the maintenance database first and may create the target database automatically
  • The PostgreSQL user therefore needs permission to connect to postgres and create the target database, unless the target database already exists or you use postgres itself as the database name

After the service is running, open http://your-host:3000/ in a browser and upload a test image.

Then restart the service and confirm metadata, uploads, and cached variants still work:

Terminal window
sudo systemctl restart rs-ibed
sudo systemctl status rs-ibed