Handy Docker Things

When working with docker, especially with building images there’s a few handy things to note. This is not so much of a tutorial but more of a place to keep up with some handy notes and tips

Ubuntu Best Practices

Clearing apt cache

When building an image and using Ubuntu as a base image, generally, there’s no need to keep the apt cache around after installing whatever it is that’s needed for the service. This is a method to update the cache, install packages, and then delete the cache. This is considered a “best practice” rather than using apt autoremove. See Docker Image Guidelines

1
2
3
4
5
FROM ubuntu:latest

RUN apt-get update \
    && apt-get install -y smokeping dnsutils \
    && rm -rf /var/lib/apt/lists/*

Do not install extra packages

Usually there’s no need to install the ‘suggets’ or ‘recommended’ packages if the install is in a container. Configure apt to not include those

1
2
3
4
5
RUN echo 'APT::Install-Suggests "0";' >> /etc/apt/apt.conf.d/00-docker
RUN echo 'APT::Install-Recommends "0";' >> /etc/apt/apt.conf.d/00-docker
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y smokeping dnsutils \
    && rm -rf /var/lib/apt/lists/*

Set apt to work non-interactively

Some packages will prompt the user for input upon installation, setting the noninteractive env var will suppress these

1
2
3
RUN DEBIAN_FRONTEND=noninteractive apt-get update \
    && DEBIAN_FRONTEND=noninteractive apt-get install -y smokeping dnsutils \
    && rm -rf /var/lib/apt/lists/*

Keeping a container running without a daemon

Sometime a container only has tools to be used as one-shot commands or for testing purposes you need a container to run without firing up a long running daemon. There’s a couple of acceptable way to keep the container running in these situations.

tail -f /dev/null

This will effectively run forever without actually doing anything

1
2
3
4
5
FROM ubuntu:latest

...

ENTRYPOINT ["tail", "-f", "/dev/null"]

sleep forever

Another method is to call sleep and tell it to run forever. The downside to this method is not all implementations of sleep support the infinity argument. So…your mileage may vary

1
2
3
4
5
FROM ubuntu:latest

...

ENTRYPOINT ["sleep", "infinity"]

Setting environment variables on the command line while chaining command with &&

Sometimes you might want RUN a command and provide some setting or flag via environment variables. Let’s say you want to tell apt to not prompt the user for any input, due to this not being a tty, only a script. Usually you could do something like:

1
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install -y smokeping

The issue here is the env var DEBIAN_FRONTEND will only exist for the apt-get update, it will be cleared when the apt-get install ... runs. There’s a couple of ways to get around this.

Either set the env var for each command to run:

1
RUN DEBIAN_FRONTEND=noninteractive apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y smokeping

or set it all to run as a shell script:

1
RUN env Hello=123 sh -c 'npm run a && npm run b && npm run c'

This will set the env var and then execute all the commands under a single shell thus inheriting the env var for all commands.