Files
slocker-lite/docs/slocker-lite.1.scd
ceamac 586c20f341 Add a man page, built optionally via scdoc
docs/slocker-lite.1.scd covers the full CLI (grouped like README.md's
flag table, including the DEBUGGING section for --mount/--umount/
--cleanup and the reassigned-short-option note), FILES, EXIT STATUS,
and SEE ALSO. meson.build builds it into slocker-lite.1 and installs it
under man1 only when scdoc is found on the host -- configuration still
succeeds without it, matching this project's existing "degrade
gracefully when an optional tool is missing" policy. Verified the
rendered page with `man --warnings` (clean, no troff warnings) and a
DESTDIR install.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Gv3s5jckJKzh6JkMoi2Akz
2026-09-07 17:08:08 +00:00

349 lines
12 KiB
Markdown

slocker-lite(1)
# NAME
slocker-lite - mount and sandbox OCI images without podman, docker, or kernel overlayfs
# SYNOPSIS
*slocker-lite* -r|--run _image.tar_ [_options_]... [-- _command_ [_args_...]]
*slocker-lite* -x|--exec _pid_ [-- _command_ [_args_...]]
*slocker-lite* --kill _pid_
*slocker-lite* -l|--list-images _directory_
*slocker-lite* -i|--inspect _image.tar_
*slocker-lite* -v|--volume _name_ _directory_
*slocker-lite* --list-volumes
*slocker-lite* --delete-volume|--delete-volume-full _name_
*slocker-lite* -n|--network _name_ (--extern|--intern) [_network-options_]...
*slocker-lite* --list-networks
*slocker-lite* --delete-network|--delete-network-full _name_
*slocker-lite* --list-processes
*slocker-lite* --clean-processes
*slocker-lite* [-c|--config-file _path_] -w|--write-config
*slocker-lite* -t|--test [-- _catch-options_]
*slocker-lite* -u|--up _images-dir_ [_compose-file_]
*slocker-lite* -d|--down [_compose-file_]
*slocker-lite* --list-containers
*slocker-lite* -h|--help
*slocker-lite* -V|--version
# DESCRIPTION
*slocker-lite* mounts an OCI Image Layout tar (the format produced by
*skopeo*(1), *podman-save*(1) with _--format oci-archive_, or a modern
*docker-save*(1)) and runs a sandboxed command against it, without needing
*podman*, *docker*, or a kernel that supports overlayfs.
It targets Android with a stock kernel: neither *podman* nor *docker* run
there (missing namespace support), and there is no kernel overlayfs. Image
layers are imported into *containers-storage*(1) and mounted with
*fuse-overlayfs*(1) (userspace, no kernel overlayfs needed), then the
requested command is sandboxed with *bwrap*(1) in "degraded mode" - using
only whichever _--unshare-xxx_ namespaces the running kernel actually
supports, instead of requiring the full set.
# OPTIONS
## RUNNING CONTAINERS
*-r*, *--run* _image.tar_
Mount, run *bwrap*(1) in the foreground, then unmount and clean up on
exit. Defaults to the image's own Entrypoint/Cmd (or _/bin/sh_ if
neither is set); pass _-- command [args...]_ to override.
*--no-nsenter*
With *--run*, bind the mount directly instead of *nsenter*(1)-ing
into *fuse-overlayfs*'s namespace. Automatic when running as root;
use this to force it off otherwise.
*-D*, *--daemonize*
With *--run*, fork into the background: detaches from the
controlling terminal, ignores SIGHUP, and redirects stdin from
_/dev/null_ and stdout/stderr to a log file under
_$XDG_STATE_HOME/slocker-lite/logs/_. Prints the session's pid and
log path, then returns.
*--user* _user_
With *--run*, run the command as this user (name or numeric uid)
instead of the image's own declared user (or root, if it declares
none). Resolved against the image's own _/etc/passwd_. Only takes
effect when *--run* executes as root.
*--group* _group_
With *--user*, use this group (name or numeric gid) instead of the
user's primary group.
*--hostname* _name_
With *--run*, set the sandbox's hostname. Only takes effect if the
running kernel supports _--unshare-uts_; ignored with a warning
otherwise.
*--env* _VAR=VALUE_
With *--run*, set an environment variable in the sandbox (overrides
the default PATH/HOME/PWD/TERM if given the same name). Repeatable;
combined with *--env-file* in command-line order, each later one
winning over an earlier one for the same name.
*--env-file* _file_
With *--run*, load environment variables from _file_ - one
_VAR=VALUE_ per line; blank lines and _#_-comments are skipped.
Repeatable.
*-v*, *--volume* _name-or-dir_ _container-path_
With *--run*, mount a volume into the sandbox (repeatable): the
first argument is an existing named volume, or, if it contains _/_,
a host directory path (created if missing); the second is the
absolute path inside the container to mount it at.
*-n*, *--network* _name_
With *--run*, join _name_ to the container as its own _ethN_
interface with an address from the network's subnet. Repeatable, no
membership limit.
*-p*, *--port-forward* [_network_:]_host-port_:_container-port_[/tcp|udp]
With *--run*, forward a port from the host into the container - TCP
by default, or UDP with an explicit _/udp_ suffix. _network_ is
optional, defaulting to the container's sole *--extern* network (an
error if it joined more than one without specifying). Repeatable,
including the same port pair once per protocol. Reachable via the
host's real, externally-facing IP; _localhost_/loopback access has a
known NAT-hairpinning limitation, for both protocols.
*--no-dns*
With *--run*, skip starting the per-session *dnsmasq*(8) resolver
even if it is available. Has no effect if no *-n*/*--network* was
given, or if *dnsmasq* is not installed.
*-x*, *--exec* _pid_
Join an already-running *--run* session (_pid_ must be one
*--list-processes* shows as running) and run a command inside its
container. Pass _-- command [args...]_ to specify it.
*--kill* _pid_
Stop a running *--run* session (_pid_ must be one *--list-processes*
shows as running): sends SIGTERM, waits up to 10 seconds, then
forces it with SIGKILL. Reaches every process the session started,
including daemonized/reparented ones a plain _kill pid_ would leave
behind, via a dedicated cgroup when available, or the sandboxed pid
namespace's own collapse-on-kill guarantee when not, falling back to
signaling the tracked pid alone if neither applies.
*--list-processes*
List running *--run* sessions found by their pid files under
_$XDG_STATE_HOME/slocker-lite/run/_, with their pid, container name,
and status (running or exited).
*--clean-processes*
Remove stale pid files (see *--list-processes*), and any
*-p*/*--port-forward* iptables rules or *-n*/*--network*
tap-relay/DNS-resolver processes, left behind by sessions that are
no longer running (e.g. after a crash).
## IMAGES
*-l*, *--list-images* _directory_
List OCI Image Layout tars (\*.tar, \*.tar.\*) found directly in
_directory_, with their name:tag.
*-i*, *--inspect* _image.tar_
Print an image's declared user, exposed ports, env, volumes, and
default command, without mounting or running it.
## VOLUMES
*-v*, *--volume* _name_ _directory_
Create a named volume mapped to a host directory (created if
missing), recorded in the config file's _volumes_ section. Fails if
the name or directory is already used by an existing volume. Volume
names cannot contain _/_. (See RUNNING CONTAINERS above for combined
use with *--run*.)
*--list-volumes*
List all named volumes with their host directory.
*--delete-volume* _name_
Remove a named volume from the config. The host directory is left
untouched.
*--delete-volume-full* _name_
Like *--delete-volume*, but also recursively deletes the volume's
host directory.
## NETWORKS
*-n*, *--network* _name_ (*--extern*|*--intern*)
Create a persistent named network: *--extern* is a bridge in its
own dedicated namespace, with an uplink out to the host's real
network so containers reach it via IPv4 NAT/forwarding; *--intern*
is a bridge inside its own dedicated, routeless namespace, only
reachable by other containers on the same network. Root-only. (See
RUNNING CONTAINERS above for combined use with *--run*.)
*--subnet* _cidr_
With network creation, override the auto-allocated IPv4 range.
*--with-ipv6*=_bool_
With network creation, enable/disable the auto-allocated IPv6 range.
Defaults to the config file's own _global.with-ipv6_.
*--subnet6* _cidr_
With network creation and IPv6 enabled, override the auto-allocated
IPv6 range.
*--with-veth*=_bool_
With network creation, _false_ forces the tap+relay join fallback
even on a kernel that supports veth (useful for testing that path;
otherwise chosen automatically whenever the running kernel lacks
veth support). Defaults to the config file's own _global.with-veth_.
*--list-networks*
List all named networks with their kind, IPv4 subnet, bridge name,
and IPv6 subnet.
*--delete-network* _name_
Remove a named network from the config. Its live
bridge/namespace/iptables state is left untouched.
*--delete-network-full* _name_
Like *--delete-network*, but also tears down its live state, so a
network with the same name can be created fresh afterward.
## CONFIGURATION
*-c*, *--config-file* _path_
Use _path_ instead of the default _config.yaml_ for the *global*
section only (log-level, unshare-\*, with-veth, with-ipv6) -
volumes/networks always come from the separate, always-fixed
_persistent.yaml_. Errors if _path_ does not exist. Combine with
*-w* to bootstrap a config file at a custom location. Always
available, regardless of command.
*-w*, *--write-config*
Write a complete global config file (creating it, and its parent
directory, if missing), filling in every global option's current or
default value. Never touches volumes/networks. Prints the file's
full path.
## TESTING
*-t*, *--test* [-- _catch-options_]
Run the built-in Catch2 test suite. A bare *-t* runs everything
Catch2 finds; select a category with a tag expression after a
literal _--_ (needed since Catch2's own *-r*/*--reporter* would
otherwise collide with *slocker-lite*'s own *-r*/*--run*).
## COMPOSE
*-u*, *--up* _images-dir_ [_compose-file_]
Start a docker-compose.yaml-subset project: mount every service's
image (from the OCI tars in _images-dir_), provision its declared
networks/volumes, then start each service's container in dependency
order, daemonized. _compose-file_ defaults to _compose.yaml_ in the
current directory. Root-only if the compose file declares any
networks.
*-d*, *--down* [_compose-file_]
Stop every container a matching *--up* run started and tear down
any networks it created that are no longer in use by anything else;
named volumes are always left in place. _compose-file_ defaults the
same way as *--up*.
*--list-containers*
List containers started by *--up*, with their compose file, service
name, container name, pid, and status.
## OTHER
*--log-level* _level_
Set log verbosity: trace, debug, info, warn, error, critical, off.
*-h*, *--help*
Print usage and exit.
*-V*, *--version*
Print version information and exit.
## DEBUGGING
These three commands bypass *--run*'s own mount/sandbox/cleanup lifecycle and
exist mainly for troubleshooting; they are long-option only. Earlier versions
used *-m*, *-u*, and *-c* as short forms for these; those letters have since
been reassigned (*-u* to *--up*, *-c* to *--config-file*) since compose
orchestration and per-invocation config overrides are both far more commonly
used.
*--mount* _image.tar_
Validate and mount an OCI Image Layout tar. See *-r*/*--run* and
*-x*/*--exec* above for the normal way to actually use an image.
*--umount* _layer-id_
Unmount a previously mounted layer (the ID printed by
*--mount*/*--run*, or from _containers-storage layers_).
*-r*/*--run* already unmounts on its own when done.
*--cleanup* _layer-id_
Delete a layer and its ancestor chain from local storage (unmount
it first).
# FILES
_$XDG_CONFIG_HOME/slocker-lite/config.yaml_ (falling back to
_$HOME/.config/slocker-lite/config.yaml_)
The *global* section only: log verbosity, bwrap namespace policy,
network-creation defaults. What *-c*/*--config-file* can point
elsewhere for a single invocation.
_$XDG_CONFIG_HOME/slocker-lite/persistent.yaml_
The _volumes_ and _networks_ sections: real, provisioned host state.
Always this one fixed file - *-c*/*--config-file* never affects it.
_$XDG_STATE_HOME/slocker-lite/run/_
Locked pid files for active *--run* sessions (falls back to
_$HOME/.local/state/slocker-lite/_).
_$XDG_STATE_HOME/slocker-lite/logs/_
Log files for *-D*/*--daemonize* sessions.
_$XDG_STATE_HOME/slocker-lite/compose/_
State files mapping a compose file to the pids *--up* started, used
by *--down* and *--list-containers*.
# EXIT STATUS
*0*
Success.
*1*
An error occurred (invalid arguments, a failed mount/run, etc.).
# SEE ALSO
*bwrap*(1), *containers-storage*(1), *fuse-overlayfs*(1), *nsenter*(1)
The project's README.md and docs/networking-design.md, installed alongside
the source, cover the full architecture and the networking design in more
detail than fits here.
# AUTHOR
Written by Viorel Munteanu. Licensed GPL-2.0-or-later.