Skip to content

Instantly share code, notes, and snippets.

@cjus
Last active October 31, 2017 05:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save cjus/3db5a91e5e8aab776555089bc15f19a1 to your computer and use it in GitHub Desktop.
Save cjus/3db5a91e5e8aab776555089bc15f19a1 to your computer and use it in GitHub Desktop.

Notes while learning Docker

These notes are derived from my efforts in working through The Docker Book: Containerization is the new virtualization written by James Turnbull. I highly recommend getting a copy of Jame's book which is an $8 dollar e-book on Amazon.

The following notes are my own and simply an interpretation of what James has written. Caveat lector.

Ensuring Docker is ready

$ docker info

Creating and running your first container

$ docker run -i -t ubuntu /bin/bash
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
6d28225f8d96: Pull complete
166102ec41af: Pull complete
d09bfba2bd6a: Pull complete
c80dad39a6c0: Pull complete
a3ed95caeb02: Pull complete
Digest: sha256:5718d664299eb1db14d87db7bfa6945b28879a67b74f36da3e34f5914866b71c
Status: Downloaded newer image for ubuntu:latest
root@0b601c41918b:/#

The -i flag keeps STDIN open for input. The -t flag is used to assign a pseudo-tty to the container for output. We tell docker to create a container using the ubuntu base image and then to execute the /bin/bash shell on startup.

The resulting container is a very basic one which has only the minimum it needs to start. For example, even vi isn't installed:

root@0b601c41918b:/# vi test
bash: vi: command not found
root@0b601c41918b:/#

If we want it, we'd have to install it.

$ root@0b601c41918b:/# apt-get update -y && apt-get install vim -y

Once installed we can launch vi.

To exit the container just type exit:

root@0b601c41918b:/# exit
exit

Displaying containers

You can view a list of running containers using the docker ps command.

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

To view a list of all containers, even those which aren't currently running you need to use the -a flag.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                          PORTS               NAMES
0b601c41918b        ubuntu              "/bin/bash"         7 hours ago         Exited (0) About a minute ago                       desperate_tesla
720d54b22037        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                             focused_brattain
8663f0b5a6f5        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                             small_golick

The -l flag displays the last container which was run.

$ docker ps -l
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                     PORTS               NAMES
0b601c41918b        ubuntu              "/bin/bash"         7 hours ago         Exited (0) 7 minutes ago                       desperate_tesla

Working with container names

When docker launches a container it automatically assigns a random container name. In our last example we saw the name desperate_tesla.

We can specify our own name when launching a container by using the --name flag.

$ docker run --name my_container -i -t ubuntu /bin/bash
root@9b1040108a63:/#

If we exit and run the ps command we'll see:

docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
9b1040108a63        ubuntu              "/bin/bash"         57 seconds ago      Exited (0) 35 seconds ago                       my_container
0b601c41918b        ubuntu              "/bin/bash"         7 hours ago         Exited (0) 13 minutes ago                       desperate_tesla
720d54b22037        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                         focused_brattain
8663f0b5a6f5        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                         small_golick

We now have an additional stopped container with the name my_container.

Restarting stopped containers

We can restart our stopped container my_container:

$ docker start my_container
my_container

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
9b1040108a63        ubuntu              "/bin/bash"         5 minutes ago       Up 23 seconds                           my_container

Notice that we didn't get an interactive prompt. Instead the container is simply running in the background.

The container did start with the same options we entered earlier and we can use the attach command to connect to the running container:

$ docker attach my_container

You might need to press the enter key to see the container prompt, after you enter the attach command.

Typing exit will exit the container and stop it.

However, after started the container and before we attached to it, we could have simply stopped the container using the stop command.

$ docker stop my_container
my_container

Again, to view all containers, both running and stopped you can use the ps command with the -a flag.

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
9b1040108a63        ubuntu              "/bin/bash"         16 minutes ago      Exited (0) 40 seconds ago                       my_container
0b601c41918b        ubuntu              "/bin/bash"         8 hours ago         Exited (0) 29 minutes ago                       desperate_tesla
720d54b22037        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                         focused_brattain
8663f0b5a6f5        hello-world         "/hello"            17 hours ago        Exited (0) 17 hours ago                         small_golick

Daemonized containers

In our earlier examples we worked with a container with an interactive shell. Docker allows us to launch containers which run in the background without exposing an interactive shell.

Most of the containers you'll build and run will be launched as daemonized containers. This includes application servers and services.

Let's look at an example which used the -d and -c flags:

$ docker run --name my_daemon -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1; done"

634d2bcff42fa346a67df89c433d637c944a49d318341231c6a19496e78a856a

So we started a container with the name my_daemon and set it to be a daemon using the -d flag, and then we use the -c command flag to specify a simple shell script.

The actual script is entered as a single line but is essential the same as this:

while true;
  do echo hello world;
  sleep 1;
done

