DEV Community

Cover image for Docker knowledge to get you through the day
Ben Selby
Ben Selby

Posted on • Originally published at benmatselby.dev

Docker knowledge to get you through the day

Following on from the "Git commands to get you through the day" post, Paddy Morgan and I delivered a Docker 101 workshop today at work.

This post covers what we ran through.


Time allocation: 60 minutes

This workshop will be a high level overview of the basic docker commands you will use daily. It's an entry level workshop, so if you're comfortable with docker on the CLI, this probably isn't for you.

What we will cover:

Some up front terminology

  • Image - A definition of an environment.
  • Container - A virtualised run time environment of a docker image.

Commands

We need to make sure we have docker installed, so let's run that first.

docker

If Docker is installed, this will output a raft of commands that we can make use of. If you haven't got Docker, checkout the installation page.

You may notice that some of the commands are the same, e.g.

  • docker images
  • docker image ls

Take some time to review the output from the main docker command.

Pulling

Let's start with understanding what images we have on our machine.

docker images

This shows us all the images that are pre-built and stored on your machine. Any images listed here are available to be run locally. If you have not used Docker before, the list is likely to be empty.

Let's pull down the hello-world image.

docker pull hello-world

If you now run docker images you should see something very similar to this:

❯ docker images
REPOSITORY      TAG       IMAGE ID       CREATED        SIZE
hello-world     latest    d1165f221234   7 days ago     13.3kB
Enter fullscreen mode Exit fullscreen mode

Running basic commands

Let's now run that image as a container.

docker run hello-world

So docker is the main command. run is the subcommand which allows us to run the hello-world image as a container.

If we now run docker ps -a you will see containers that are: running, have ran and stopped.

❯ docker ps -a
CONTAINER ID   IMAGE         COMMAND    CREATED              STATUS                          PORTS     NAMES
1fd4a9f1b80b   hello-world   "/hello"   About a minute ago   Exited (0) About a minute ago             practical_blackwell
Enter fullscreen mode Exit fullscreen mode

Ideally, we want to clean-up after ourselves. So lets run the container again.

docker run --rm hello-world

Notice the --rm flag, which will remove the container once execution has finished.

If we run docker ps -a again you will notice there isn't a new entry in the list.

Defining

Let's cover two scenarios

  1. An environment you want to work in.
  2. Shipping something.

Environment

Let's look at a VS Code Dev Environment.

Key items to cover off are:

  • FROM - The base image is golang:1.
    • This in turn will have a base image, so essentially these can be chained.
    • Some base images will be low level linux distructions like Ubuntu, or Alpine.
    • Some base images will provide extra capabilities on top of the OS, like golang.
  • ENV - Environment variables for the image.
  • ARG - Arguments that can be overridden when building the image.
  • COPY - The ability to copy files from the host into the image (These will persist in the image).
    • The host file is on the left, whilst the image location is on the right hand side of the declaration.
  • RUN - Running commands to build the image.
    • You can see that commands are grouped together as one RUN command.
    • This is to keep those defined as a "layer".

Shipping something

Let's look at Hagen which is a CLI tool for getting some data out of GitHub. This is running a Go binary inside the container.

Key items to cover off are:

  • alpine - Base images are generally linux based.
    • Alpine is a very small linux distribution.
    • If you can use it, it will keep your images small (which ultimately saves time and money).
    • Alpine, by default, uses apk not apt to install packages, this may catch people out to start with.
  • FROM scratch - Start with a bare bones container, nothing in there.
  • ENTRYPOINT - This defines what should be executed when the image is instantiated as a container.
    • Here you can see we are running the hagen command, which has been placed in /usr/bin/.
  • CMD - Here we using CMD to pass --help to hagen.
    • So if you do not pass any other arguments into the container when running it, it will provide you will a help menu.

Building

Let's look at the Hagen example again.

docker build -t benmatselby/hagen .
Enter fullscreen mode Exit fullscreen mode

Breaking this down we have docker build as the command.

-t defines the string we will tag the image with. You can specify multiple tags, and they will all show when you run docker images.

And finally the . provides the context to the build command.

Running more advanced commands

For a more in-depth review of what you can do whilst running containers, please see the documentation.

An example of sharing environment variables, and files from the host to the container.

docker run \
  --rm \
  -t \
  -eGITHUB_OWNER \
  -eGITHUB_ORG \
  -eGITHUB_TOKEN \
  -v "${HOME}/.benmatselby":/root/.benmatselby \
  benmatselby/hagen
Enter fullscreen mode Exit fullscreen mode

Breaking this down.

  • --rm will remove the container from the system once finished execution.
  • -t allocates a tty. See this.
  • -e provides environment variables to the container.
    • If the names match you can do it this way.
    • If not you can provide them in the -e foo=bar format.
  • -v defines a volume, which is essentially a file share between the host and the container.
    • The format is host:container.
    • This allows us to share the configuration used for hagen, with the container.

What if you want to get your terminal back, and run the container unsupervised? Then you can do this

$ docker run \
  --rm \
  -p 8080:80 \
  -v "$(pwd):/usr/share/nginx/html" \
  -d \
  nginx
dcc55061e1118f7b6ccf2c3708d717531bf0c92327ed42f94f08d13020e901ea
$ curl http://localhost:8080/
Enter fullscreen mode Exit fullscreen mode

The extra bits here are:

  • -p 8080:80 links the host port (8080) to the container port (80) that has been exposed.
  • -d will disconnect the container from your terminal, and then output the container id back to you.
  • You can see after the docker run command, a unique ID presented back to you. This is the running container process ID.
  • The example above then hits nginx and tries to retrieve some HTML. If your pwd (current working directory) does not have any HTML, this will give a 404.

Process management

Want to know what processes are running?

docker ps will give the current containers running.

docker ps -a will give you all the containers that are running and stopped.

Want to connect to a container that is running, then you can do this:

docker exec -it dcc55061e1118f7b6ccf2c3708d717531bf0c92327ed42f94f08d13020e901ea bash
Enter fullscreen mode Exit fullscreen mode

Breaking this down, we have docker exec for executing something, but we run interactively with -it options and then run bash. This could be zsh or actually any command that is available in the container. Notice we are using the same container from the nginx example.

Want to know more about a running container, then run

docker inspect dcc55061e1118f7b6ccf2c3708d717531bf0c92327ed42f94f08d13020e901ea
Enter fullscreen mode Exit fullscreen mode

To stop a container you can run

docker stop dcc55061e1118f7b6ccf2c3708d717531bf0c92327ed42f94f08d13020e901ea
Enter fullscreen mode Exit fullscreen mode

Clean-up

These commands will help keep your machine tidy:

  • docker rm $(docker ps -aq) - Remove all containers.
  • docker rmi $(docker images -q) - Remove all images stored locally.
  • docker rmi $(docker images -f "dangling=true" -q) - Remove all images that are not being used - "dangling".
  • docker stop $(docker ps -aq) - Stop all containers running.

Or

docker system prune

Tidbits

Top comments (0)