Docker | Cookbook
Useful apps
dive: About A tool for exploring each layer in a docker image
Useful commands
- docker ps — Lists running containers.
Some useful flags include:-a
/-all
for all containers (default shows just running) and—-quiet
/-q
to list just their ids (useful for when you want to get all the containers). - docker pull — Most of your images will be created on top of a base image from the Docker Hub registry. Docker Hub contains many pre-built images that you can
pull
and try without needing to define and configure your own. To download a particular image, or set of images (i.e., a repository), usedocker pull
. - docker build — Builds Docker images from a Dockerfile and a “context”.
A build’s context is the set of files located in the specifiedPATH
orURL
. Use the-t
flag to label the image, for exampledocker build -t my_container .
with the.
at the end signalling to build using the currently directory. - docker run — Run a docker container based on an image.
You can follow this on with other commands, such as-it bash
to then run bash from within the container.
Also see Top 10 options for docker run — a quick reference guide for the CLI command.docker run my_image -it bash
- docker logs — Display the logs of a container.
You must specify a container and can use flags, such as--follow
to follow the output in the logs of using the program.docker logs --follow my_container
- docker volume ls — Lists the volumes,.
Volumes are the preferred mechanism for persisting data generated by and used by Docker containers. - docker rm — Removes one or more containers.
docker rm my_container
- docker rmi — Removes one or more images.
docker rmi my_image
- docker stop — Stops one or more containers.
docker stop my_container
stops one container, whiledocker stop $(docker ps -a -q)
stops all running containers. A more direct way is to usedocker kill my_container
, which does not attempt to shut down the process gracefully first. - Use them together, for example to clean up all your docker images and containers:
- kill all running containers with
docker kill $(docker ps -q)
- delete all stopped containers with
docker rm $(docker ps -a -q)
- delete all images with
docker rmi $(docker images -q)
Create new container
Start a new docker image with a given name
You can start a new container by using the run command and specify the desired image
$ docker run -it --name playground ubuntu:17.10 /bin/bash .... root@c106fbb48b20:/# exit
As a result, you are in the container at the bash command line
Reconnect to image
$ docker attach playground
Commit changes in container
$ docker start playground $ docker attach playground root@c106fbb48b20:/# echo 1.0 >VERSION root@c106fbb48b20:/# exit $ docker commit playground playground:1.0 $ docker tag playground:1.0 playground:latest $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE playground 1.0 01703597322b Less than a second ago 94.6MB playground latest 01703597322b Less than a second ago 94.6MB
Add tools and utilities
Python
$ apt-get update $ apt-get upgrade $ apt-get install python3 python3-pip
Java
$ apt-get install default-jre
Manage File Shares
File shares with Docker Desktop on Mac OS
Configuration is stored under
~/Library/Group Containers/group.com.docker/settings.json
Monitor Docker Logs
Logs with Docker Desktop on Mac OS
pred='process matches ".*(ocker|vpnkit).*" || (process in {"taskgated-helper", "launchservicesd", "kernel"} && eventMessage contains[c] "docker")'
/usr/bin/log stream --style syslog --level=debug --color=always --predicate "$pred"
Alternative you can run
/usr/bin/log show --style syslog --debug --info --last 1d --predicate "$pred" >/tmp/logs.txt
Add Timezone Konfiguration
ENV TZ 'Europe/Berlin' RUN echo $TZ > /etc/timezone RUN apt-get install -y tzdata \ && rm /etc/localtime \ && ln -snf /usr/share/zoneinfo/$TZ /etc/localtime \ && dpkg-reconfigure -f noninteractive tzdata \ && apt-get clean
Install local apps in a docker container
Install Atom Editor
Start docker image
$ docker run -it --name docker-atom -v /Dockerfiles/HOME:/home -e DISPLAY=192.168.99.1:0 ubuntu /bin/bash
Install Atom
# apt-get update # apt-get install curl # curl -sL https://deb.nodesource.com/setup_7.x | bash - # apt-get install nodejs # node -v v7.4.0
# apt-get -y install git # apt-get -y install software-properties-common
# add-apt-repository -y ppa:webupd8team/atom # apt-get update # apt-get -y install atom
# apt-get install libxss1
Commit changes and build a image
# docker commit -a "Docker Tutorial 1.0.0" -m ionic d378e8647af9 atom:1.0.0 # docker tag atom:1.0.0 atom:latest
Links and Resources
Docker quick reference guides
- Run bash or any command in a Docker container
- Top 10 options for docker run — a quick reference guide for the CLI command
- Docker’s detached mode for beginners: How to run containers in the background of your terminal
Docker in more depth
- Clean out your Docker images, containers and volumes with single commands
- How I filter and grep Docker containers, images, and volumes, and how you can too
- Expose vs publish: Docker port commands explained simply
- Docker run vs exec: deep-dive into their differences
- How to use Entrypoint with Docker and Docker Compose
Working with networks
I’ve got a lot of inspiration from wsargent/docker-cheat-sheet.
Goal
We will setup to applications, each in his one container, running on the smae network, so they can communication together.
Setup
Starting with the default configuration, you will see 4 networks
$ docker network ls NETWORK ID NAME DRIVER SCOPE 6742a11bff1e bridge bridge local 3af0a1c9eaac host host local e60f68aad9d6 none null local
Create a bridged network for running two apps inside: web and database
$ docker network create -d bridge playground_bridge c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1
$ docker network ls NETWORK ID NAME DRIVER SCOPE 6742a11bff1e bridge bridge local 3af0a1c9eaac host host local e60f68aad9d6 none null local c97a80b449d9 playground_bridge bridge local
Start the database application using the bridges network
$ docker run -d --net=playground_bridge --name playground_db training/postgres 88abb9d018c628ed1abe7da0466289846a8342a28b2cbef3305ea5313c46d647
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db| python -m json.tool { "playground_bridge": { "Aliases": [ "88abb9d018c6" ], "DriverOpts": null, "EndpointID": "9fdfe9baf5b159471a39601779ee451aa555a9a9be72be4472e56bd3fcfd1350", "Gateway": "172.18.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAMConfig": null, "IPAddress": "172.18.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "Links": null, "MacAddress": "02:42:ac:12:00:02", "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1" } }
Now, start the web application with the default network (not the playground_bridge used by the database)
$ docker run -d --name playground_web training/webapp python app.py 2f31761168d75d10c2f1bffc805fb8963a18529e17c2592c2b279afd9e364e7b
They cannot communication, because they are running in different networks:
$ docker exec -it playground_db ifconfig | grep inet inet addr:172.18.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet addr:127.0.0.1 Mask:255.0.0.0 $ docker exec -it playground_web ifconfig | grep inet inet addr:172.17.0.2 Bcast:0.0.0.0 Mask:255.255.0.0 inet addr:127.0.0.1 Mask:255.0.0.0
Now check the connectivity. The Web application can reach itself:
$ docker exec -it playground_web ping -c 5 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.027 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.033 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.036 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.031 ms 64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.029 ms
But could not reach the database application (because of the different network):
$ docker exec -it playground_web ping -c 5 172.18.0.2 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. --- 172.18.0.2 ping statistics --- 5 packets transmitted, 0 received, 100% packet loss, time 4126ms
To connect both apps together, put them in the same network:
Before, they use different networks:
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_web | python -m json.tool|grep NetworkID "NetworkID": "6742a11bff1ebcdeaee9151f146a74b1c3d77db95d4931e4e79f48f7d7f491f7" $ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db | python -m json.tool|grep NetworkID "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"
Connect Web Application to network playground_bridge:
$ docker network connect playground_bridge playground_web
Now, they use the same network:
$ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_web | python -m json.tool|grep NetworkID "NetworkID": "6742a11bff1ebcdeaee9151f146a74b1c3d77db95d4931e4e79f48f7d7f491f7" "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1" $ docker inspect --format='{{json .NetworkSettings.Networks}}' playground_db | python -m json.tool|grep NetworkID "NetworkID": "c97a80b449d9b6b28ddffa0a7bd4a7938e0b8261773080ab33ae4b7ab08826b1"
And they can communication
$ docker exec -it playground_web ping -c 5 172.17.0.2 PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data. 64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.044 ms 64 bytes from 172.17.0.2: icmp_seq=2 ttl=64 time=0.032 ms 64 bytes from 172.17.0.2: icmp_seq=3 ttl=64 time=0.033 ms 64 bytes from 172.17.0.2: icmp_seq=4 ttl=64 time=0.032 ms 64 bytes from 172.17.0.2: icmp_seq=5 ttl=64 time=0.033 ms --- 172.17.0.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4144ms rtt min/avg/max/mdev = 0.032/0.034/0.044/0.008 ms $ docker exec -it playground_web ping -c 5 172.18.0.2 PING 172.18.0.2 (172.18.0.2) 56(84) bytes of data. 64 bytes from 172.18.0.2: icmp_seq=1 ttl=64 time=0.134 ms 64 bytes from 172.18.0.2: icmp_seq=2 ttl=64 time=0.052 ms 64 bytes from 172.18.0.2: icmp_seq=3 ttl=64 time=0.056 ms 64 bytes from 172.18.0.2: icmp_seq=4 ttl=64 time=0.052 ms 64 bytes from 172.18.0.2: icmp_seq=5 ttl=64 time=0.053 ms --- 172.18.0.2 ping statistics --- 5 packets transmitted, 5 received, 0% packet loss, time 4156ms rtt min/avg/max/mdev = 0.052/0.069/0.134/0.033 ms
Usefull Links
https://blog.docker.com/2019/07/intro-guide-to-dockerfile-best-practices/