Skip to main content

svci

A tool to install Python apps as systemd (Linux) or launchd (macOS) services.

Features

  • Cross-platform: systemd on Linux, launchd on macOS
  • Three service modes: user, system, and system-at-user
  • ConfigArgParse-based CLI with CLI args, environment variables, and TOML config file support
  • --pyproject flag to read config from [tool.svci] in pyproject.toml
  • Built-in templates with customizable overrides
  • Dry-run by default, --install to write to disk
  • DIY mode (--diy) generates a deployment bundle with service file + README
  • Pre-flight checks: .venv detection, linger status (Linux), existing service detection
  • Colored unified diff before overwriting existing services
  • D-Bus integration for systemd control (via jeepney)
  • Modern launchctl commands (bootstrap/bootout/kickstart) for macOS

Requirements

  • Python 3.10 or newer
  • Linux (systemd) or macOS (launchd)

Installation

pip install svci

Or with uv:

uv tool install svci

Usage

Dry run (preview the generated service file)

svci \
  --working-dir /path/to/app \
  --run-cmd "uv run app --host 127.0.0.1 --port 7867"

Install a user service

svci \
  --install \
  --enable \
  --start \
  --working-dir /path/to/app \
  --run-cmd "uv run app --host 127.0.0.1 --port 7867"

Install a system-wide service

sudo svci \
  --install \
  --service-mode system \
  --name my-app \
  --working-dir /srv/my-app \
  --run-cmd "uv run app --host 127.0.0.1 --port 7867"

Install a system-wide name@user service

sudo svci \
  --install \
  --service-mode system-at-user \
  --name my-app \
  --user myuser \
  --working-dir /srv/my-app \
  --run-cmd "uv run app --host 127.0.0.1 --port 7867"

Show platform-specific management commands

svci --help-platform --name my-app --service-mode user

This prints all the commands you need to manage the service (enable, start, stop, restart, logs, remove), tailored to your platform (systemd or launchd) and service mode. Works standalone or after install/dry-run.

Generate a DIY deployment bundle

svci \
  --diy \
  --working-dir /path/to/app \
  --run-cmd "uv run app --host 127.0.0.1 --port 7867"

This creates a ~/tmp/<name>/ directory with the service file and a README with manual deployment instructions.

Using pyproject.toml

Add a [tool.svci] section to your project's pyproject.toml:

[tool.svci]
name = "my-web-app"
description = "FastAPI app running via uv"
run_cmd = "uv run main.py --host 127.0.0.1 --port 8000"
service_mode = "user"

[tool.svci.environment]
DEBUG = "false"
PORT = "8000"
DATABASE_URL = "postgresql://localhost/mydb"

[tool.svci.systemd]
restart = "always"
restart_sec = 3

[tool.svci.launchd]
run_at_load = true

Then deploy with a single command from your project directory:

svci --pyproject --install --enable --start

Or point to a specific file:

svci --pyproject /path/to/pyproject.toml --install

When --pyproject is used, working_dir defaults to the directory containing the pyproject.toml. CLI arguments always override values from pyproject.toml.

[tool.svci] reference

Key Type Description
name string Service name (default: directory name)
description string Service description
run_cmd string Command to execute
working_dir string Working directory (default: pyproject.toml directory)
service_mode string "user", "system", or "system-at-user"
user string User for system modes
group string Group for system modes (Linux only)
template string Path to custom template file
Section Key Type Description
[tool.svci.environment] any string Environment variables set in the service
[tool.svci.systemd] restart string Restart policy (default: "on-failure")
[tool.svci.systemd] restart_sec integer Seconds between restarts (default: 5)
[tool.svci.launchd] run_at_load boolean Start at login/boot (default: true)

Configuration

svci looks for config files in:

  • ~/.config/svci/config.toml

Custom templates can be placed at:

  • ~/.config/svci/templates/systemd.service-template
  • ~/.config/svci/templates/launchd.plist-template

All CLI options can also be set via environment variables with the SVCI_ prefix (e.g., SVCI_WORKING_DIR, SVCI_RUN_CMD).

Priority order

CLI args > environment variables (SVCI_*) > --pyproject ([tool.svci]) > config file (~/.config/svci/config.toml) > defaults

Service modes

Mode Linux macOS
user systemd user unit (~/.config/systemd/user/) LaunchAgent (~/Library/LaunchAgents/)
system systemd system unit (/etc/systemd/system/) LaunchDaemon (/Library/LaunchDaemons/)
system-at-user name@.service template LaunchDaemon with UserName

License

MIT

Metadata

Release files for svci 1.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for svci 1.2.0
File Size Uploaded
svci-1.2.0.tar.gz 14.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for svci 1.2.0
File Interpreter ABI Platform
svci-1.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.9 kB

Release files / svci-1.2.0.tar.gz

Download URL svci-1.2.0.tar.gz
Size 14.3 kB
Tags Source
SHA-256 checksum
How to use checksums
9c5a2d0b28deb969b4fce911550e52d86e80f3c8c4fd72a2eed9b57afef2bb41
BLAKE2b-256 checksum
How to use checksums
e61d033eb0e20a6885153cd8879a67b21732f14e1c9ee3b319ce65075ef1b096
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / svci-1.2.0-py3-none-any.whl

Download URL svci-1.2.0-py3-none-any.whl
Size 17.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
52cb72de00af2a23c3c276bf125526fe264a6898da0889efa1edf103b405e610
BLAKE2b-256 checksum
How to use checksums
4062576f279e1462b81df4f961eda8db66c70abb2b6283cfb14145d66fa4c1bc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.3 {"installer":{"name":"uv","version":"0.11.3","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.2.0 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page