Skip to content

Latest commit

 

History

History
311 lines (170 loc) · 9.72 KB

README.md

File metadata and controls

311 lines (170 loc) · 9.72 KB

Docker

https://github.com/dotcloud/docker

Relies on Linux Kernel namespaces to solve dependency hell.

Upsides:

  • fast
  • each VM (container) takes very little disk space.

Downsides:

Good getting started: http://docs.docker.io/introduction/working-with-docker/

Docker was developed by a company called dotCloud Inc, and open sourced. dotCloud was renamed to Docker Inc. in 2014.

Getting started

Download Ubuntu image, and create a new container from it named ub16:

sudo docker run --name ub16 -it ubuntu:16.04 bash

Write a file there:

date >f

Ctrl + D kills the VM, as can be seen by the empty:

sudo docker ps

which lists all containers. To get turn it back on:

sudo docker start -ai ub16

To detach without turning it off enter Ctrl-P Ctrl-Q: https://stackoverflow.com/questions/19688314/how-do-you-attach-and-detach-from-dockers-process

To open a new shell in a running container https://stackoverflow.com/questions/39794509/how-to-open-multiple-terminals-in-docker run:

sudo docker exec -it ub16 bash

And check that f is present:

cat f

Help

List all commands:

sudo docker help

Get help on one command:

sudo docker help build

Good info on the manpages:

man docker
man docker-run

Images

Public image index at https://index.docker.io/.

Search for image:

sudo docker search nginx

Sample output:

