How to initialize a Docker container without building an image

2020 February 10

Recently, I was debugging a Travis build issue, and I wanted to shorten the iteration time. The best way I could imagine was to create a container with a copy of the Travis environment and run a shell in it.

I started with a base image and wrote an initialization script. The conventional pattern is to create a Dockerfile that copies the script into the container and executes it:

FROM image:tag
WORKDIR /tmp
COPY prepare.sh .
RUN ./prepare.sh && rm prepare.sh

Since I would need to iterate on the initialization script until I got it right, I thought for a second if there was a way I could run a script at the start of a container, without writing a Dockerfile or running more than one command (i.e. no build step before the run step). Here's what I came up with:

  1. Start a container from the base image.
  2. Mount the local directory as a volume in the container.
  3. Execute the initialization script as the ENTRYPOINT of the container.

In one short command, it looks like this:

sudo docker run --rm -it "-v$PWD:/ep" --entrypoint /ep/entrypoint.sh image:tag

We can abstract this pattern into a shell function:

# dbr = docker-build-run
dbr() {
image="${1:-ubuntu:xenial}"
script="${2:-entrypoint.sh}"
sudo docker run --rm --interactive --tty --volume "$PWD:/entrypoint" \
--entrypoint "/entrypoint/${script}" "${image}"
}

# dbr
# dbr image:tag
# dbr image:tag prepare.sh