Building and Running Containers

Summary of Best Practices

The primary best practice in this article is pretty subtle but very important. As you read through best practices to build and run images and containers, you should design the container for the use cases and any goals you have in mind: Will the container be interactive? Will it run without a user logging in to it? Who will use the container? To keep all of the design goals in mind, you can create a simple text file that describes the goals and use cases for the container. Perhaps you could even copy the text file into the final version of the container.

Although this article is a bit long, it mentions some important best practices:

(1) Use a good name:tag combination for all Docker images you build.

  • Don’t make it impossibly long.
  • Don’t make it cryptic so no one else understands it
  • If you add special characters or phrases indicating the image has been “certified” in some fashion, be sure to tell the users.
  • Don’t make it too short. People won’t understand it.
  • I personally like adding dates and creator initials, but not everyone does.

(2) Singularity doesn’t have the concept of an image name:tag. Unlike Docker, the container is just a file, so you can name it whatever you want, as long as it’s a legal file name. For Singularity, just be sure to use a good file name that has some evidence of when and who built the container, as well as some information about the container, and you might want to indicate that the image is encrypted. (Yes, the file name will be long.) You could even mimic the Docker name:tag combination, but without the semicolon.

(3) Use bind mounts for both Docker and Singularity! As mentioned in the first article, keeping all application data outside the container and on the host file system is highly recommended.

  • For Docker, use the -v option to mount the file or directory in the container (e.g., -v /data/testcase1:/data). Note that Docker is slowly moving to the --mount option, but be assured they are going to support -v for a long time, because there are too many docker run commands floating around to just kill -v in a new version of Docker.
  • For Singularity, use the --bind option (e.g., --bind /data/testcase1:data:rw).
  • Both Docker and Singularity have options for mounting the file or directory in the container.

(4) Even though the --squash Docker option is still marked experimental, it has been around for years. I use it all the time; however, if it worries you, feel free not to use it.

(5) For Singularity, always encrypt your containers with the --encrypt command-line option and either a passphrase or PEM key; however, encrypt them, especially if you intend to share your container with others.

(6) For Docker, always set the UID:GID inside the container to be the same as outside the container. The run-time option is -u $(id -u):$(id -g).

(7) If you use environment variables with Docker, you are put into your /home directory when running the container, and you are the same $USER as outside the container (-e HOME=$HOME -e USER=$USER). Note that you need to mount your /home directory into the container.

(8) For Singularity, always use the --fakeroot option to build and run the container. If you are going to run a Docker image with Singularity, you can still use --fakeroot.

(9) For Singularity, remember that if the container isn’t run interactively, it will run the script in the %runscript section.

(10) If you are going to run a Docker container with Singularity and run it non-interactively, Singularity will run the script in the Docker container’s ENTRYPOINT. Be sure you have a script in that section of the container. (Docker does not have a %runscipt section.)

(11) For Docker, always assign a process name to the running container that is different from the container name, so you know exactly which container you are running.

Please take these practices into account as you create images and run containers.