So as we can see, it's just a loop which prints hello world to the console and sleeps for one second before resuming.

We can use the ps command to see our daemon running:

docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                      PORTS               NAMES
634d2bcff42f        ubuntu              "/bin/sh -c 'while tr"   4 minutes ago       Up 4 minutes                                    my_daemon
:
:

But note that we have a daemon container running in the background, so how do we actually see what it's dong?

We can use the logs command:

$ docker logs my_daemon
hello world
hello world
hello world
:
:

Note, you'll need to use CTRL-C to exist the log display, since the container keeps generating output.

The output is a lot easier to read if you use the -ft flags:

$docker logs -ft my_daemon
2016-05-24T12:16:08.666373871Z hello world
2016-05-24T12:16:09.651019841Z hello world
2016-05-24T12:16:10.652780439Z hello world

Then every second you'll see another hello world message with a new timestamp.

Another way of seeing what's going on inside of a daemonized container is to use the top command:

$ docker top my_daemon
PID                 USER                TIME                COMMAND
11381               root                0:00                /bin/sh -c while true; do echo hello world; sleep 1; done
12200               root                0:00                sleep 1

We can also run another process inside of our daemonized container. In this example we'll use the exec command to execute a touch /etc/new_config_file command to create a new file.

$ docker exec -d my_daemon touch /etc/new_config_file

To view the results of our last command we can enter our daemonized container and see whether the new file new_config_file actually exists.

We'll use the exec command again but this time to create an interactive shell inside of our container.

$ docker exec -t -i my_daemon /bin/bash
root@634d2bcff42f:/# ls -l /etc/new_config_file

It worked, indeed! However, you may be wondering why we didn't simply attach to our daemon using the attach command we used earlier? The reason is because we would have attached to the running process which is running our hello world loop.

docker attach my_daemon
hello world
hello world
hello world
hello world
hello world
hello world
^C

Then issuing CTRL-C above would have killed our background daemon:

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
634d2bcff42f        ubuntu              "/bin/sh -c 'while tr"   27 minutes ago      Exited (0) 5 seconds ago                           my_daemon

By issuing a docker exec command to open an interactive shell we were able to search for our newly created file without disturbing the hello world process.

Ok, and finally. To stop a running daemon we simply issue the stop command.

If you were following along and tried the attach command above to see what would happen then you've stopped your my_daemon container. You can start it now using docker start my_daemon my_daemon

$ docker stop my_daemon

Deleting a container

You can delete any containers you don't need using:

$ docker rm my_daemon
my_daemon

Don't forget you can use the docker ps -a command to view all of your containers, both running and stopped. Then simply use the delete command to remove containers you no longer need.

Building your own container

In an earlier example we added vi to our container. If we used docker commit we could have saved the container with the installation of vi. To building your own container can be as easy as creating a base container and installing the modules your application requires. Then committing your changes.

However, there's a better way of building containers which has a host of benefits. You can create a Dockerfile which is really just a text file with setup instructions docker will use to construct a container.

Here's a Dockerfile I wrote to define a container with NodeJS 6.3 and Git installed.

FROM node:6.3
EXPOSE 5000

To build the actual container you just use the build command:

$ docker build -t node:6.3 .

We can use the docker images command to display the newly created container image:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
node                6.3                 e79fe5711c94        13 days ago         660.7 MB

To run the container we reference the image node:6.3:

$ docker run -it node:6.3 /bin/bash
root@765b88800ade:/# node --version
v6.3.0

Videos

Docker cookbook

Action Command example
List images $ docker images
Search for images $ docker search ubuntu
Search for images based on number of stars $ docker search --filter=stars=1000 ubuntu
Download and run an image $ docker run -it ubuntu ./bin/bash
Run a container providing it a name $ docker run -it --name=mycontainer ubuntu ./bin/bash
Run a container in the background $ docker run -d --name=mycontainer ubuntu sleep 15
Run a container and provide a volume $ docker run -it -v /Users/cjus:/data --name=mycontainer ubuntu ./bin/bash
Run a container and remap ports $ docker run -it -p 9000:3000 --name=mycontainer ubuntu ./bin/bash
Commit container $ docker commit -a "cjus" 0e15cf5343a7 ubuntu-node:0.1
List running images $ docker ps
List recent container, even those not running $ docker ps -a
Inspect docker container details $ docker inspect mycontainer
Run a container specifiying the working directory (-w option) and command to start $ docker run -d -w /microservice node-microservice:01 npm start
Attach to a running container $ docker attach 36d6cc18abec
Attach to a running container $ docker attach --name elegant_stallman
Remove container $ docker rm 768ec5f80ed3
Remove image $ docker rmi f238bc948d87
Stop docker container $ docker stop b03

docker run --name myredis -p 6379:6379 -v /Users/cjus/data:/data -d redis redis-server --appendonly yes

docker run --name myredis -p 6379:6379 -d redis

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment