Skip to content

Using Docker CLI

Installation

Install the Docker Engine for Linux (Ubuntu) here.

To run Docker as a non-root user

  1. Create the docker group: sudo groupadd docker
  2. Add your user to the group: sudo usermod -aG docker $USER
  3. Logout and back in.

Docker allows the code you write to be run anywhere. While learning Docker isn't always straightforward, it is a crucial technology for modern software development and it worthwhile to learn.

Docker works by using Docker images. These images contain information about the filesystem, code, and dependencies needed to run a program. Images are run in instances called containers, which share the underlying operating system but otherwise entirely isolates the user space (or environment) the code is executed in.

What is a Container?

A container is a running process with a dedicated subset of computer resources that are allocated specifically to that process.

Basics

To build a docker image you need a Dockerfile, this is like a recipe that outlines the steps that are executed to setup the docker image. There are many examples of Dockerfiles online that can be used as templates for a specific project.

To build an image, use the command:

sh
docker build .
# OR a bit more advanced
docker build --tag <name_of_image>:<version> --file foo/Dockerfile .
docker build .
# OR a bit more advanced
docker build --tag <name_of_image>:<version> --file foo/Dockerfile .

In the above command, the -t argument specifies the tag/name that is given to this image. This argument can be omitted, but it is recommended since it provides information about images on your machine when you run docker images.

Additionally, if you run this command in the folder with the target Dockerfile, the --file Dockerfile argument is unnecessary, but this allows for Dockerfiles to be located in different places and with different names.

Finally, the . at the end of the command defines the build context, any parent directory of the build context won't be accessible inside the Docker image.

To run the docker image after it's been built, use command:

sh
docker run -v $(pwd):/foo -it <name_of_image>:<version>
docker run -v $(pwd):/foo -it <name_of_image>:<version>

This will run the docker image in an interactive session and mount the current directory ($(pwd)) to the folder /foo in the container (see How to Mount a Local Directory).

How Does this Work? To begin, Docker checks your filesystem for the specified image (e.g. ubuntu:22.04 may be used in place of <name_of_image> in the above command to run a pre-built Docker image). If the image isn't found locally it checks Docker Hub, a Docker Registry that contains publicly available images. Private registries can also be set up to use private Docker images (see How to Set Up a Private Docker Registry).

Tip

Every time you use the docker run command you're creating a new container. This takes up disk space. You can remove containers with docker rm <ID> or autoremove when the container is exited by adding --rm to the docker run command.

Important Commands

docker build

Build your docker container --no-cache progress=plain .: Show progress without cache, good for debugging -t/--tag <docker-id>/<image-name>:<version>: Tag your docker image so you can refer to it via its tag

docker push

Push the container into your docker registry

docker start -a <id>

Start one or more stopped containers

sh
docker start -a 37a8c  # Use `-a` to attach the container to stdin/stdout
docker start -a 37a8c  # Use `-a` to attach the container to stdin/stdout

-ia: Attach container in an interactive session

docker stop <id> or docker kill <id>

Stop sends SIGTERM, allows for a little bit of clean up. Kill sends SIGKILL, stop immediately.

shell
docker kill nanomq
docker stop nanomq
docker kill nanomq
docker stop nanomq

docker ps

List running containers -a/--all: Show all containers

docker network ls

List all networks created by docker.

docker images or docker image ls

List images -a/--all: List all images

docker logs <id>

docker run

Convenience command for creating and then starting a container -it: Attach to stdin & stdout of the container's prompt --name <name>: Give the container a name for easier reference --rm: Clean up the container after it exits (this is very useful) -d/--detach: Run docker container in background -v/--volume X:/Y/Z: Mount a volume from directory X on the host to directory /Y/Z in the container -p/--publish X:Y: Map port X on the host to port Y in the container --network=host: Uses the host's network (127.0.0.1) for the container

Overriding default command.

sh
docker run <image> <override-command>
# e.g. open a shell in the container, regardless of the default CMD
docker run -it <image> bash
# e.g.
docker run busybox echo hi there
> hi there
docker run <image> <override-command>
# e.g. open a shell in the container, regardless of the default CMD
docker run -it <image> bash
# e.g.
docker run busybox echo hi there
> hi there

Run vs. create and start

sh
docker run hello-world
# same as
docker create hello-world
> a9dsmd...
docker start -a a9dsmd
docker run hello-world
# same as
docker create hello-world
> a9dsmd...
docker start -a a9dsmd

docker exec

Execute a command in a currently running container.

sh
docker run --name abc redis
docker exec -it abc redis-cli # Add `-it` if you want to bind to the shell
docker run --name abc redis
docker exec -it abc redis-cli # Add `-it` if you want to bind to the shell

Tips 'n Tricks

Attach to a terminal in a running container

docker exec -it <container-id/name> [bash/zsh/sh]
docker exec -it <container-id/name> [bash/zsh/sh]

Creating an Running a web app

Recall, Docker containers are isolated from the underlying OS, this includes network ports. To forward a port from the container to the underlying OS, use the -p option. For example,

sh
docker run -p 8080:9090 <name_of_image>
docker run -p 8080:9090 <name_of_image>

exposes port 8080 in the Docker container on port 9090 on the host OS.

Removing images, containers, volumes

  • Always remove your containers before removing the associated image or volumes.
sh
docker container ls
docker rm <container tag or id>

docker image ls
docker rmi <image tag or id>

docker volume ls
docker volume rm <volume tag or id>
docker volume prune # This can free up lots of disk space

docker system prune # Remove all docker artifacts including containers, images, etc.
docker container ls
docker rm <container tag or id>

docker image ls
docker rmi <image tag or id>

docker volume ls
docker volume rm <volume tag or id>
docker volume prune # This can free up lots of disk space

docker system prune # Remove all docker artifacts including containers, images, etc.

Logging in to docker registry

Reference the docker login command here

sh
# Option 1
docker login <registry> -p <password> -u <username>
# Option 2 (recommended)
echo $DOCKER_PASSWD | docker login <registry> -u <username> --password-stdin
# Option 1
docker login <registry> -p <password> -u <username>
# Option 2 (recommended)
echo $DOCKER_PASSWD | docker login <registry> -u <username> --password-stdin

Pushing to docker registry

Reference this article for how to build and push Docker images to a registry in CI

sh
# Only available once logged in to the registry
# Ensure you have a build image with the correct tag name
docker build --tag registry.example.com/group/image:version .
docker push registry.example.com/group/image:version
# Only available once logged in to the registry
# Ensure you have a build image with the correct tag name
docker build --tag registry.example.com/group/image:version .
docker push registry.example.com/group/image:version

Remove all docker containers or images

sh
docker container rm -f $(docker container ls -aq)
docker image rm $(docker image ls -aq)
docker container rm -f $(docker container ls -aq)
docker image rm $(docker image ls -aq)

Troubleshooting

If you receive and error like

Error response from daemon: Get "https://registry-1.docker.io/v2/": Get "https://auth.docker.io/token? <REDACTED> : net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)
Error response from daemon: Get "https://registry-1.docker.io/v2/": Get "https://auth.docker.io/token? <REDACTED> : net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers)

Trying issuing

docker login
docker login

If this doesn't work, try restarting the docker daemons

systemctl restart docker
systemctl restart containerd
systemctl restart docker
systemctl restart containerd
ESSENTIAL RESOURCES
ADDITIONAL RESOURCES

Understanding Docker Networking