NAME                            DESCRIPTION                              STARS  OFFICIAL  TRUSTED
dockerfile/nginx                Trusted Nginx (http://nginx.org/)  ...   27               [OK]
dockerfiles/django-uwsgi-nginx  Dockerfile and configuration files ...   7                [OK]
paintedfox/nginx-php5           A docker image for running Nginx wi...   5                [OK]

TODO: how is TRUSTED determined?

Download image:

sudo docker pull ubuntu
sudo docker pull dockerfile/nginx

List images available locally:

sudo docker images

Sample output:

REPOSITORY         TAG      IMAGE ID      CREATED         VIRTUAL SIZE
myUserName/nginx   latest   a0d6c70867d2  41 seconds ago  578.8 MB
nginx              latest   173c2dd28ab2  3 minutes ago   578.8 MB
ubuntu             13.10    5e019ab7bf6d  3 weeks ago     180 MB
ubuntu             saucy    5e019ab7bf6d  3 weeks ago     180 MB
ubuntu             12.04    74fe38d11401  3 weeks ago     209.6 MB
ubuntu             precise  74fe38d11401  3 weeks ago     209.6 MB

TAG is the version of the box, much like Git tags. Tags can be specified as: ubuntu:14.04.

Remove image:

sudo docker rmi image_name

No existing container, including stopped, must be using it. Can force with -f (TODO does it prevent from using the container then?).

Export an image to tar format:

sudo docker save image_name > image_name.tar

Then note that every ADD and RUN command in a Dockerfile generates a separate snapshot of the image.

Interesting images include:

run

Create a new container and run command on it. Use start to reuse a container created with run.

The most useful command is of the form:

id="$(sudo docker run -d -p 127.0.0.1:8000:80 dockerfile/nginx)"

which will run Nginx on port 8000 of the host. It can be stopped with:

sudo docker stop "$id"

This presupposes that the image's dockerfile/nginx Dockerfile contains a CMD line.

Run single command on starting from image ubuntu:

sudo docker run ubuntu /usr/bin/id -un
sudo docker run 5e019ab7bf6d /usr/bin/id -un

Output:

root

If not present, the image is downloaded.

If the image's Dockerfile has CMD, then the command can be omitted and CMD is used. This is the case for the official Nginx image:

sudo docker run dockerfile/nginx

which automatically starts running Nginx.

Run multiple commands:

sudo docker run ubuntu /bin/bash -c 'sleep 2 && id -un'

Docker binds the terminals from container into host terminal and only exits when the command exits.

Start interactive shell with -it:

sudo docker run -it ubuntu /bin/bash

TODO why does it not work without -it, considering that it also occupies the stdin / stdout?

-p: map port 80 of container to port 8000 of host:

sudo docker run -p 127.0.0.1:8000:80 dockerfile/nginx

And now from the host:

firefox localhost:8000

--name: give a name to a container:

sudo docker run --name container_name ubuntu /usr/bin/id -un

If you don't do this, you will have to refer to the container by its ID. This allows you to run on another terminal things like:

sudo docker attach container_name
sudo docker stop container_name

The name must be unique, including across stopped containers.

It is only possible to run a single process inside a container, but it is possible to have a process that runs many others: http://docs.docker.io/examples/using_supervisord/. This is why the following fails to run on the host TODO confirm:

sudo docker run -p 8000:80 -it ubuntu /bin/bash
apt-get install -y nginx
service apache2 nginx

Same goes for a bare CMD nginx, since by default Nginx turns itself into a background process. This is why daemon off is required on the Nginx configuration as stated at: http://stackoverflow.com/questions/18861300/how-to-run-nginx-within-docker-container-without-halting.

-d: run detached container and print it ID:

id="$(sudo docker run -d -p 127.0.0.1:8000:80 dockerfile/nginx)"
sudo docker stop "$id"

volume

v

Share directory between guest and host:

sudo docker run -v path/in/host:/full/path/in/guest ubuntu date > /full/path/in/guest/mydate
cat path/in/host/mydate

It gets updated immediately.

Can only take absolute paths on guest. Efficient for large files, unlike some VM schemes. The paths get created if they don't exist.

Only works for new containers: https://stackoverflow.com/questions/28302178/how-can-i-add-a-volume-to-an-existing-docker-container

Cannot mount guest to host: https://stackoverflow.com/questions/36246094/how-to-mount-a-directory-in-a-docker-container-to-the-host

GUI apps

Easiest method: https://stackoverflow.com/questions/31446661/build-a-full-ubuntu-desktop-docker-image/51122106#51122106

More manual method: https://stackoverflow.com/questions/16296753/can-you-run-gui-apps-in-a-docker-container

sudo docker run --net=host

Then in guest:

apt-get install x11vnc xvfb

Then in host:

sudo apt-get install vinagre
vinagre localhost:5900

Port forwarding

https://stackoverflow.com/questions/17770902/forward-host-port-to-docker-container

ps

List running containers:

sudo docker ps

List all containers, including those previously stopped:

sudo docker ps -a

Sample output:

CONTAINER ID        IMAGE                     COMMAND                CREATED              STATUS                          PORTS               NAMES
e676beb2500b        ubuntu:14.04              /bin/bash -c 'sleep    About a minute ago   Exited (0) About a minute ago                       silly_perlman
b7876bb06c7d        ubuntu:14.04              /bin/bash              3 minutes ago        Exited (1) 3 minutes ago                            prickly_albattani
3426d733883a        ubuntu:14.04              /bin/bash -c 'sleep    5 minutes ago        Exited (0) 5 minutes ago                            insane_fermat

Some fields such as mapped ports and name only appear of they are not empty:

sudo docker run --name name0 --expose 8000 -i -p 127.0.0.1:8000:8000 -t dockerfile-test bash
sudo docker ps

Stop container:

sudo docker stop ubuntu

Restart container that was stopped / finished executing detached:

sudo docker run --name start_test ubuntu date
sudo docker start start_test

Since it is detached by default it will only print its ID, not the stdout.

Attach:

sudo docker start -a start_test

Remove a container:

sudo docker rm 3e552code34a

Remove all containers http://stackoverflow.com/questions/17236796/how-to-remove-old-docker-io-containers:

sudo docker rm $(sudo docker ps -aq --no-trunc)

attach

Attach to a running container:

sudo docker run -it --name name0 ubuntu bash

On another terminal:

sudo docker attach name0

Now stdin and stdout of both terminals are attached: whatever you do on one shows on both.

Detach with Ctrl-p + Ctrl-q. Doing Ctrl-d would terminate the shell and the container. You can detach even if you are in the last TTY.

Dockerfile

Dockerfiles use yet another programming language.

A good way to learn their most important features is by looking at key Dockerfiles such as:

Documentation at: http://docs.docker.io/reference/builder/

Build is very efficient. Each step generates a new cached machine. Next machines pick up from those caches. So if you run apt-get install biglib and build twice, it will only download the library once! Downside: no state is kept between builds.

build

Generate a container from the Dockerfile in the current directory with given name:

sudo docker build -t name .
sudo docker run -it name bash