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"

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

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.1.tar.gz (14.2 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.1-py3-none-any.whl (17.4 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: svci-1.1.1.tar.gz
  • Upload date:
  • Size: 14.2 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.1.tar.gz
Algorithm Hash digest
SHA256 9d6cae19af4a7664bfa7d0550b141474d4cffe41bdecb1985731ce2560c084cc
MD5 cd1001190ab6a8ba9e6dda02549b9c68
BLAKE2b-256 b16e537a75f810d69ce593e9a25a0b4cf692aa750ede88b58d28a35dd28bcd1e

See more details on using hashes here.

File details

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

File metadata

  • Download URL: svci-1.1.1-py3-none-any.whl
  • Upload date:
  • Size: 17.4 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 52de24d560b150d0aa390fc9c72ba82f48bc64b6e6fbaa51cb3897aeea61576f
MD5 19ce54fe5a3022fad997d76b035eb295
BLAKE2b-256 18cb14d8389e8a117b0949e5d9d399de376158d32f610bf13e0fc46d9c122743

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