# unitctl
Docker-like process controls backed by pure systemd primitives from Elixir.
`unitctl` is the opinionated runtime layer above [`systemdkit`](https://hex.pm/packages/systemdkit). It starts and controls transient systemd services over D-Bus, without Docker and without shelling out to `systemctl`.
This package is intentionally early. It exists to claim the shape of the API and keep the low-level `systemdkit` package focused.
## Installation
```elixir
def deps do
[
{:unitctl, "~> 0.1.0-pre"}
]
end
```
## Example
```elixir
{:ok, instance} =
Unitctl.start(
name: "demo-worker",
command: ["/usr/bin/env", "sleep", "60"],
description: "Demo worker",
environment: %{"MIX_ENV" => "prod"},
working_directory: "/srv/demo",
resources: %{
memory_max: 256 * 1024 * 1024,
tasks_max: 64,
cpu_quota: 500_000
},
sandbox: %{
no_new_privileges: true,
private_tmp: true,
protect_system: "strict"
}
)
{:ok, state} = Unitctl.inspect(instance)
{:ok, stats} = Unitctl.stats(instance)
:ok = Unitctl.stop(instance)
```
## Scope
`systemdkit` answers: “How do I talk to systemd correctly from Elixir?”
`unitctl` answers: “How do I run and control app processes with container-like ergonomics using systemd?”
Planned areas:
- transient services and scopes
- resource controls through cgroups
- sandbox/security presets
- filesystem isolation
- credentials/secrets
- journald logs/follow
- stats and inspect APIs
- deployment-runtime primitives for Xamal-style bare-metal releases
## Integration tests
Integration tests require Linux with systemd and a system bus:
```sh
SYSTEMD_INTEGRATION=1 mix test
```
Maintainers can run the Lima-backed test wrapper from macOS:
```sh
scripts/integration_test.sh
```
## Non-goals
- no Docker dependency
- no `systemctl` shell wrappers
- no OCI image lifecycle in the first layer