* Improve SSH key setup by auto-detecting key format * Add diagnostics for key validation and size
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
prefix: "" # optional: prepended to all service names, e.g. "prod-"
suffix: "" # optional: appended to all service names, e.g. "-svc"
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
Prefix and suffix
Set prefix and/or suffix to namespace your service files:
prefix: prod-
suffix: ""
Generates: unitdore-prod-nginx.service, unitdore-prod-myapp.service, etc.
Prefix/suffix apply to the service file name only — container names are unchanged.
Unnamed containers
If a container has no name, syncup uses its short container ID (first 12 chars) as the unit name.
You can rename it later with unitdore edit.
Generated unit files
See docs/generated-units.md for full examples covering:
- System units (root)
- User units (rootless)
- Docker vs Podman
- Custom commands
- Prefix/suffix naming
- Startup ordering
- Unnamed containers (short ID fallback)
Quick 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
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