Skip to main content

A tool to install Python as SystemD or LaunchD service

Project description

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

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"

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

svci-1.1.0.tar.gz (13.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

svci-1.1.0-py3-none-any.whl (17.1 kB view details)

Uploaded Python 3

File details

Details for the file svci-1.1.0.tar.gz.

File metadata

  • Download URL: svci-1.1.0.tar.gz
  • Upload date:
  • Size: 13.9 kB
  • Tags: Source
  • Uploaded using 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}

File hashes

Hashes for svci-1.1.0.tar.gz
Algorithm Hash digest
SHA256 008d1099f959fcd172727625796cc4f45bee6568a749a3bcc45e1f0f9b2d4e07
MD5 58fbb89fef5a4b96d68989b4274d29d5
BLAKE2b-256 69161fed8a9f84dde436f44bb40e79fcd7312f14ae44615768feddb8b1813ac8

See more details on using hashes here.

File details

Details for the file svci-1.1.0-py3-none-any.whl.

File metadata

  • Download URL: svci-1.1.0-py3-none-any.whl
  • Upload date:
  • Size: 17.1 kB
  • Tags: Python 3
  • Uploaded using 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}

File hashes

Hashes for svci-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 12209b171296ebcfb80bcd4a230184b66e3a897d7bfe48b4733bc4a442493790
MD5 254718f4239ccc65e8d1e698da8ccb32
BLAKE2b-256 1d3b5f92e527a079fd0712794c3ba6564e5c024721a62e480d07351c14a12a51

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page