Docker Crash Course

Boy was I wrong

I stayed away from docker for a long time because I thought it was difficult. Boy was I wrong. So lets dive right in. Docker is a form of linux container (now also windows) that is made mainly for isolating one app. This is the original idea anyway. How ever its safe to say some Docker images run more than one service. Like a web app will usually run both a web server and the underlying web app. However the main idea is that an image contains one app or function.

What happened was that I stopped using LXC for my “mediaserver”. I still use LXC for other things like my Nextcloud, but for media / managment etc docker turned out to be way easier to maintain / update. Continue reading this article to discover why.

Installing (Not reinventing the wheel here)

Installing docker on your system of choice has as many guides as there are newspapers. But whichever you choose. Make sure you use the Overlay or Overlay2 storage system as this makes a huge performance difference. I will recommend two:

Arch / Atergos: https://wiki.archlinux.org/index.php/Docker
Ubuntu: http://blog.ciplogic.com/index.php/blog/109-docker-with-overlayfs-on-ubuntu-16-04-lts

I’ve used both and they are good choices.

Intro

Docker Hub is the “marked” place for Docker images. This is also where you push (upload) your own image after making them. That being said, usually you dont have to make an image as there are thousands available for free…

Lets take a look at a typical docker hub page:
https://hub.docker.com/r/izzno/plexconnect/

There is typically a “usage” description . Lets have a look:

docker run -d \
--name plexconnect \
--network=host \
-v /path/to/store/plexconnect:/PlexConnect \
-e USERID=xxxx -e GROUPID=xxxx \
izzno/plexconnect

Now, what put me off the first time was the “\” at the end of the lines. This is called a line-continuation. Which means the above is actually just:

docker run -d --name plexconnect --network=host -v /path/to/store/plexconnect:/PlexConnect -e USERID=xxxx -e GROUPID=xxxx izzno/plexconnect

The “\” makes it an easier read and helps organize the command. Now lets split them up and try and explain the different switches.

docker run = Tells docker to run an Image. (Docker).
-d = Tells docker to daemonize (like “cmd &”) the Image.
–name = Gives the running image a name on your computer (more later).
–network=host = Gives the image access to ALL host ports.
-p = gives access to a cirtain port (Not Shown) .

-v = Volume, where to store files locally.

Some switches are split in two, separated by “:” or “=”. The first part of the “:” is where to store the files locally on your machine, the second part is the directory address of the files in the image.

-e = Environment variables.

This could be anything really. Its a way of passing information to the image during startup. In this particular case we are passing the user id and the group id which will tell the image who is going to own the files it produces on your filesystem.

izzno/plexconnect = This is the actual image, user/app.

Basic Use

Every guide I have ever read about docker uses Ubuntu as your first/example image. You spin up an Ubuntu instance, do some commands, close it and that’s it. Not very useful is it? That’s why we will do something completely different! 😛

Try:

docker run -d -p 8080:8080 aschil/snake

Every time you run an image, it checks to see if you have the newest/any version locally, if you dont it pulls (downloads) it. Now open your browser and type “localhost:8080” in the address bar. You now have snake running in docker, isolated from your system. But if you noticed, we did not enter any -v (volumes). This means this image does not have any persistent data, so when you stop your image, you will loose your highscore. Bummer. Lets have a look at docker:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59bf1d9797d0 aschil/snake "/bin/sh -c 'exec ..." 9 minutes ago Up 9 minutes 0.0.0.0:8080->8080/tcp boring_jepsen

You need a 1920 screen to view the over/under CLI interface from docker. Its incredible, but true. Anyway, the “docker ps” cmd will give you an overview of running images/containers. Now lets try and stop it:

$ docker stop snake
Error response from daemon: No such container: snake

Now here is where the “–name” comes to play. We did not give the container a name so docker picked one for us. For me you can se in the section above, its boring_jepsen :

$ docker stop boring_jepsen
boring_jepsen
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

For the sake of mental health I like to –name all my containers. Lets start snake again, but this time with a name:

