Running as a systemd Service¶
For long-running deployments (lab workstation, dedicated server) we ship
a systemd user unit that wraps omnipath-utils serve so the API
restarts on failure and starts automatically at boot. This is what we
use for the public service at utils.omnipathdb.org and is also the
recommended setup for self-hosted instances with custom database
builds.
The unit file is part of the repository at
deploy/systemd/omnipath-utils.service. It assumes:
- the package is installed into a virtualenv at
~/deploy/omnipath-utils/.venv/, ~/deploy/omnipath-utils/.envholds the runtime configuration (DB URL, host, port),- a PostgreSQL container can be started via
docker compose up -d dbfrom~/deploy/omnipath-utils/.
One-time setup¶
Lay out the deploy directory the unit expects, then build the database (see Database Build for build options including multi-organism and custom resource sets):
mkdir -p ~/deploy/omnipath-utils && cd ~/deploy/omnipath-utils
# Postgres for the API to talk to
cat > docker-compose.yml << 'YAML'
services:
db:
image: postgres:16
environment:
POSTGRES_DB: omnipath_utils
POSTGRES_USER: omnipath
POSTGRES_PASSWORD: CHANGE_ME
ports: ["127.0.0.1:5434:5432"]
volumes: [pgdata:/var/lib/postgresql/data]
restart: unless-stopped
volumes: { pgdata: {} }
YAML
docker compose up -d db
# Runtime config (read by the systemd unit)
cat > .env << 'ENV'
OMNIPATH_UTILS_DB_URL=postgresql+psycopg://omnipath:CHANGE_ME@localhost:5434/omnipath_utils
OMNIPATH_UTILS_HOST=127.0.0.1
OMNIPATH_UTILS_PORT=8083
ENV
# Virtualenv + database build
uv venv .venv --python 3.13
.venv/bin/pip install "omnipath-utils[server]"
.venv/bin/omnipath-utils build --db-url "$(grep DB_URL .env | cut -d= -f2-)" --organisms 9606
Install the unit¶
Run as the user that will own the service (does not need to be root):
git clone https://github.com/saezlab/omnipath-utils.git ~/dev/omnipath-utils
mkdir -p ~/.config/systemd/user
ln -sf ~/dev/omnipath-utils/deploy/systemd/omnipath-utils.service \
~/.config/systemd/user/omnipath-utils.service
systemctl --user daemon-reload
systemctl --user enable --now omnipath-utils.service
To survive reboots without an active login session, enable lingering once as root:
sudo loginctl enable-linger "$USER"
Custom databases¶
OMNIPATH_UTILS_DB_URL can point at any PostgreSQL instance you
control — including a database you built with a custom organism
set, custom resources, or schema overrides. The service is stateless
beyond that connection, so swapping in a new DB is a systemctl --user
restart omnipath-utils away.
If your environment needs additional setup (e.g. activating a Conda
profile or exporting an LD_LIBRARY_PATH on NixOS), drop the export
statements into ~/dev/.envrc. The unit sources that file when
present and ignores it otherwise.
Operate¶
systemctl --user status omnipath-utils
systemctl --user restart omnipath-utils
systemctl --user stop omnipath-utils
journalctl --user -u omnipath-utils -f # live journal
tail -f ~/deploy/omnipath-utils/server.log # uvicorn access log
The service binds to 127.0.0.1 by default. To expose it publicly,
front it with nginx, Caddy, or an SSH reverse tunnel and terminate TLS
there — do not bind 0.0.0.0 directly on an untrusted network.
System-wide alternative¶
If you prefer a system service (e.g. a dedicated omnipath system
account with no login shell), copy the same unit to
/etc/systemd/system/omnipath-utils.service, replace %h with the
target home directory, add User= / Group= lines under [Service],
and run systemctl daemon-reload && systemctl enable --now
omnipath-utils.service as root. No other changes are required.
Multiple instances on one host¶
For shared development hosts where several instances of the service
need to run side-by-side (e.g. a staging deployment alongside a
production deployment, or a per-feature dev URL), a templated unit is
shipped at deploy/systemd/omnipath-utils@.service.
Lay each instance out at ~/instances/<name>/ — with src/,
.venv/, .env, and docker-compose.yml (Postgres on a dedicated
port) — then enable:
systemctl --user enable --now omnipath-utils@staging.service
Each instance gets its own database, port, and server.log. The same
loginctl enable-linger once-per-user setup applies.