ch-build man page

ch-build — Build an image and place it in the builder's back-end storage


$ ch-build [-b BUILDER] [--builder-info] -t TAG [ARGS ...] CONTEXT


Build an image named TAG described by a Dockerfile. Place the result into the builder’s back-end storage.

Using this script is not required for a working Charliecloud image. You can also use any builder that can produce a Linux filesystem tree directly, whether or not it is in the list below. However, this script hides the vagaries of making the supported builders work smoothly with Charliecloud and adds some conveniences (e.g., pass HTTP proxy environment variables to the build environment if the builder doesn’t do this by default).

Supported builders, unprivileged:

Supported builders, privileged:

Specifying the builder, in descending order of priority:

-b, --builder BUILDER

Command line option.


Environment variable


docker if Docker is installed; otherwise, ch-grow.

Other arguments:


Print the builder to be used and its version, then exit.

-f, --file DOCKERFILE

Dockerfile to use (default: $CONTEXT/Dockerfile)

-t TAG

Name (tag) of Docker image to build.


Print help and exit.


Print version and exit.

Additional arguments are accepted and passed unchanged to the underlying builder.


The tag suffix :latest is somewhat misleading, as by default neither ch-build nor bare builders will notice if the base FROM image has been updated. Use --pull to make sure you have the latest base image.


Create an image tagged foo and specified by the file Dockerfile located in the context directory. Use /bar as the Docker context directory. Use the default builder.

$ ch-build -t foo /bar

Equivalent to above:

$ ch-build -t foo --file=/bar/Dockerfile /bar

Instead, use /bar/Dockerfile.baz:

$ ch-build -t foo --file=/bar/Dockerfile.baz /bar

Equivalent to the first example, but use ch-grow even if Docker is installed:

$ ch-build -b ch-grow -t foo /bar

Equivalent to above:

$ export CH_BUILDER=ch-grow
$ ch-build -t foo /bar

Reporting Bugs

If Charliecloud was obtained from your Linux distribution, use your distribution’s bug reporting procedures.

Otherwise, report bugs to: <>

See Also


Full documentation at: <>

Docker Tips

Docker is a convenient way to build Charliecloud images. While installing Docker is beyond the scope of this documentation, here are a few tips.

Understand the security implications of Docker

Because Docker (a) makes installing random crap from the internet really easy and (b) is easy to deploy insecurely, you should take care. Some of the implications are below. This list should not be considered comprehensive nor a substitute for appropriate expertise; adhere to your moral and institutional responsibilities.

docker equals root

Anyone who can run the docker command or interact with the Docker daemon can trivially escalate to root. This is considered a feature.

For this reason, don’t create the docker group, as this will allow passwordless, unlogged escalation for anyone in the group.

Images can contain bad stuff

Standard hygiene for “installing stuff from the internet” applies. Only work with images you trust. The official Docker Hub repositories can help.

Containers run as root

By default, Docker runs container processes as root. In addition to being poor hygiene, this can be an escalation path, e.g. if you bind-mount host directories.

Docker alters your network configuration

To see what it did:

$ ifconfig    # note docker0 interface
$ brctl show  # note docker0 bridge
$ route -n

Docker installs services

If you don’t want the service starting automatically at boot, e.g.:

$ systemctl is-enabled docker
$ systemctl disable docker
$ systemctl is-enabled docker

Configuring for a proxy

By default, Docker does not work if you have a proxy, and it fails in two different ways.

The first problem is that Docker itself must be told to use a proxy. This manifests as:

$ sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
Pulling repository hello-world
Get dial tcp connection refused

If you have a systemd system, the Docker documentation explains how to configure this. If you don’t have a systemd system, then /etc/default/docker might be the place to go?

The second problem is that Docker containers need to know about the proxy as well. This manifests as images failing to build because they can’t download stuff from the internet.

The fix is to set the proxy variables in your environment, e.g.:

export HTTP_PROXY=
export http_proxy=$HTTP_PROXY
export https_proxy=$HTTP_PROXY
export all_proxy=$HTTP_PROXY
export NO_PROXY='localhost,,'
export no_proxy=$NO_PROXY

You also need to teach sudo to retain them. Add the following to /etc/sudoers:

Defaults env_keep+="HTTP_PROXY http_proxy HTTPS_PROXY https_proxy ALL_PROXY all_proxy NO_PROXY no_proxy"

Because different programs use different subsets of these variables, and to avoid a situation where some things work and others don’t, the Charliecloud test suite (see below) includes a test that fails if some but not all of the above variables are set.

Referenced By

charliecloud(1), ch-builder2tar(1).

2020-01-28 00:00 Coordinated Universal Time Charliecloud