Challenge, Medium,  on  Containers

Write a Dockerfile for a Containerized CLI Tool

In this challenge, you will write a Dockerfile for a small internal command-line tool. The key learning objective is to explore how the right use of the ENTRYPOINT instruction can improve the UX of containerized CLI applications.

Explore the tool

The tool you need to package is located in the ~/corpctl/ directory. It's a made-up internal operations utility called corpctl - think of it as the kind of helper CLI a company might use to access internal services (most companies have such tools).

Take a moment to explore the project:

cd ~/corpctl
cat main.go

Before containerizing corpctl, try building and running it locally:

go build -o corpctl .
./corpctl --help

The task

Your goal is to create a Dockerfile in the ~/corpctl/ directory and build a Docker image named corpctl.

The image should behave like a proper CLI tool when run with Docker. In particular, the following commands should work naturally:

docker run corpctl --help
docker run corpctl --version
docker run corpctl status payments-api
docker run corpctl report platform-health

Notice the desired user experience: after the image name, only the CLI arguments are passed. The user should not need to know where the executable is located inside the image, nor re-type the corpctl command on every docker run invocation.

Dockerizing Go applications

For a refresher on how to Dockerize a Go application, check out this challenge:

Build and Compile Applications in Dockerfiles

ENTRYPOINT vs CMD

A Dockerfile can use two instructions for defining what runs when a container starts:

  • CMD sets a default command that is entirely replaced when arguments are passed to docker run.
  • ENTRYPOINT sets a command that is prepended to the CMD or the docker run arguments.

If not specified, the ENTRYPOINT defaults to a shell, but for a CLI tool where users need to pass different subcommands and flags, setting the ENTRYPOINT to the CLI binary is usually a better choice.

Debugging hint

If the check doesn't pass, try running the container manually:

docker run corpctl

Does it show the help text? Now try running a subcommand:

docker run corpctl status payments-api

If this doesn't show the status message, the arguments are not being passed to corpctl correctly. Review how CMD and ENTRYPOINT differ in handling docker run arguments and try solving these docker run challenges to internalize the knowledge: