586c20f341
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
349 lines
12 KiB
Markdown
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.
|