umoci unpack: Extract an OCI Image to a Rootfs
umoci unpack extracts an OCI image from an image layout into an OCI runtime bundle (a rootfs plus config) you can inspect or run.
When you need the actual files inside an OCI image (to inspect, patch, or run with runc) umoci unpack turns an OCI layout into a rootfs bundle.
What it does
umoci unpack reads an image from an OCI image-layout directory (created by skopeo copy to an oci: target, for example) and extracts the selected tag into a runtime bundle: a rootfs/ directory and a config.json. You can then modify the rootfs and umoci repack it into a new image.
Common usage
# get an OCI layout with skopeo
skopeo copy docker://alpine:3.20 oci:alpine-layout:3.20
# unpack the tag into a bundle
umoci unpack --image alpine-layout:3.20 bundle/
# inspect or edit bundle/rootfs, then repack
umoci repack --image alpine-layout:3.20-patched bundle/Options
| Flag | What it does |
|---|---|
| --image <layout>[:tag] | OCI image layout and tag to operate on |
| --rootless | Unpack without root (maps ownership into a user namespace) |
| --keep-dirlinks | Preserve directory symlinks during unpack |
| unpack BUNDLE | Destination bundle directory (positional) |
In CI
umoci is common in unprivileged image pipelines: skopeo produces an OCI layout, umoci unpacks it to a rootfs, a build step edits files, and umoci repack rebuilds the image, all without a daemon. Use --rootless on runners without root.
Common errors in CI
"image path does not exist" or "tag not found" means the OCI layout or tag name is wrong; confirm what skopeo wrote. "operation not permitted" during unpack of a root-owned rootfs means you need --rootless or actual root. "invalid image source" means the directory is not a valid OCI layout (missing index.json or blobs).