.TH UNITDORE 1 "2026-04-08" "0.1.0" "User Commands" .SH NAME unitdore \- manage container units via systemd, OpenRC or runit .SH SYNOPSIS .B unitdore [\fB\-\-config\fR \fIpath\fR] \fIcommand\fR [\fIarguments\fR] .SH DESCRIPTION .B unitdore bridges your container runtime (Podman, Docker) and systemd. It discovers running containers and podman\-compose stacks, stores them in a config file, and generates and manages systemd \fI.service\fR units for each one. .PP As root: system units, plus user units for users listed in \fBusers:\fR. As a normal user: own config (\fI~/.config/unitdore/units.yaml\fR) and user units only. .SH OPTIONS .TP .BR \-\-config " " \fIpath\fR Path to the units config file. Default: \fI/etc/unitdore/units.yaml\fR (non\-root: \fI~/.config/unitdore/units.yaml\fR) .SH COMMANDS .TP .B syncup Query all available runtimes for running containers and add any new ones to the config. Reconciles existing entries: if a configured unit's container no longer exists it is marked disabled with a reason. Podman is queried first; Docker only for names Podman does not have. podman\-compose containers become one \fBkind: stack\fR unit per project; existing member units are disabled. As root, rootless Podman containers of each user in \fBusers:\fR are also discovered. .TP .B install \fIname\fR | \fB\-\-all\fR Generate the service file for one enabled unit. Does not enable or start it. Use \fB\-\-dry\-run\fR to preview without writing. With \fB\-\-all\fR (and no name) it behaves like \fBinstallall\fR. .TP .B installall Generate service files for all enabled units. Disabled units that are installed are stopped, disabled and removed. Supports \fB\-\-dry\-run\fR. .TP .B uninstall \fIname\fR | \fB\-\-all\fR Disable, stop, and remove the service file for a unit. With \fB\-\-all\fR, for every installed unit in reverse startup order (same as \fBuninstallall\fR). .TP .B start \fIname\fR | \fB\-\-all\fR Start an installed unit without enabling it at boot. With \fB\-\-all\fR, start all enabled, installed units in startup order: equal \fBorder\fR in parallel, groups one after another (same as \fBstartall\fR). \fBorder\fR and \fBdelay\fR are also written into the service files (systemd \fBAfter=\fR and \fBExecStartPre\fR, OpenRC \fBafter\fR and \fBstart_pre\fR, runit \fBsv check\fR and \fBsleep\fR), so they apply at boot. .TP .B enable \fIname\fR | \fB\-\-all\fR Like \fBstart\fR, but also enable at boot (same as \fBenableall\fR). .TP .B stop \fIname\fR | \fB\-\-all\fR Stop an installed unit. With \fB\-\-all\fR, stop all installed units one at a time in reverse startup order (same as \fBstopall\fR). .TP .B update \fIname\fR Update a unit's config. An installed unit's service file is recreated, or stopped and removed if the unit is now disabled. Other installed units are regenerated too, as ordering depends on their neighbours. .RS .TP .BR \-\-order " " \fIn\fR Set the startup order. .TP .B \-\-enable Enable the unit. .TP .B \-\-disable Disable the unit. .RE .TP .B status Print a summary table of all managed units showing runtime, user, enabled state, installed state, systemd active state, and disabled reason. .TP .B list Print a table of all tracked units including the path to each service file. .TP .B edit Open the units config file in \fB$EDITOR\fR. Falls back to \fBnvim\fR, \fBnano\fR, \fBvi\fR in that order. .SH CONFIG FILE .B Location: \fI/etc/unitdore/units.yaml\fR .PP .nf prefix: "" # prepended to all service names, e.g. "prod-" suffix: "" # appended to all service names, e.g. "-svc" users: [] # root only: rootless users scanned by syncup units: - name: nginx runtime: podman # podman | docker user: "" # empty = system unit; set for rootless user unit command: "" # optional: override ExecStart order: 1 # startup order (lower = earlier) delay: 0s # delay after previous order group enabled: true disabled_reason: "" # auto-set by syncup reconciliation - name: shop # compose project name kind: stack # container (default) | stack runtime: podman project: shop working_dir: /srv/shop compose_files: [compose.yaml] compose_bin: /usr/bin/podman-compose .fi .PP Stack units run \fBpodman\-compose up\fR/\fBstop\fR when compose_bin, working_dir and compose_files exist; otherwise \fBpodman pod start\fR/\fBstop pod_\fR\fIproject\fR. .SH INIT SYSTEMS The \fBinit:\fR config key selects \fBsystemd\fR, \fBopenrc\fR or \fBrunit\fR. Empty means autodetect, falling back to systemd. OpenRC and runit are root only; rootless units run as system services as that user. runit service links go in \fBservice_dir:\fR (default \fI/var/service\fR or \fI/etc/service\fR). OpenRC scripts are written to \fI/etc/init.d/unitdore\-*\fR and runit services to \fI/etc/sv/unitdore\-*\fR. .SH GENERATED SERVICE FILES System units are written to \fI/etc/systemd/system/\fR and user units to \fI~/.config/systemd/user/\fR. Service names follow the pattern: .PP .RS \fBunitdore-\fR[\fIprefix\fR]\fIname\fR[\fIsuffix\fR]\fB.service\fR .RE .SH EXAMPLES Discover containers and install their service files: .PP .RS .nf sudo unitdore syncup sudo unitdore install \-\-all sudo unitdore start \-\-all .fi .RE .PP Preview generated service files without writing: .PP .RS sudo unitdore install nginx \-\-dry\-run .RE .PP Start a single container unit: .PP .RS sudo unitdore start nginx .RE .PP Change startup order and re\-apply service file: .PP .RS sudo unitdore update nginx \-\-order 2 .RE .SH FILES .TP .I /etc/unitdore/units.yaml Default configuration file. .TP .I ~/.config/unitdore/units.yaml Configuration file when run as a normal user. .TP .I /etc/systemd/system/unitdore-*.service Generated system unit files. .TP .I ~/.config/systemd/user/unitdore-*.service Generated rootless user unit files. .SH REQUIREMENTS systemd, OpenRC or runit; Podman and/or Docker (only installed runtimes are used); podman\-compose for compose\-mode stacks. User units need linger to start at boot: \fBloginctl enable\-linger\fR \fIuser\fR. Root is required for system units; the relevant user for rootless units. .SH SEE ALSO .BR systemctl (1), .BR podman (1), .BR docker (1) .SH AUTHORS Hein (Warky Devs) \(em https://warky.dev