Docker run -it & Other Command Line Tips for Beginners

While I often utilize Docker as part of a hosting and deployment system, I also use it locally for all sorts of exploration, spikes, and development. There are a couple of especially useful patterns and invocations that I show to people when I am introducing them to Docker and its usage.

The following tips are not comprehensive, but they do cover some of the most common operations that beginning users are likely to need when first working with containers. All of the following tips work with the standard Docker CLI from version 18.06.0-ce. I’ve organized them by sub-commands to the main docker executable.

Docker Build

Docker build creates Docker images from Dockerfiles.

The anatomy of a Dockerfile is beyond the scope of this post, but looking at examples from official repositories on Docker Hub and the Docker documentation can be helpful.

You can easily build a new image from a Dockerfile and tag it with:

docker build PATH -f FILE -t NAME:TAG


docker build . -f docker/Dockefile -t my-rails-app:latest

 

The -f specifies the path to the actual Dockerfile, whereas the PATH (. in the example) tells Docker what to use for its context or current directory when building the image. (This is important when considering commands specifying files and paths within the Dockerfile.)

The -t will tag the image built by Docker.

All Docker images have an image identifier (a generated, 12-character alphanumeric string). They may also be given a name and a tag. If only a name is provided, the default tag of “latest” is used. Image names and tags help tremendously to readily (and unambiguously) reference specific images.

Docker Run

Docker run is for creating containers. It is important to differentiate it from exec, which is used to interact with containers that are already running.

Sometimes, it’s useful to just start a container to poke around, and then discard it afterwards. The following will start a new container, drop into a shell, and then destroy the container after you exit:

docker run -it --rm IMAGE COMMAND


docker run -it --rm ruby:latest bash

The -it runs Docker interactively (so you get a pseudo-TTY with STDIN). The --rm causes Docker to automatically remove the container when it exits.

The image being used to create the container is generally specified as : such as ruby:latest. If the specified image is not available locally, Docker will attempt to retrieve it from Docker Hub (or any connected Docker registry).

If you need to find Docker images available locally, you can run: docker images or docker image ls.

The following will start a container with specified environment variables and forwarding ports from your local computer into the Docker container:

docker run -p HOST_PORT:CONTAINER_PORT -e ENV_VAR=VALUE IMAGE COMMAND


docker run -p 8080:3000 -e RACK_ENV=development my-rails-app:latest rails s

The -p defines the port mapping from the host to the container, and the -e defines key value pairs to set in the container’s environment when it starts up. Multiple parameters can be provided:


docker run -it -—rm -p 8080:3000 -p 8081:3001 -e RACK_ENV=development -e HOSTNAME=my-container my-rails-app:latest rackup

Docker Exec

As mentioned earlier, Docker exec only interacts with containers that are actively running.

If there is an existing container that was started headless (such as by docker-compose), you can easily drop into a shell to check on the state of things:

docker exec -it CONTAINER COMMAND


docker exec -it 90cdc54358fa bash

As in the earlier example, the -it allows an interactive session. The container to run exec can either be specified by the container ID or the more friendly name that is generated or specified when the container is created.

If you do not know the name of the container, you can easily find it with: docker ps or docker container ls.

Docker Image/Container

The main resources used for local containers are images, containers, and volumes. Containers are the basic unit of execution. Images are the basis for containers, and volumes are mounted by containers.

Docker has sub-commands which allow you to examine and interact with these resources. While there are many dozens of sub-commands (and sub-sub commands), I find that these are the ones I use most frequently:

docker container allows you to manage containers, for example:

  • docker container ls to list all running containers
  • docker container kill CONTAINER to forcefully stop a running container
  • docker container rm CONTAINER to remove a container
  • docker inspect CONTAINER to view detailed information about a running container

docker images allows you to manage images, for example:

  • docker image ls to list all locally available images
  • docker image rm IMAGE to remove an image
  • docker image prune to remove dangling images (those not attached to a container, or a dependency for an image that is)
  • docker image prune -a to remove all images
  • docker image tag IMAGE IMAGE to tag an image from one image id or tag, to a new tag. (e.g. my-app:latest to my-app:1.0.0)

I hope this post will encourage you to experiment with Docker.