On Github paulczar / cdatx-advanced-docker
Created by Paul Czarkowski / @pczarkowski
Cloud Engineer - BlueBox Cloud
FROM ubuntu:latest ADD . /home/docker ADD https://dist.torproject.org/torbrowser/4.0.4/tor-browser-linux64-4.0.4_en-US.tar.xz /home/docker/tor.tar.xz RUN apt-get update && true ENV DEBIAN_FRONTEND noninteractive RUN apt-get install -y firefox RUN localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 || : RUN useradd -m -d /home/docker docker RUN cd /home/docker && tar xJf /home/docker/tor.tar.xz USER docker CMD ["/home/docker/tor-browser_en-US/start-tor-browser"]
Optimizing your Dockerfile for build cache hits.
Sort your commands by
Sharable with other images Frequency of change Time to runUse the image of the application that is consuming it as the base for the volume container.
FROM ubuntu:latest ADD . /home/docker ADD https://dist.torproject.org/torbrowser/4.0.4/tor-browser-linux64-4.0.4_en-US.tar.xz /home/docker/tor.tar.xz RUN apt-get update && true ENV DEBIAN_FRONTEND noninteractive RUN apt-get install -y firefox RUN localedef -v -c -i en_US -f UTF-8 en_US.UTF-8 || : RUN useradd -m -d /home/docker docker RUN cd /home/docker && tar xJf /home/docker/tor.tar.xz USER docker CMD ["/home/docker/tor-browser_en-US/start-tor-browser"]
"I don't need Config Management now that I have Docker."
You probably shouldn't be trusting docker [yet] for managing long term persistent data.
Persistent data stores and other infrastructure services have to be managed by something.
https://supermarket.chef.io/cookbooks/docker
include_recipe "docker::default"
docker_image 'registry' do action [:pull] end docker_container 'registry' do detach true port '5000:5000' action [:run] end node['my_app']['images'].each do |image| docker_image image do action [:pull] end docker_image image do repository "#{node['my_app']['registry']}/#{image}" registry node['my_app']['registry'] action [:tag, :push] end end
git "#{Chef::Config[:file_cache_path]}/docker-testcontainerd" do repository 'git@github.com:bflad/docker-testcontainerd.git' notifies :build, 'docker_image[tduffield/testcontainerd]', :immediately end docker_image 'tduffield/testcontainerd' do action :pull_if_missing end
Almost anything that can be done with docker can be done via the docker cookbook.
Puppet and Ansible both have a similar story.
You probably shouldn't...
But if it makes sense in your use case ... go for it.
Consider Chef for Containers if you want to do this, it will help deal with managing services etc.
Run Chef from a volume mount so that it doesn't actually live in your container.
If you're already using a tool like Packer to create images with Config Management, you can probably switch it to build Docker images very easily.
If you're like me and run an OS that's not well supported by ChefDK ... run it in a container.
$ docker run -d -v ~/chef/cookbook:/cookbook --name chefdk spheromak/docker-chefdk sleep 6000000 $ docker exec -ti chefdk bundle install $ docker exec -ti chefdk rake test
This used to be hard. It's a lot less hard now.
Try your very best not to ever log to a file in the container. Otherwise you will probably face logfile management issues.
Logspout by @progrium
$ docker run -v=/var/run/docker.sock:/tmp/docker.sock \ progrium/logspout \ syslog://logs.papertrailapp.com:55555
But my app doesn't log to stdout/stderr.
It does now!
# /etc/nginx/nginx.conf worker_processes 1; daemon off; user app app; pid /app/nginx.pid; error_log /dev/stderr; access_log /dev/stdout; ...
But seriously I can't configure it to log to /dev/stdout
Logging improvements coming soon!
CAdvisor to the rescue.
sudo docker run \ --volume=/:/rootfs:ro \ --volume=/var/run:/var/run:rw \ --volume=/sys:/sys:ro \ --volume=/var/lib/docker/:/var/lib/docker:ro \ --publish=8080:8080 \ --detach=true \ --name=cadvisor \ google/cadvisor:latest
Cadvisor natively support Docker and most linux containers based on LXC
There are times when you need to run multiple processes in a container.
Ignore the nay-sayers ... this is OK.
#!/bin/boot mysqld_safe & /usr/bin/hhvm --config /etc/hhvm/server.ini --user app -m server & apache2 -DFOREGROUND
Problems
Docker and the pid 1 zombie reaping problem
I have an application in a container ... but how do I actually configure it ?
This is the simplest use case, if your configuration file is very static just use ADD in your `Dockerfile` to put it in the correct place.
You can also mount it in from your host ( useful if already using CM to write the config file on the host ).
docker run -d -v /my/app/apache2/httpd.conf:/etc/apache2/httpd.conf myapp
It's OK to do this, but be aware of the potential security implications.
#!/bin/bash PORT=${PORT:-5000} sed -i "s/xxxPORTxxx/$PORT/" /etc/apache2/httpd.conf exec apache2 -DFOREGROUND
FROM ubuntu:trusty RUN \ curl -sSL -o /usr/local/bin/etcdctl \ https://s3-us-west-2.amazonaws.com/opdemand/etcdctl-v0.4.6 \ && chmod +x /usr/local/bin/etcdctl \ && curl -sSL -o /usr/local/bin/confd \ https://github.com/kelseyhightower/confd/releases/download/v0.7.1/confd-0.7.1-linux-amd64 \ && chmod +x /usr/local/bin/confd
#!/bin/bash BACKEND=${BACKEND:-env} until confd -onetime -backend=${BACKEND} -confdir=/etc/confd ; do echo "echo ==> ${APP_NAME}: waiting for confd to write initial templates..." sleep 1 done exec apache2 -DFOREGROUND
$ docker run -d -p 8080 \ -e APACHE_PORT=8080 -e APACHE_ROOT=/app/web \ apache /app/bin/boot
Deeper dive into confd during demo / workshop.
docker pull factorish/example
$ docker run -d -e SERVICES_EXAMPLE_TEXT=father \ -p 8080:8080 --name father factorish/example $ curl localhost:8080 # or IP of boot2docker $ docker run -d -e SERVICES_EXAMPLE_TEXT=mother \ -p 8081:8080 --name mother factorish/example $ curl localhost:8080 # or IP of boot2docker $ docker kill father mother $ docker rm father mother
$ vagrant up ..... $ vagrant ssh core-01 $ etcd ctl / --recursive