Docker

Docker uses the resource isolation features of the Linux kernel to allow independent "containers" to run within a single Linux instance, avoiding the overhead of starting and maintaining virtual machines.

Docker idea

There a docker images. You can create new images by taking an existing image and change it, e.g. take an Ubuntu image and install apache on it. This will than be a new image with a new name. You can run commands in the context of an docker image. For example you can run an apache webserver on your new Ubuntu image with apache installed. You can even start several instances of the apache webserver from the same image and have a cluster of webservers running. You can give the running commands names, to distinguish between the different commands (e.g. webserver_1, webserver_2, ...). Per default they get funny human readable names.

Installation

Install Docker on Debian

apt-get install docker.io
docker run hello-world

FATA[0000] Post http:///var/run/docker.sock/v1.17/containers/create: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

You forgot to start Docker :-)

sudo service docker start
sudo docker run hello-world
Unable to find image 'hello-world:latest' locally
Pulling repository hello-world
docker run hello-world

Find images for download

Different various how to choose from Docker images other people have already prepared and uploaded for you

docker pull ubuntu
docker pull ubuntu:15.10
docker pull debian:jessie

Show locally stored images

docker images

Remove locally stored images

docker rmi -f ff3358d67357

Build you own Docker image

Create an empty folder, but a file Dockerfile https://docs.docker.com/engine/reference/builder/ in it. Fill the Dockerfile with docker instructions how to create the image. Run

docker build -t myName .

to create a new docker image with the name myName (or foo/myName if foo would be your username for later uploading the image)

https://docs.docker.com/engine/userguide/dockerimages/

https://docs.docker.com/engine/reference/builder/

Dockerizing an service

Building an image with the idea to run a specific service later on from it, e.g. a database. For many popular services there are images already ready to be used. Examples how to do that by your own

https://docs.docker.com/engine/examples/running_ssh_service/

In short, create an empty folder with a file named Dockerfile in it. In this file define what you need to have installed and what to run at the end.

This builds a docker image and runs it

docker build -t anyname .
docker rm anyname
docker run -d -P --name=anyname anyname
docker ps -a | grep anyname

The names are optional but otherwise it is confusing to understand what is your stuff.

During development this opens a bash instead of running the CMD at end of the Dockerfile

docker run --name anyname -it anyname bash

Running commands in a docker context

Any changes which are caused by running commands to their image are discarded once they are stopped!

Start in echo command in an Debian image (will be downloaded if not there already)

docker run debian:jessie /bin/echo 'Hello world' with output Hello world

There is even a ready to be used Hello world image

docker run hello-world

Run a command interactively inside the image with name "debian"

docker run --name funnyName  -it debian bash
docker run --name funnyName -it --entrypoint /bin/bash debian

Run a commen interactively inside an already running container

docker exec -it cocky_wright bash

Get the output of that command

docker logs cocky_wright

Get a list of currently running commands

docker ps

Stop a running command (the name is not the image name but the name which was assigned to the running command. See docker ps for that name)

docker stop cocky_wright

Run commands in background

docker run -d debian /bin/sh -c "while true; do echo hello world; sleep 1; done"

A more useful example is that you have an image to hold the mongoDB database called foo/mongo. The database normally uses port 27017. With this command you can start 2 instances of that database in the context of your image. Thanks to port mapping you can reach one instance on port 28001 and the other one on 28001

docker run -p 28001:27017 --name mongo_instance_001 -d foo/mongo
docker run -p 28002:27017 --name mongo_instance_002 -d foo/mongo

An alternative would be to connect directly to the IP address of the docker container which you can find like this

docker inspect --format='{{ .NetworkSettings.IPAddress }}' mongo_instance_001
docker inspect --format='{{ .NetworkSettings.IPAddress }}' mongo_instance_002

List file content of a docker image (does not need to be started). The output is a tar file so you need tar to read it

docker export debian | tar t

Running a command inside a docker container that does not even exist there but take it from the host (here my-docker-container does not have netstat installed

nsenter -t $(docker inspect -f '{{.State.Pid}}' my-docker-container) -n netstat -n

Persist Data

Normally all changes within a running docker image are not persisted. Here so ways to keep data between restarts: https://docs.docker.com/engine/userguide/containers/dockervolumes/

Problems

If you get this error

FATA[0000] Post http:///var/run/docker.sock/v1.17/containers/create: dial unix /var/run/docker.sock: no such file or directory. Are you trying to connect to a TLS-enabled daemon without TLS?

you may have forgotten to start docker

sudo service docker start

Helpful Docker commands

Copy a docker image from one registry to another

docker login -u userA -p SECRET_PASSWORD_A my_registry_a.example.com
docker login -u userB -p SECRET PASSWORD_B my_registry_b.example.com

docker tag  my_registry_a.example.com/my-software:v0.0.4     my_registry_b.example.com/my-software:v0.0.4
docker push my_registry_b.example.com/my-software:v0.0.4

See the contents of a docker image without the need to start it

docker create --name foo my-docker-registy.example.com/foo-back:1.234
docker export foo  | tar vx