Published 2021-04-28.
Last modified 2021-05-06.
Time to read: 4 minutes.
There are many ways to create and run Docker-compatible images.
Docker is probably the worst option, mostly because it runs as a daemon, and all *nix daemons run with root
privileges.
Also, the docker-ce
package lists iptables
as a dependency, which needs systemd
to be running normally,
and WSL2 only partially supports systemd
.
A Comprehensive Container Runtime Comparison provides helpful background information and an interesting historical viewpoint.
Open Container Initiative (OCI)
The latest evolution of Docker-compatible images, OCI image format (not to be confused with Oracle Cloud Infrastructure), is compatible with:
- AWS Lambda
- Azure Functions
- Azure Kubernetes Service
- Buildah
- Cloud Native Buildpacks
- CircleCI
- Docker
- Dokku
- GitLab
- Google Cloud
- Heroku
- Knative
- Kubernetes
podman
skopeo
- Spring Boot
- Tekton
Supported OCI formats include:
- Docker containers schema 1
- Docker containers schema 2
- Pods (groups of containers)
- Images
- Volumes
Buildah, podman and skopeo
This article discusses 3 related open source projects from RedHat / IBM that provide an alternative to Docker:
Buildah, podman
and skopeo
.
These 3 projects share a common source code base, and are
daemonless tools for managing Open Container Initiative (OCI) images.
Paraphrasing the reasons expressed in
Podman and Buildah for Docker Users
for using podman
instead of Docker,
wherever podman
is mentioned, read “podman
, Buildah and skopeo
”:
The Podman approach is simply to directly interact with the image registry,
with the container and image storage,
and with the Linux kernel through the runC
container runtime process (not a daemon).
Running Podman as a normal user means that Podman will,
by default, store images and containers in the user’s home directory.
Podman uses a repository in the user’s home directory:
~/.local/share/containers
(instead of /var/lib/docker
).
Despite the new locations for the local repositories, the images created by Docker and Podman are compatible with the OCI standard.
Podman can push to and pull from popular container registries like Quay.io and Docker hub, as well as private registries.
Buildah vs. podman
Podman
can build OCI containers interactively or in batch mode.
You can either build using a Dockerfile
using podman build
(batch mode),
or you can interactively run a container,
make changes to the running image, and then podman commit
those changes to a new image tag.
Buildah was written before podman
.
Some of Buildah's source code for creating and managing container images was ported to podman
.
The podman build
command is a subset of Buildah’s functionality.
However, apparently the differences between the two programs are important:
Buildah builds OCI images.
Confusingly, podman build
can also be used to build Docker images also,
but it’s incredibly slow and used up a lot of disk space by using the vfs
storage driver by default.
buildah bud
(‘build using Dockerfile’) was much faster for me, and uses the overlay storage driver.
– From Goodbye Docker: Purging is Such Sweet Sorrow by Ian Miell.
podman
Podman
supports developing, managing, and running OCI Containers on Linux systems, including WSL, without requiring root
privilege.
$ yes | sudo apt install buildah podman skopeo
Because podman
is a drop-in replacement for docker
, the following alias enables the docker
command to invoke podman
:
alias docker=podman
As described in How to Install and Use Podman on Ubuntu 20.04,
I added 'registry.access.redhat.com'
to the list of
registries
in /etc/containers/registries.conf
.
I also added gallery.ecr.aws
and
gcr.io
.
[registries.search] registries = ['docker.io', 'gallery.ecr.aws', 'gcr.io', 'quay.io', 'registry.access.redhat.com']
$ podman --help Manage pods, containers and images
Usage: podman [flags] podman [command]
Available Commands: attach Attach to a running container auto-update Auto update containers according to their auto-update policy build Build an image using instructions from Containerfiles commit Create new image based on the changed container container Manage containers cp Copy files/folders between a container and the local filesystem create Create but do not start a container diff Display the changes to the object's file system events Show podman events exec Run a process in a running container export Export container's filesystem contents as a tar archive generate Generate structured data based on containers and pods. healthcheck Manage health checks on containers help Help about any command history Show history of a specified image image Manage images images List images in local storage import Import a tarball to create a filesystem image info Display podman system information init Initialize one or more containers inspect Display the configuration of object denoted by ID kill Kill one or more running containers with a specific signal load Load an image from container archive login Login to a container registry logout Logout of a container registry logs Fetch the logs of one or more containers manifest Manipulate manifest lists and image indexes mount Mount a working container's root filesystem network Manage networks pause Pause all the processes in one or more containers play Play a pod and its containers from a structured file. pod Manage pods port List port mappings or a specific mapping for the container ps List containers pull Pull an image from a registry push Push an image to a specified destination restart Restart one or more containers rm Remove one or more containers rmi Removes one or more images from local storage run Run a command in a new container save Save image to an archive search Search registry for image start Start one or more containers stats Display a live stream of container resource usage statistics stop Stop one or more containers system Manage podman tag Add an additional name to a local image top Display the running processes of a container unmount Unmounts working container's root filesystem unpause Unpause the processes in one or more containers unshare Run a command in a modified user namespace untag Remove a name from a local image version Display the Podman Version Information volume Manage volumes wait Block on one or more containers
Flags: --cgroup-manager string Cgroup manager to use ("cgroupfs"|"systemd") (default "cgroupfs") --cni-config-dir string Path of the configuration directory for CNI networks --conmon string Path of the conmon binary -c, --connection string Connection to use for remote Podman service --events-backend string Events backend to use ("file"|"journald"|"none") (default "file") --help Help for podman --hooks-dir strings Set the OCI hooks directory path (may be set multiple times) (default [/usr/share/containers/oci/hooks.d]) --identity string path to SSH identity file, (CONTAINER_SSHKEY) --log-level string Log messages above specified level (debug, info, warn, error, fatal, panic) (default "error") --namespace string Set the libpod namespace, used to create separate views of the containers and pods on the system --network-cmd-path string Path to the command for configuring the network -r, --remote Access remote Podman service (default false) --root string Path to the root directory in which data, including images, is stored --runroot string Path to the 'run directory' where all state information is stored --runtime string Path to the OCI-compatible binary used to run containers, default is /usr/bin/runc --storage-driver string Select which storage driver is used to manage storage of images and containers (default is overlay) --storage-opt stringArray Used to pass an option to the storage driver --syslog Output logging information to syslog as well as the console (default false) --tmpdir string Path to the tmp directory for libpod state content.
Note: use the environment variable 'TMPDIR' to change the temporary storage location for container images, '/var/tmp'.
--url string URL to access Podman service (CONTAINER_HOST) (default "unix:/home/mslinn/.docker/run/podman/podman.sock") -v, --version Version of Podman
Use "podman [command] --help" for more information about a command.
podman info
$ podman info host: arch: amd64 buildahVersion: 1.15.2 cgroupVersion: v1 conmon: package: 'conmon: /usr/libexec/podman/conmon' path: /usr/libexec/podman/conmon version: 'conmon version 2.0.20, commit: unknown' cpus: 8 distribution: distribution: ubuntu version: "20.10" eventLogger: file hostname: Bear idMappings: gidmap: - container_id: 0 host_id: 1000 size: 1 - container_id: 1 host_id: 100000 size: 65536 uidmap: - container_id: 0 host_id: 1000 size: 1 - container_id: 1 host_id: 100000 size: 65536 kernel: 5.4.72-microsoft-standard-WSL2 linkmode: dynamic memFree: 897724416 memTotal: 6231638016 ociRuntime: name: runc package: 'containerd.io: /usr/bin/runc' path: /usr/bin/runc version: |- runc version 1.0.0-rc93 commit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec spec: 1.0.2-dev go: go1.13.15 libseccomp: 2.5.1 os: linux remoteSocket: path: /home/mslinn/.docker/run/podman/podman.sock rootless: true slirp4netns: executable: /bin/slirp4netns package: Unknown version: |- slirp4netns version 1.0.1 commit: 6a7b16babc95b6a3056b33fb45b74a6f62262dd4 libslirp: 4.3.1 swapFree: 0 swapTotal: 0 uptime: 306h 23m 6.37s (Approximately 12.75 days) registries: search: - quay.io - docker.io - gallery.ecr.aws - registry.access.redhat.com store: configFile: /home/mslinn/.config/containers/storage.conf containerStore: number: 8 paused: 0 running: 0 stopped: 8 graphDriverName: overlay graphOptions: overlay.mount_program: Executable: /bin/fuse-overlayfs Package: Unknown Version: |- fusermount3 version: 3.9.3 fuse-overlayfs: version 1.0.0 FUSE library version 3.9.3 using FUSE kernel interface version 7.31 graphRoot: /home/mslinn/.local/share/containers/storage graphStatus: Backing Filesystem: extfs Native Overlay Diff: "false" Supports d_type: "true" Using metacopy: "false" imageStore: number: 4 runRoot: /home/mslinn/.docker/run/containers volumePath: /home/mslinn/.local/share/containers/storage/volumes version: APIVersion: 1 Built: 0 BuiltTime: Wed Dec 31 19:00:00 1969 GitCommit: "" GoVersion: go1.14.7 OsArch: linux/amd64 Version: 2.0.6
podman container Help
$ man podman-container podman-container(1) General Commands Manual podman-container(1)
NAME podman-container - Manage containers
SYNOPSIS podman container subcommand
DESCRIPTION The container command allows you to manage containers
COMMANDS ┌───────────┬────────────────────────────────┬───────────────────────────────────┐ │Command │ Man Page │ Description │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │attach │ podman-attach(1) │ Attach to a running container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │checkpoint │ podman-container-checkpoint(1) │ Checkpoints one or more running │ │ │ │ containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │cleanup │ podman-container-cleanup(1) │ Cleanup the container's network │ │ │ │ and mountpoints. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │commit │ podman-commit(1) │ Create new image based on the │ │ │ │ changed container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │cp │ podman-cp(1) │ Copy files/folders between a │ │ │ │ container and the local │ │ │ │ filesystem. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │create │ podman-create(1) │ Create a new container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │diff │ podman-diff(1) │ Inspect changes on a container or │ │ │ │ image's filesystem. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │exec │ podman-exec(1) │ Execute a command in a running │ │ │ │ container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │exists │ podman-container-exists(1) │ Check if a container exists in │ │ │ │ local storage │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │export │ podman-export(1) │ Export a container's filesystem │ │ │ │ contents as a tar archive. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │init │ podman-init(1) │ Initialize a container │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │inspect │ podman-inspect(1) │ Display a container or image's │ │ │ │ configuration. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │kill │ podman-kill(1) │ Kill the main process in one or │ │ │ │ more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │list │ podman-ps(1) │ List the containers on the │ │ │ │ system.(alias ls) │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │logs │ podman-logs(1) │ Display the logs of a container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │mount │ podman-mount(1) │ Mount a working container's root │ │ │ │ filesystem. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │pause │ podman-pause(1) │ Pause one or more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │port │ podman-port(1) │ List port mappings for the │ │ │ │ container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │prune │ podman-container-prune(1) │ Remove all stopped containers │ │ │ │ from local storage. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │restart │ podman-restart(1) │ Restart one or more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │restore │ podman-container-restore(1) │ Restores one or more containers │ │ │ │ from a checkpoint. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │rm │ podman-rm(1) │ Remove one or more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │run │ podman-run(1) │ Run a command in a container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │runlabel │ podman-container-runlabel(1) │ Executes a command as described │ │ │ │ by a container image label. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │start │ podman-start(1) │ Starts one or more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │stats │ podman-stats(1) │ Display a live stream of one or │ │ │ │ more container's resource usage │ │ │ │ statistics. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │stop │ podman-stop(1) │ Stop one or more running │ │ │ │ containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │top │ podman-top(1) │ Display the running processes of │ │ │ │ a container. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │unmount │ podman-unmount(1) │ Unmount a working container's │ │ │ │ root filesystem.(Alias unmount) │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │unpause │ podman-unpause(1) │ Unpause one or more containers. │ ├───────────┼────────────────────────────────┼───────────────────────────────────┤ │wait │ podman-wait(1) │ Wait on one or more containers to │ │ │ │ stop and print their exit codes. │ └───────────┴────────────────────────────────┴───────────────────────────────────┘
SEE ALSO podman, podman-exec, podman-run
podman-container(1)
Podman Run Help
$ podman container run --help Run a command in a new container
Description: Runs a command in a new container from the given image
Usage: podman container run [flags] IMAGE [COMMAND [ARG...]]
Examples: podman container run imageID ls -alF /etc podman container run --network=host imageID dnf -y install java podman container run --volume /var/hostdir:/var/ctrdir -i -t fedora /bin/bash
Flags: --add-host strings Add a custom host-to-IP mapping (host:ip) (default []) --annotation strings Add annotations to container (key:value) -a, --attach strings Attach to STDIN, STDOUT or STDERR --authfile string Path of the authentication file. Use REGISTRY_AUTH_FILE environment variable to override --blkio-weight string Block IO weight (relative weight) accepts a weight value between 10 and 1000. --blkio-weight-device DEVICE_NAME:WEIGHT Block IO weight (relative device weight, format: DEVICE_NAME:WEIGHT) --cap-add strings Add capabilities to the container --cap-drop strings Drop capabilities from the container --cgroup-parent string Optional parent cgroup for the container --cgroupns string cgroup namespace to use --cgroups string control container cgroup configuration ("enabled"|"disabled"|"no-conmon") (default "enabled") --cidfile string Write the container ID to the file --conmon-pidfile string Path to the file that will receive the PID of conmon --cpu-period uint Limit the CPU CFS (Completely Fair Scheduler) period --cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota --cpu-rt-period uint Limit the CPU real-time period in microseconds --cpu-rt-runtime int Limit the CPU real-time runtime in microseconds --cpu-shares uint CPU shares (relative weight) --cpus float Number of CPUs. The default is 0.000 which means no limit --cpuset-cpus string CPUs in which to allow execution (0-3, 0,1) --cpuset-mems string Memory nodes (MEMs) in which to allow execution (0-3, 0,1). Only effective on NUMA systems. -d, --detach Run container in background and print container ID --detach-keys [a-Z] Override the key sequence for detaching a container. Format is a single character [a-Z] or a comma separated sequence of `ctrl-<value>`, where `<value>` is one of: `a-cf`, `@`, `^`, `[`, `\`, `]`, `^` or `_` (default "ctrl-p,ctrl-q") --device strings Add a host device to the container --device-cgroup-rule strings Add a rule to the cgroup allowed devices list --device-read-bps strings Limit read rate (bytes per second) from a device (e.g. --device-read-bps=/dev/sda:1mb) --device-read-iops strings Limit read rate (IO per second) from a device (e.g. --device-read-iops=/dev/sda:1000) --device-write-bps strings Limit write rate (bytes per second) to a device (e.g. --device-write-bps=/dev/sda:1mb) --device-write-iops strings Limit write rate (IO per second) to a device (e.g. --device-write-iops=/dev/sda:1000) --disable-content-trust This is a Docker specific option and is a NOOP --dns strings Set custom DNS servers --dns-opt strings Set custom DNS options --dns-search strings Set custom DNS search domains --entrypoint string Overwrite the default ENTRYPOINT of the image -e, --env stringArray Set environment variables in container (default [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin,TERM=xterm]) --env-file strings Read in a file of environment variables --env-host Use all current host environment variables in container --expose strings Expose a port or a range of ports --gidmap strings GID map to use for the user namespace --group-add strings Add additional groups to join --health-cmd string set a healthcheck command for the container ('none' disables the existing healthcheck) --health-interval string set an interval for the healthchecks (a value of disable results in no automatic timer setup) (default "30s") --health-retries uint the number of retries allowed before a healthcheck is considered to be unhealthy (default 3) --health-start-period string the initialization time needed for a container to bootstrap (default "0s") --health-timeout string the maximum time allowed to complete the healthcheck before an interval is considered failed (default "30s") -h, --hostname string Set container hostname --http-proxy Set proxy environment variables in the container based on the host proxy vars (default true) --image-volume string Tells podman how to handle the builtin image volumes ("bind"|"tmpfs"|"ignore") (default "bind") --init Run an init binary inside the container that forwards signals and reaps processes --init-path string Path to the container-init binary -i, --interactive Keep STDIN open even if not attached --ip string Specify a static IPv4 address for the container --ipc string IPC namespace to use --kernel-memory <number>[<unit>] Kernel memory limit (format: <number>[<unit>], where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes)) -l, --label stringArray Set metadata on container --label-file strings Read in a line delimited file of labels --log-driver string Logging driver for the container --log-opt strings Logging driver options --mac-address string Container MAC address (e.g. 92:d0:c6:0a:29:33) -m, --memory <number>[<unit>] Memory limit (format: <number>[<unit>], where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes)) --memory-reservation <number>[<unit>] Memory soft limit (format: <number>[<unit>], where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes)) --memory-swap string Swap limit equal to memory plus swap: '-1' to enable unlimited swap --memory-swappiness int Tune container memory swappiness (0 to 100, or -1 for system default) (default -1) --mount stringArray Attach a filesystem mount to the container --name string Assign a name to the container --network string Connect a container to a network (default "slirp4netns") --no-healthcheck Disable healthchecks on container --no-hosts Do not create /etc/hosts within the container, instead use the version from the image --oom-kill-disable Disable OOM Killer --oom-score-adj int Tune the host's OOM preferences (-1000 to 1000) --pid string PID namespace to use --pids-limit int Tune container pids limit (set 0 for unlimited, -1 for server defaults) --pod string Run container in an existing pod --pod-id-file string Read the pod ID from the file --privileged Give extended privileges to container -p, --publish strings Publish a container's port, or a range of ports, to the host (default []) -P, --publish-all Publish all exposed ports to random ports on the host interface --pull string Pull image before creating ("always"|"missing"|"never") (default "missing") -q, --quiet Suppress output information when pulling images --read-only Make containers root filesystem read-only --read-only-tmpfs When running containers in read-only mode mount a read-write tmpfs on /run, /tmp and /var/tmp (default true) --replace If a container with the same name exists, replace it --restart string Restart policy to apply when a container exits ("always"|"no"|"on-failure") --rm Remove container (and pod if created) after exit --rmi Remove container image unless used by other containers --rootfs The first argument is not an image but the rootfs to the exploded container --seccomp-policy string Policy for selecting a seccomp profile (experimental) (default "default") --security-opt stringArray Security Options --shm-size <number>[<unit>] Size of /dev/shm (format: <number>[<unit>], where unit = b (bytes), k (kilobytes), m (megabytes), or g (gigabytes)) (default "65536k") --sig-proxy Proxy received signals to the process (default true) --stop-signal string Signal to stop a container. Default is SIGTERM --stop-timeout uint Timeout (in seconds) to stop a container. Default is 10 (default 10) --subgidname string Name of range listed in /etc/subgid for use in user namespace --subuidname string Name of range listed in /etc/subuid for use in user namespace --sysctl strings Sysctl options --systemd string Run container in systemd mode ("true"|"false"|"always") (default "true") --tmpfs tmpfs Mount a temporary filesystem (tmpfs) into a container -t, --tty Allocate a pseudo-TTY for container --uidmap strings UID map to use for the user namespace --ulimit strings Ulimit options -u, --user string Username or UID (format: <name|uid>[:<group|gid>]) --userns string User namespace to use --uts string UTS namespace to use -v, --volume stringArray Bind mount a volume into the container --volumes-from strings Mount volumes from the specified container(s) -w, --workdir string Working directory inside the container
podman run
From Building and Deploying Lambdas from a Docker Container by Keith Gregory:
$ podman run \ -it \ --entrypoint /bin/bash \ --rm \ -v /tmp:/mnt \ amazon/aws-lambda-python:3.8 Trying to pull quay.io/amazon/aws-lambda-python:3.8... Requesting bear token: invalid status code from registry 405 (Method Not Allowed) Trying to pull docker.io/amazon/aws-lambda-python:3.8... Getting image source signatures Copying blob df513d38f4d9 skipped: already exists Copying blob 2e2bb77ae2dc skipped: already exists Copying blob 031c6369fb2b skipped: already exists Copying blob 03ac043af787 skipped: already exists Copying blob 842c9dce67e8 skipped: already exists Copying blob 1de4740de1c2 [--------------------------------------] 0.0b / 0.0b Copying config e12ea62c55 done Writing manifest to image destination Storing signatures bash-4.2# pwd /var/task
Cleaning Up a Container
podman container cleanup
is a good command to know about.
$ podman container cleanup --help Cleanup network and mountpoints of one or more containers Description: podman container cleanup Cleans up mount points and network stacks on one or more containers from the host. The container name or ID can be used. This command is used internally when running containers, but can also be used if container cleanup has failed when a container exits. Usage: podman container cleanup [options] CONTAINER [CONTAINER...] Examples: podman container cleanup --latest podman container cleanup ctrID1 ctrID2 ctrID3 podman container cleanup --all Options: -a, --all Cleans up all containers --exec string Clean up the given exec session instead of the container -l, --latest Act on the latest container podman is aware of Not supported with the "--remote" flag --rm After cleanup, remove the container entirely --rmi After cleanup, remove the image entirely
Buildah
Buildah is a drop-in replacement for using docker build
and a Dockerfile
.
build-using-dockerfile/bud
for each build,
Buildah has commands to actually interact with the temporary container created during the build process.
(Docker uses temporary, or intermediate containers, too, but you don’t really interact with them while the image is being built.)
Unlike
docker build
, Buildah doesn’t commit changes to a layer automatically for every instruction in the Dockerfile
– it builds everything from top to bottom, every time.
On the positive side, this means non-cached builds (for example, those you would do with automation or build pipelines)
end up being somewhat faster than their Docker build counterparts, especially if there are many instructions.
– From Getting started with Buildah., published by
opensource.com
Some key Buildah subcommands:
- buildah bud
- Buildah’s
build-using-dockerfile
, orbud
argument makes it behave just likedocker build
does. - buildah from
- Build up a container root filesystem from an image or from scratch.
- buildah config
- Adjust defaults in the image's configuration blob.
- buildah run
-
buildah run
is for running commands that build a container image. This is similar toRUN
in aDockerfile
, and unlikedocker run
. - buildah commit
- Commit changes to the container to a new image.
- buildah push
- Push images to registries (such a Quay) or a local
dockerd
instance.
Buildah Help
$ buildah -h A tool that facilitates building OCI images
Usage: buildah [flags] buildah [command]
Available Commands: add Add content to the container build-using-dockerfile Build an image using instructions in a Dockerfile commit Create an image from a working container config Update image configuration settings containers List working containers and their base images copy Copy content into the container from Create a working container based on an image help Help about any command images List images in local storage info Display Buildah system information inspect Inspect the configuration of a container or image login Login to a container registry logout Logout of a container registry manifest Manipulate manifest lists and image indexes mount Mount a working container's root filesystem pull Pull an image from the specified location push Push an image to a specified destination rename Rename a container rm Remove one or more working containers rmi Remove one or more images from local storage run Run a command inside of the container tag Add an additional name to a local image umount Unmount the root file system of the specified working containers unshare Run a command in a modified user namespace version Display the Buildah version information
Flags: -h, --help help for buildah --log-level string The log level to be used. Either "debug", "info", "warn" or "error". (default "error") --registries-conf string path to registries.conf file (not usually used) --registries-conf-dir string path to registries.conf.d directory (not usually used) --root string storage root dir (default "/var/lib/containers/storage") --runroot string storage state dir (default "/var/run/containers/storage") --storage-driver string storage-driver --storage-opt strings storage driver option --userns-gid-map ctrID:hostID:length default ctrID:hostID:length GID mapping to use --userns-uid-map ctrID:hostID:length default ctrID:hostID:length UID mapping to use -v, --version version for buildah
Use "buildah [command] --help" for more information about a command.
Buildah / Dockerfile Compatibility
Buildah can create an image from a Dockerfile by typing:
$ buildah bud -t hello .
…instead of:
$ sudo docker build -t hello .
Buildah can create an image called hello
from the Dockerfile
and the Python app by typing:
$ buildah bud -t hello . STEP 1: FROM public.ecr.aws/lambda/python:3.8 Getting image source signatures Copying blob 1de4740de1c2 done Copying blob 2e2bb77ae2dc done Copying blob df513d38f4d9 done Copying blob 03ac043af787 done Copying blob 031c6369fb2b done Copying blob 842c9dce67e8 done Copying config e12ea62c55 done Writing manifest to image destination Storing signatures STEP 2: COPY app.py ./ STEP 3: CMD ["app.handler"] STEP 4: COMMIT hello Getting image source signatures Copying blob 109f575f8e6a skipped: already exists Copying blob ff64b4f854ad skipped: already exists Copying blob dd66ad8702f4 skipped: already exists Copying blob d6fa53d6caa6 skipped: already exists Copying blob 80166c3283e5 skipped: already exists Copying blob 61f74564c3aa skipped: already exists Copying blob d95ebdc79761 done Copying config 40ef32b39c done Writing manifest to image destination Storing signatures --> 40ef32b39cf 40ef32b39cf4ffd3d2e4e3426bec4a5ea168524f7f3fcfe863a378abd9794270
Once the build is complete, the new image can be displayed with the buildah images
command:
$ buildah images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/hello latest 40ef32b39cf4 56 seconds ago 622 MB
The new image, tagged hello:latest
, can be pushed to a remote image registry.
This is easily accomplished with the buildah push
command.
buildah push Help
$ man buildah-push buildah-push(1) General Commands Manual buildah-push(1)
NAME buildah-push - Push an image from local storage to elsewhere.
SYNOPSIS buildah push [options] image [destination]
DESCRIPTION Pushes an image from local storage to a specified destination, decompressing and recompessing layers as needed.
imageID Image stored in local container/storage
DESTINATION The DESTINATION is a location to store container images. If omitted, the source image parameter will be reused as destination.
The Image "DESTINATION" uses a "transport":"details" format. Multiple transports are supported:
dir:path An existing local directory path storing the manifest, layer tarballs and signatures as individual files. This is a non-standardized format, primarily useful for debugging or noninvasive container inspection.
docker://docker-reference An image in a registry implementing the "Docker Registry HTTP API V2". By default, uses the authorization state in $XDG\_RUNTIME\_DIR/containers/auth.json, which is set using (buildah login). If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using (docker login). If docker-reference does not include a registry name, the image will be pushed to a registry running on local‐ host.
docker-archive:path[:docker-reference] An image is stored in the docker save formatted file. docker-reference is only used when creating such a file, and it must not contain a digest.
docker-daemon:docker-reference An image _dockerreference stored in the docker daemon internal storage. If _dockerreference does not begin with a valid registry name (a domain name containing "." or the reserved name "localhost") then the default registry name "docker.io" will be prepended. _dockerreference must contain either a tag or a digest. Alternatively, when reading images, the format can also be docker-daemon:algo:digest (an image ID).
oci:path:tag An image tag in a directory compliant with "Open Container Image Layout Specification" at path.
oci-archive:path:tag An image tag in a tar archive compliant with "Open Container Image Layout Specification" at path.
If the transport part of DESTINATION is omitted, "docker://" is assumed.
OPTIONS --authfile path
Path of the authentication file. Default is ${XDG_RUNTIME_DIR}/containers/auth.json, which is set using buildah lo‐ gin. If the authorization state is not found there, $HOME/.docker/config.json is checked, which is set using docker login.
--cert-dir path
Use certificates at path (*.crt, *.cert, *.key) to connect to the registry. Default certificates directory is /etc/containers/certs.d.
--creds creds
The [username[:password]] to use to authenticate with the registry if required. If one or both values are not sup‐ plied, a command line prompt will appear and the value can be entered. The password is entered without echo.
--digestfile Digestfile
After copying the image, write the digest of the resulting image to the file.
--disable-compression, -D
Don't compress copies of filesystem layers which will be pushed.
--encryption-key key
The [protocol:keyfile] specifies the encryption protocol, which can be JWE (RFC7516), PGP (RFC4880), and PKCS7 (RFC2315) and the key material required for image encryption. For instance, jwe:/path/to/key.pem or pgp:admin@exam‐ ple.com or pkcs7:/path/to/x509-file.
--format, -f
Manifest Type (oci, v2s1, or v2s2) to use when saving image to directory using the 'dir:' transport (default is manifest type of source)
--quiet, -q
When writing the output image, suppress progress output.
--remove-signatures
Don't copy signatures when pushing images.
--sign-by fingerprint
Sign the pushed image using the GPG key that matches the specified fingerprint.
--tls-verify bool-value
Require HTTPS and verify certificates when talking to container registries (defaults to true)
EXAMPLE This example pushes the image specified by the imageID to a local directory in docker format.
# buildah push imageID dir:/path/to/image
This example pushes the image specified by the imageID to a local directory in oci format.
# buildah push imageID oci:/path/to/layout:image:tag
This example pushes the image specified by the imageID to a tar archive in oci format.
# buildah push imageID oci-archive:/path/to/archive:image:tag
This example pushes the image specified by the imageID to a container registry named registry.example.com.
# buildah push imageID docker://registry.example.com/repository:tag
This example pushes the image specified by the imageID to a container registry named registry.example.com and saves the digest in the specified digestfile.
# buildah push --digestfile=/tmp/mydigest imageID docker://registry.example.com/repository:tag
This example works like docker push, assuming registry.example.com/my_image is a local image.
# buildah push registry.example.com/my_image
This example pushes the image specified by the imageID to a private container registry named registry.example.com with authentication from /tmp/auths/myauths.json.
# buildah push --authfile /tmp/auths/myauths.json imageID docker://registry.example.com/repository:tag
This example pushes the image specified by the imageID and puts into the local docker container store.
# buildah push imageID docker-daemon:image:tag
This example pushes the image specified by the imageID and puts it into the registry on the localhost while turning off tls verification. # buildah push --tls-verify=false imageID docker://localhost:5000/my-imageID
This example pushes the image specified by the imageID and puts it into the registry on the localhost using creden‐ tials and certificates for authentication. # buildah push --cert-dir /auth --tls-verify=true --creds=username:password imageID docker://local‐ host:5000/my-imageID
ENVIRONMENT BUILD_REGISTRY_SOURCES
BUILD_REGISTRY_SOURCES, if set, is treated as a JSON object which contains lists of registry names under the keys insecureRegistries, blockedRegistries, and allowedRegistries.
When pushing an image to a registry, if the portion of the destination image name that corresponds to a registry is compared to the items in the blockedRegistries list, and if it matches any of them, the push attempt is denied. If there are registries in the allowedRegistries list, and the portion of the name that corresponds to the registry is not in the list, the push attempt is denied.
TMPDIR The TMPDIR environment variable allows the user to specify where temporary files are stored while pulling and pushing images. Defaults to '/var/tmp'.
FILES registries.conf (/etc/containers/registries.conf)
registries.conf is the configuration file which specifies which container registries should be consulted when com‐ pleting image names which do not include a registry or domain portion.
policy.json (/etc/containers/policy.json)
Signature policy file. This defines the trust policy for container images. Controls which container registries can be used for image, and whether or not the tool should trust the images.
SEE ALSO buildah(1), buildah-login(1), containers-policy.json(5), docker-login(1), containers-registries.conf(5)
buildah June 2017 buildah-push(1)
$ buildah run \
--entrypoint /var/lang/bin/pip \
--rm \
--user "$(id -u):$(id -g)" \
-v "$(pwd):/mnt" \
amazon/aws-lambda-python:3.8 \
install --target /mnt/build --upgrade psycopg2-binary
How To
The following was inspired by Recap: images and containers from Docker for beginners. The equivalent commands for Docker alternatives are shown.
Check software version
$ docker -v
Docker version 20.10.2, build 20.10.2-0ubuntu1~20.10.1
$ buildah -v
buildah version 1.15.2 (image-spec 1.0.1, runtime-spec 1.0.2-dev)
$ podman -v
podman version 2.0.6
Download the Amazon Linux 2 image
AWS Lambda functions run under Amazon Linux.
Each of these 3 commands does a very similar task, downloading a specific image.
Docker uses different subdirectories for images than Buildah and podman
do.
$ sudo docker pull amazonlinux Using default tag: latest latest: Pulling from library/amazonlinux 3c2c91c7c431: Pull complete Digest: sha256:06b9e2433e4e563e1d75bc8c71d32b76dc49a2841e9253746eefc8ca40b80b5e Status: Downloaded newer image for amazonlinux:latest docker.io/library/amazonlinux:latest
Buildah works without complaint.
$ buildah pull amazonlinux 53ef897d731f9a5673c083d0e86d7911f85d6e63bb2be2346b17bdbacdc58637
podman
seems to hiccup and then complete successfully.
$ podman pull amazonlinux Trying to pull quay.io/amazonlinux... error parsing HTTP 404 response body: invalid character '<' looking for beginning of value: "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 3.2 Final//EN\">\n<title>404 Not Found</title>\n<h1>Not Found</h1>\n<p>The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.</p>\n" Trying to pull docker.io/library/amazonlinux... Getting image source signatures Copying blob 3c2c91c7c431 [--------------------------------------] 0.0b / 0.0b Copying config 53ef897d73 done Writing manifest to image destination Storing signatures 53ef897d731f9a5673c083d0e86d7911f85d6e63bb2be2346b17bdbacdc58637
Run a Bash Command in an OCI Container
Again, Docker
must be run as root for this operation, this represents an unnecessary security risk.
$ sudo docker container run amazonlinux echo 'Hello World!' Hello World!
$ podman container run amazonlinux cat /etc/os-release VERSION="2" ID="amzn" ID_LIKE="centos rhel fedora" VERSION_ID="2" PRETTY_NAME="Amazon Linux 2" ANSI_COLOR="0;33" CPE_NAME="cpe:2.3:o:amazon:amazon_linux:2" HOME_URL="https://amazonlinux.com/"
Show All Locally Available Images
Again, Docker
must be run as root for this operation, this represents an unnecessary security risk.
$ sudo docker images REPOSITORY TAG IMAGE ID CREATED SIZE amazonlinux latest 53ef897d731f 21 hours ago 163MB
$ podman images REPOSITORY TAG IMAGE ID CREATED SIZE localhost/hello latest 40ef32b39cf4 5 hours ago 622 MB docker.io/library/amazonlinux latest 53ef897d731f 21 hours ago 170 MB
List OCI Containers
$ sudo docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
$ podman container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
View All OCI Containers (Running or Not)
$ sudo docker container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 250f56d9aced amazonlinux "echo 'Hello World!'" 14 minutes ago Exited (0) 14 minutes ago competent_einstein
$ podman container ls -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 0f8203e9d3b8 docker.io/library/amazonlinux:latest echo Hello world! 36 minutes ago Exited (0) 36 minutes ago beautiful_mestorf 14282ace8978 docker.io/library/amazonlinux:latest echo Hello world! 36 minutes ago Exited (0) 36 minutes ago beautiful_goldwasser 1b9a8db52fb9 docker.io/library/alpine:latest echo Hello World! About an hour ago Exited (0) About an hour ago zealous_easley 6444ee144488 docker.io/library/amazonlinux:latest echo Hello World! 12 minutes ago Exited (0) 12 minutes ago frosty_ritchie 7444122cbc59 docker.io/library/alpine:latest cat /etc/motd About an hour ago Exited (0) About an hour ago elated_sammet aef84973d6ad docker.io/library/amazonlinux:latest echo Hello world! About an hour ago Exited (0) About an hour ago lucid_sinoussi e210f74bc209 docker.io/library/amazonlinux:latest cat /etc/motd About an hour ago Exited (0) About an hour ago jovial_borg
List Running OCI containers
$ sudo docker container ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 250f56d9aced amazonlinux "echo 'Hello World!'" 5 minutes ago Exited (0) 5 minutes ago competent_einstein
podman
has a problem with the container ps
sub-subcommand.
$ podman container ps -a Error: unrecognized command `podman container ps` Try 'podman container --help' for more information.
buildah push to Docker Daemon
$ buildah push hello:latest docker-daemon:hello:latest Getting image source signatures Copying blob sha256:72fcdba8cff9f105a61370d930d7f184702eeea634ac986da0105d8422a17028 247.02 MiB / 247.02 MiB [==================================================] 2s Copying blob sha256:e567905cf805891b514af250400cc75db3cb47d61219750e0db047c5308bd916 144.75 MiB / 144.75 MiB [==================================================] 1s Copying config sha256:6d54bef73e638f2e2dd8b7bf1c4dfa26e7ed1188f1113ee787893e23151ff3ff 1.59 KiB / 1.59 KiB [======================================================] 0s Writing manifest to image destination Storing signatures
$ buildah images | head -n2 REPOSITORY TAG IMAGE ID CREATED SIZE docker.io/hello latest 6d54bef73e63 2 minutes ago 398 MB
$ buildah run -t hello:latest Hello, world!
Delete an OCI Image
Delete an OCI image in Buildah's ~/.local/share/container
directory with the rmi
subcommand:
$ buildah rmi e12ea62c5582 e12ea62c5582f91a2228e3e284ea957f2df4f1cdb150fd2c189ef8f11d7633ce