Docker
Cheat Sheet
docker build -t fitness . docker run --rm -v /var/run/mysqld/:/var/run/mysqld/ -p 3000:80 fitness (--rm means destroy the container when it's done) docker ps (get container id) docker inspect <container id> | grep IPAddress docker save my_image > my_image.tar docker load < my_image.tar docker exec <container id> some command... # examine contents of an image docker run -it eba11ed5c3ae /bin/bash # get interactive terminal for running container docker exec -it 28a50b7d941f /bin/bash # if you load a new image and you don't like it, you can # revert to the previous image docker tag -f 6f77dd268130 shakes:latest # get rid of all stopped containers docker rm $(docker ps -a -f status=exited -q) # get rid of all unused images docker rmi $(docker images -a -f dangling=true -q) # see resource usage docker stats
Install
follow instructions here:
https://docs.docker.com/engine/installation/ubuntulinux/
update firewall
The FORWARD chain should be changed from DROP to ACCEPT
Containers
docker run -i -t ubuntu /bin/bash # create a container docker run --name bob_the_container -i -t ubuntu /bin/bash # create a container with specified name docker ps # show running containers docker ps -a # show all containers docker ps -l # show more details docker start bob_the_container # start a stopped container docker attach bob_the_container # attach to a container # NOTE: hit Enter to get a prompt # create daemonized container docker run --name daemon_dave -d ubuntu /bin/sh -c \ "while true; do echo hello world; sleep 1; done" # view terminal output inside the container docker logs daemon_dave docker logs -f daemon_dave # like tail -f docker logs -t daemon_dave # print timestamps docker top daemon_dave # see what's happening inside the container # run a process inside the container docker exec -d daemon_dave touch /etc/config_file # background docker exec -t -i daemon_dave /bin/bash # interactive docker stop daemon_dave # stop a daemonized container # automatic container restarts docker run --restart=always --name daemon_dave -d ubuntu \ /bin/sh -c "while true; do echo hello world; sleep 1; done" # might be better to use this flag --restart=on-failure:5 # max of 5 restarts docker inspect daemon_dave # get container details # get IP address docker inspect --format '{{ .NetworkSettings.IPAddress }}' daemon_dave docker rm 80430f8d0921 # delete a stopped container
Images
Each image belongs to a repository. Repositories are either maintained by Docker, Inc. or by users. Official Docker repositories have a single name like ubuntu
or mysql
, while user-contributed repositories include a username, e.g. jamtur01/puppet
. All public repositories are generally hosted on Docker Hub
The ubuntu
repository contains images for each version. By default you get the image tagged latest
. You could also specify ubuntu:12.04
or ubuntu:precise
for version 12.04.
Docker images are read-only filesystems that get layered on top of each other in a union mount to form a container's filesystem. A read-write layer is always available on top.
docker images # list all local docker images docker images ubuntu # list only ubuntu-related images docker pull ubuntu:12.04 # download image without immediately running it docker inspect ubuntu:12.04 # show properties of a specific image docker search puppet # search Docker Hub docker rmi puppet # delete local image
Build an image with a Dockerfile
- create a directory with a
Dockerfile
in it:
$ mkdir static_web $ cd static_web $ touch Dockerfile
- edit the
Dockerfile
to look like this:
# Version: 0.0.1 FROM ubuntu: 14.04 MAINTAINER James Turnbull "james@example.com" RUN apt-get update RUN apt-get install -y nginx RUN echo 'Hi, I am in your container' > /usr/share/nginx/html/index.html EXPOSE 80
- build the image:
docker build --rm -t jamtur01/static_web:v1 .
- you can see the build steps with the history command:
docker history jamtur01/static_web
Build cache gotcha
Each step of the build is cached as a distinct image layer. As long as your Dockerfile doesn't change, these cached images get re-used for the build. You can use an ENV
variable to flush the cache at a particular step:
FROM ubuntu:14.04 MAINTAINER James Turnbull "james@example.com" ENV REFRESHED_AT 2014-07-01 RUN apt-get -qq update
Manually change the date in the ENV
line to get the latest updates.
Launch a container from an image
# port 80 of the container is mapped to a random high port on the host docker run -d -p 80 --name static_web jamtur01/static_web nginx -g "daemon off;" # port 80 of the container is mapped to port 12345 on the host docker run -d -p 12345:80 --name static_web jamtur01/static_web nginx -g "daemon off;" # port 80 of the container is mapped to port localhost:12345 on the host docker run -d -p 127.0.0.1:12345:80 --name static_web jamtur01/static_web nginx -g "daemon off;" # the EXPOSEd port of the container is mapped to a random high port on the host docker run -d -P --name static_web jamtur01/static_web nginx -g "daemon off;"
find the assigned port with
docker ps -l docker port mysql 3306 # if there multiple ports and you're interested in a specific service
Dockerfile
instructions
default command-line arguments for docker run
:
ENTRYPOINT ["/usr/bin/nginx"] # always executed when container is run CMD ["-h"] # added to command if nothing else at run command line docker run -t -i jamtur01/static_web -g "daemon off;" # gets added to nginx docker run -t -i jamtur01/static_web # no argument given; shows help instead
modifying run context:
WORKDIR /opt/webapp/db # changes working directory ENV RVM_PATH /home/rvm # added environment variable USER nginx # the user a container should be run as; default is root
file access:
COPY conf.d/ /etc/apache2/ # conf.d/ must exist in the build directory that contains the Dockerfile ADD software.lic /opt/application/software.lic # same as COPY ADD http://wordpress.org/latest.zip /root/wordpress.zip # copy from web ADD latest.tar.gz /var/www/wordpress/ # unpacks tarball into target directory VOLUME [ "/opt/project" ] # allows sharing and reuse of data
The ONBUILD
instruction adds triggers to images. A trigger is executed when the image is used as the basis of another image (e.g., if you have an image that needs source code added from a specific location that might not yet be available, or if you need to execute a build script that is specific to the environment in which the image is built).
ONBUILD ADD . /app/src ONBUILD RUN cd /app/src && make
Docker Hub Account
First create an account on the web, then run
docker login
and enter your credentials. The credentials will be stored on your machine at $HOME/.dockercfg
To push an image to your Docker Hub repository
docker push jamtur01/static_web
Can also use Automated Builds to upload directly from GitHub.
Run your own Docker registry
Use the registry
image from docker:
docker run -p 5000:5000 registry
To use it:
docker push example.server.com:5000/jamtur01/static_web
More details: https://github.com/docker/docker-registry/blob/master/README.md
Static web site
Dockerfile
FROM ubuntu:14.04 MAINTAINER James Turnbull "james@example.com" ENV REFRESHED_AT 2014-06-01 RUN apt-get update RUN apt-get -y -q install nginx RUN mkdir -p /var/www/html/website ADD nginx/nginx.conf /etc/nginx/ ADD nginx/global.conf /etc/nginx/conf.d/ EXPOSE 80
nginx.conf
user www-data; worker_processes 4; pid /run/nginx.pid; daemon off; events { } http { sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; access_log /var/log/nginx/access.log; error_log /var/log/nginx/error.log; gzip on; gzip_disable "msie6"; include /etc/nginx/conf.d/*.conf; }
global.conf
server { listen 0.0.0.0:80; server_name _; root /var/www/html/website; index index.html index.htm; access_log /var/log/nginx/default_access.log; error_log /var/log/nginx/default_error.log; }
run it
docker run -d -p 80 --name website -v $PWD/website:/var/www/html/website jamtur01/nginx nginx
The -v
argument creates a volume of web content that will be mapped into the container.
MySQL socket example
If your mysql
database is running on the host, use this:
docker run --rm -v /var/run/mysqld/:/var/run/mysqld/:rw -p 3000:80 my_image
Linking Docker containers
docker run -d --name redis jamtur01/redis # start the database server docker run -p 4567 --name webapp --link redis:db ... jamtur01/sinatra # link to redis and call it "db"
The webapp
container gets the IP address for "db" in its /etc/hosts
file and in environment variables like DB_PORT
.
DB_PORT= tcp://172.17.0.31:6379
require 'uri'
...
uri= URI.parse ( ENV [ 'DB_PORT' ])
redis = Redis.new(:host = > uri.host, :port = > uri.port)