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

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

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.2.0.tar.gz (14.3 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.2.0-py3-none-any.whl (17.6 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: svci-1.2.0.tar.gz
  • Upload date:
  • Size: 14.3 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.2.0.tar.gz
Algorithm Hash digest
SHA256 9c5a2d0b28deb969b4fce911550e52d86e80f3c8c4fd72a2eed9b57afef2bb41
MD5 8856266193aba50a4a80725b6958d87f
BLAKE2b-256 e61d033eb0e20a6885153cd8879a67b21732f14e1c9ee3b319ce65075ef1b096

See more details on using hashes here.

File details

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

File metadata

  • Download URL: svci-1.2.0-py3-none-any.whl
  • Upload date:
  • Size: 17.6 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.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 52cb72de00af2a23c3c276bf125526fe264a6898da0889efa1edf103b405e610
MD5 7eb74558aed573aa37e171822197b0cc
BLAKE2b-256 4062576f279e1462b81df4f961eda8db66c70abb2b6283cfb14145d66fa4c1bc

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