$ docker run -d –name=snake -p 8080:8080 aschil/snake
ea19bb35edd1602c697284d6e2d8719edf881748de3e5021b9aee489337f91e5
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea19bb35edd1 aschil/snake “/bin/sh -c ‘exec …” 5 seconds ago Up 4 seconds 0.0.0.0:8080->8080/tcp snake
$ docker stop snake
snake

Now that’s more like it, and just to prove a point. Lets do it again!

$ docker run -d --name=snake -p 8080:8080 aschil/snake
docker: Error response from daemon: Conflict. The container name "/snake" is already in use by container "ea19bb35edd1602c697284d6e2d8719edf881748de3e5021b9aee489337f91e5". You have to remove (or rename) that container to be able to reuse that name.
See 'docker run --help'.

Hm, thats odd. Lets take a closer look:

$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea19bb35edd1 aschil/snake "/bin/sh -c 'exec ..." 10 minutes ago Exited (143) 7 minutes ago snake
59bf1d9797d0 aschil/snake "/bin/sh -c 'exec ..." 32 minutes ago Exited (143) 14 minutes ago boring_jepsen

This gives you a list of all your containers, stopped and running. You can not start a new container with the same name as one you already have, even if it is stopped. There is reason behind this:

$ docker start snake
snake
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ea19bb35edd1 aschil/snake "/bin/sh -c 'exec ..." 14 minutes ago Up 3 seconds 0.0.0.0:8080->8080/tcp snake
$ docker stop snake

snake

You just started snake again without passing a single switch! So, how do you get rid of them?

$ docker stop snake
snake
$ docker rm snake
snake
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
59bf1d9797d0 aschil/snake "/bin/sh -c 'exec ..." 39 minutes ago Exited (143) 22 minutes ago boring_jepsen

This removes the container. We still have the original image though. Lets look at our images:

$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
aschil/snake latest 19ca37900b68 10 months ago 434MB

Thats one hefty size for snake, we dont want that hanging around. Lets get rid of it:

$ docker image rm aschil/snake
Error response from daemon: conflict: unable to remove repository reference "aschil/snake" (must force) - container 59bf1d9797d0 is using its referenced image 19ca37900b68

Hm, something is still using the image, lets try and find out what container:

$ docker ps -a | grep 59bf1d9797d0
59bf1d9797d0 aschil/snake "/bin/sh -c 'exec ..." About an hour ago Exited (143) 34 minutes ago boring_jepsen

Ah, we forgot about the first container we made!

$ docker rm boring_jepsen
boring_jepsen
$ docker image rm aschil/snake
Untagged: aschil/snake:latest
Untagged: aschil/snake@sha256:ab807cd743c719dadc67153798c537fb0e987170c428bdd47dbc2cbd3bc15e00
Deleted: sha256:19ca37900b681cfd39b1bebfe9c103adafe491f2fc2b3178ec94147c65bf8d7c
Deleted: sha256:dfffe498a9c20498c2118935f364c45e1b1d12419179b4c2cb3b2c945f00cd98
Deleted: sha256:3151b6d9829c97c5274f1f403e9ac0eb1d354d721e4c8a69facb5241fc324b37
Deleted: sha256:871c14d90abdbf1dd41126a80d20dd5cf505fd564e18c69bacc2bd7128597dd5
Deleted: sha256:4ed62923db8f43d4302056c368114a9796ce3f9110477e886e91083084ccdbeb
Deleted: sha256:34e7b85d83e48a22bd5dfa2b6b9ee9565b7ef672f09b3d2409c61635f9bca4db

Thats it, we are back where we started, with no images or containers. That’s it for our crash course, have a look around Docker Hub and see what you can find! After playing around with different images there is another useful cmd you should remember:

$ docker image prune -a

This will remove all images not associated with a container.

$ docker container prune

This will remove all stopped containers.

Hope you enjoyed it! There is more in stock. As soon as I have time I will write another article on how to control docker containers with systemd, automating updates and start. See you soon.

Leave a Comment!