sgcommand 5078558d01 Phase 5-7: README, Makefile, unit tests
- README.md: full usage docs
- Makefile: build/install/uninstall/test/lint/clean targets
- config/config_test.go: 7 tests (load, save, find, add, roundtrip, invalid yaml)
- runtime/runtime_test.go: 6 tests (get, available, ListRunning graceful degradation)
- systemd/generator_test.go: 7 tests (ServiceName, Generate system/user/custom/docker/unknown, buildExecCommands)
- fix: docker/podman ListRunning returns nil (not error) when daemon unavailable
- fix: invalid YAML test uses tab-indent which is genuinely unparseable
2026-04-03 14:50:36 +02:00

unitdore

A door you open and close for container units.

Unitdore bridges your container runtime (Podman, Docker) and systemd. It discovers running containers, stores them in a config file, and generates + manages systemd .service units for each one.

Install

make build
sudo make install

Or manually:

go build -o unitdore .
sudo cp unitdore /usr/local/bin/

Usage

Discover running containers

sudo unitdore syncup

Queries Podman and Docker for running containers, adds new ones to the config, and reconciles any that have disappeared (marking them disabled).

Edit the config

sudo unitdore edit

Opens /etc/unitdore/units.yaml in $EDITOR (falls back to vi).

Install systemd unit files

sudo unitdore install

Generates .service files for all enabled units and writes them to systemd. Use --dry-run to preview without writing.

sudo unitdore install --dry-run

Enable and start units

sudo unitdore active

Runs systemctl enable --now for all installed, enabled units in startup order.

Check status

sudo unitdore status

Prints a summary table:

NAME       RUNTIME   USER    ENABLED   INSTALLED   STATE             REASON
nginx      podman    root    yes       yes         active
myapp      docker    hein    yes       yes         active
oldthing   podman    hein    no        no          —                 container not found

Config file

Location: /etc/unitdore/units.yaml

units:
  - name: nginx
    runtime: podman          # podman | docker
    user: ""                 # empty = root/system unit
    command: ""              # optional: override ExecStart entirely
    order: 1                 # startup order (lower = earlier)
    delay: 0s                # delay after previous order group
    enabled: true
    disabled_reason: ""      # auto-set by syncup reconciliation

  - name: myapp
    runtime: docker
    user: hein               # rootless: generates user unit for this user
    order: 2
    delay: 5s
    enabled: true

Generated unit file (example)

# /etc/systemd/system/unitdore-nginx.service
# Generated by unitdore — do not edit manually

[Unit]
Description=Unitdore: nginx (podman)
After=network.target

[Service]
Type=simple
ExecStart=/usr/bin/podman start -a nginx
ExecStop=/usr/bin/podman stop nginx
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target

For user units (rootless containers), files go to ~/.config/systemd/user/ and target default.target.

Flags

--config string   path to units config file (default "/etc/unitdore/units.yaml")

Requirements

  • Go 1.21+
  • systemd
  • Podman and/or Docker (only what you have installed is used)
  • Root for system units; the relevant user for rootless units
Description
A door you open and close for container units. Manages systemd units for Podman/Docker containers.
Readme MIT 177 KiB
v0.0.9 Latest
2026-04-12 09:08:47 +00:00
Languages
Go 93.3%
Makefile 4.6%
Shell 2.1%