docs/index.xml

3626 lines
180 KiB
XML
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
<title>Docker Docs</title>
<link>http://localhost/</link>
<description>Recent content on Docker Docs</description>
<generator>Hugo -- gohugo.io</generator>
<language>en-us</language>
<atom:link href="http://localhost/index.xml" rel="self" type="application/rss+xml" />
<item>
<title>Link via an ambassador container</title>
<link>http://localhost/articles/ambassador_pattern_linking/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/ambassador_pattern_linking/</guid>
<description>
&lt;h1 id=&#34;link-via-an-ambassador-container&#34;&gt;Link via an ambassador container&lt;/h1&gt;
&lt;h2 id=&#34;introduction&#34;&gt;Introduction&lt;/h2&gt;
&lt;p&gt;Rather than hardcoding network links between a service consumer and
provider, Docker encourages service portability, for example instead of:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(consumer) --&amp;gt; (redis)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Requiring you to restart the &lt;code&gt;consumer&lt;/code&gt; to attach it to a different
&lt;code&gt;redis&lt;/code&gt; service, you can add ambassadors:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(consumer) --&amp;gt; (redis-ambassador) --&amp;gt; (redis)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(consumer) --&amp;gt; (redis-ambassador) ---network---&amp;gt; (redis-ambassador) --&amp;gt; (redis)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;When you need to rewire your consumer to talk to a different Redis
server, you can just restart the &lt;code&gt;redis-ambassador&lt;/code&gt; container that the
consumer is connected to.&lt;/p&gt;
&lt;p&gt;This pattern also allows you to transparently move the Redis server to a
different docker host from the consumer.&lt;/p&gt;
&lt;p&gt;Using the &lt;code&gt;svendowideit/ambassador&lt;/code&gt; container, the link wiring is
controlled entirely from the &lt;code&gt;docker run&lt;/code&gt; parameters.&lt;/p&gt;
&lt;h2 id=&#34;two-host-example&#34;&gt;Two host example&lt;/h2&gt;
&lt;p&gt;Start actual Redis server on one Docker host&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;big-server $ docker run -d --name redis crosbymichael/redis
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then add an ambassador linked to the Redis server, mapping a port to the
outside world&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;big-server $ docker run -d --link redis:redis --name redis_ambassador -p 6379:6379 svendowideit/ambassador
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On the other host, you can set up another ambassador setting environment
variables for each remote port we want to proxy to the &lt;code&gt;big-server&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client-server $ docker run -d --name redis_ambassador --expose 6379 -e REDIS_PORT_6379_TCP=tcp://192.168.1.52:6379 svendowideit/ambassador
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then on the &lt;code&gt;client-server&lt;/code&gt; host, you can use a Redis client container
to talk to the remote Redis server, just by linking to the local Redis
ambassador.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;client-server $ docker run -i -t --rm --link redis_ambassador:redis relateiq/redis-cli
redis 172.17.0.160:6379&amp;gt; ping
PONG
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;The following example shows what the &lt;code&gt;svendowideit/ambassador&lt;/code&gt; container
does automatically (with a tiny amount of &lt;code&gt;sed&lt;/code&gt;)&lt;/p&gt;
&lt;p&gt;On the Docker host (192.168.1.52) that Redis will run on:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# start actual redis server
$ docker run -d --name redis crosbymichael/redis
# get a redis-cli container for connection testing
$ docker pull relateiq/redis-cli
# test the redis server by talking to it directly
$ docker run -t -i --rm --link redis:redis relateiq/redis-cli
redis 172.17.0.136:6379&amp;gt; ping
PONG
^D
# add redis ambassador
$ docker run -t -i --link redis:redis --name redis_ambassador -p 6379:6379 busybox sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In the &lt;code&gt;redis_ambassador&lt;/code&gt; container, you can see the linked Redis
containers &lt;code&gt;env&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ env
REDIS_PORT=tcp://172.17.0.136:6379
REDIS_PORT_6379_TCP_ADDR=172.17.0.136
REDIS_NAME=/redis_ambassador/redis
HOSTNAME=19d7adf4705e
REDIS_PORT_6379_TCP_PORT=6379
HOME=/
REDIS_PORT_6379_TCP_PROTO=tcp
container=lxc
REDIS_PORT_6379_TCP=tcp://172.17.0.136:6379
TERM=xterm
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This environment is used by the ambassador &lt;code&gt;socat&lt;/code&gt; script to expose Redis
to the world (via the &lt;code&gt;-p 6379:6379&lt;/code&gt; port mapping):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker rm redis_ambassador
$ sudo ./contrib/mkimage-unittest.sh
$ docker run -t -i --link redis:redis --name redis_ambassador -p 6379:6379 docker-ut sh
$ socat TCP4-LISTEN:6379,fork,reuseaddr TCP4:172.17.0.136:6379
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now ping the Redis server via the ambassador:&lt;/p&gt;
&lt;p&gt;Now go to a different server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo ./contrib/mkimage-unittest.sh
$ docker run -t -i --expose 6379 --name redis_ambassador docker-ut sh
$ socat TCP4-LISTEN:6379,fork,reuseaddr TCP4:192.168.1.52:6379
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And get the &lt;code&gt;redis-cli&lt;/code&gt; image so we can talk over the ambassador bridge.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker pull relateiq/redis-cli
$ docker run -i -t --rm --link redis_ambassador:redis relateiq/redis-cli
redis 172.17.0.160:6379&amp;gt; ping
PONG
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;the-svendowideit-ambassador-dockerfile&#34;&gt;The svendowideit/ambassador Dockerfile&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;svendowideit/ambassador&lt;/code&gt; image is a small &lt;code&gt;busybox&lt;/code&gt; image with
&lt;code&gt;socat&lt;/code&gt; built in. When you start the container, it uses a small &lt;code&gt;sed&lt;/code&gt;
script to parse out the (possibly multiple) link environment variables
to set up the port forwarding. On the remote host, you need to set the
variable using the &lt;code&gt;-e&lt;/code&gt; command line option.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;--expose 1234 -e REDIS_PORT_1234_TCP=tcp://192.168.1.52:6379
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Will forward the local &lt;code&gt;1234&lt;/code&gt; port to the remote IP and port, in this
case &lt;code&gt;192.168.1.52:6379&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#
#
# first you need to build the docker-ut image
# using ./contrib/mkimage-unittest.sh
# then
# docker build -t SvenDowideit/ambassador .
# docker tag SvenDowideit/ambassador ambassador
# then to run it (on the host that has the real backend on it)
# docker run -t -i --link redis:redis --name redis_ambassador -p 6379:6379 ambassador
# on the remote host, you can set up another ambassador
# docker run -t -i --name redis_ambassador --expose 6379 sh
FROM docker-ut
MAINTAINER SvenDowideit@home.org.au
CMD env | grep _TCP= | sed &#39;s/.*_PORT_\([0-9]*\)_TCP=tcp:\/\/\(.*\):\(.*\)/socat TCP4-LISTEN:\1,fork,reuseaddr TCP4:\2:\3 \&amp;amp;/&#39; | sh &amp;amp;&amp;amp; top
&lt;/code&gt;&lt;/pre&gt;
</description>
</item>
<item>
<title>Resizing a Boot2Docker volume </title>
<link>http://localhost/articles/b2d_volume_resize/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/b2d_volume_resize/</guid>
<description>
&lt;h1 id=&#34;getting-no-space-left-on-device-errors-with-boot2docker&#34;&gt;Getting “no space left on device” errors with Boot2Docker?&lt;/h1&gt;
&lt;p&gt;If you&amp;rsquo;re using Boot2Docker with a large number of images, or the images you&amp;rsquo;re
working with are very large, your pulls might start failing with &amp;ldquo;no space left
on device&amp;rdquo; errors when the Boot2Docker volume fills up. There are two solutions
you can try.&lt;/p&gt;
&lt;h2 id=&#34;solution-1-add-the-diskimage-property-in-boot2docker-profile&#34;&gt;Solution 1: Add the &lt;code&gt;DiskImage&lt;/code&gt; property in boot2docker profile&lt;/h2&gt;
&lt;p&gt;The &lt;code&gt;boot2docker&lt;/code&gt; command reads its configuration from the &lt;code&gt;$BOOT2DOCKER_PROFILE&lt;/code&gt; if set, or &lt;code&gt;$BOOT2DOCKER_DIR/profile&lt;/code&gt; or &lt;code&gt;$HOME/.boot2docker/profile&lt;/code&gt; (on Windows this is &lt;code&gt;%USERPROFILE%/.boot2docker/profile&lt;/code&gt;).&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;View the existing configuration, use the &lt;code&gt;boot2docker config&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ boot2docker config
# boot2docker profile filename: /Users/mary/.boot2docker/profile
Init = false
Verbose = false
Driver = &amp;quot;virtualbox&amp;quot;
Clobber = true
ForceUpgradeDownload = false
SSH = &amp;quot;ssh&amp;quot;
SSHGen = &amp;quot;ssh-keygen&amp;quot;
SSHKey = &amp;quot;/Users/mary/.ssh/id_boot2docker&amp;quot;
VM = &amp;quot;boot2docker-vm&amp;quot;
Dir = &amp;quot;/Users/mary/.boot2docker&amp;quot;
ISOURL = &amp;quot;https://api.github.com/repos/boot2docker/boot2docker/releases&amp;quot;
ISO = &amp;quot;/Users/mary/.boot2docker/boot2docker.iso&amp;quot;
DiskSize = 20000
Memory = 2048
CPUs = 8
SSHPort = 2022
DockerPort = 0
HostIP = &amp;quot;192.168.59.3&amp;quot;
DHCPIP = &amp;quot;192.168.59.99&amp;quot;
NetMask = [255, 255, 255, 0]
LowerIP = &amp;quot;192.168.59.103&amp;quot;
UpperIP = &amp;quot;192.168.59.254&amp;quot;
DHCPEnabled = true
Serial = false
SerialFile = &amp;quot;/Users/mary/.boot2docker/boot2docker-vm.sock&amp;quot;
Waittime = 300
Retries = 75
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The configuration shows you where &lt;code&gt;boot2docker&lt;/code&gt; is looking for the &lt;code&gt;profile&lt;/code&gt; file. It also output the settings that are in use.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Initialise a default file to customize using &lt;code&gt;boot2docker config &amp;gt; ~/.boot2docker/profile&lt;/code&gt; command.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the following lines to &lt;code&gt;$HOME/.boot2docker/profile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Disk image size in MB
DiskSize = 50000
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run the following sequence of commands to restart Boot2Docker with the new settings.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ boot2docker poweroff
$ boot2docker destroy
$ boot2docker init
$ boot2docker up
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;solution-2-increase-the-size-of-boot2docker-volume&#34;&gt;Solution 2: Increase the size of boot2docker volume&lt;/h2&gt;
&lt;p&gt;This solution increases the volume size by first cloning it, then resizing it
using a disk partitioning tool. We recommend
&lt;a href=&#34;http://gparted.sourceforge.net/download.php/index.php&#34;&gt;GParted&lt;/a&gt;. The tool comes
as a bootable ISO, is a free download, and works well with VirtualBox.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Stop Boot2Docker&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Issue the command to stop the Boot2Docker VM on the command line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ boot2docker stop
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Clone the VMDK image to a VDI image&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Boot2Docker ships with a VMDK image, which can&amp;rsquo;t be resized by VirtualBox&amp;rsquo;s
native tools. We will instead create a VDI volume and clone the VMDK volume to
it.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Using the command line VirtualBox tools, clone the VMDK image to a VDI image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ vboxmanage clonehd /full/path/to/boot2docker-hd.vmdk /full/path/to/&amp;lt;newVDIimage&amp;gt;.vdi --format VDI --variant Standard
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Resize the VDI volume&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Choose a size that will be appropriate for your needs. If you&amp;rsquo;re spinning up a
lot of containers, or your containers are particularly large, larger will be
better:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt; $ vboxmanage modifyhd /full/path/to/&amp;lt;newVDIimage&amp;gt;.vdi --resize &amp;lt;size in MB&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;ol&gt;
&lt;li&gt;Download a disk partitioning tool ISO&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To resize the volume, we&amp;rsquo;ll use &lt;a href=&#34;http://gparted.sourceforge.net/download.php/&#34;&gt;GParted&lt;/a&gt;.
Once you&amp;rsquo;ve downloaded the tool, add the ISO to the Boot2Docker VM IDE bus.
You might need to create the bus before you can add the ISO.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
It&amp;rsquo;s important that you choose a partitioning tool that is available as an ISO so
that the Boot2Docker VM can be booted with it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;table&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/add_new_controller.png&#34;&gt;&lt;br&gt;&lt;br&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/add_cd.png&#34;&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/table&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add the new VDI image&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;In the settings for the Boot2Docker image in VirtualBox, remove the VMDK image
from the SATA controller and add the VDI image.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/add_volume.png&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Verify the boot order&lt;/p&gt;
&lt;p&gt;In the &lt;strong&gt;System&lt;/strong&gt; settings for the Boot2Docker VM, make sure that &lt;strong&gt;CD/DVD&lt;/strong&gt; is
at the top of the &lt;strong&gt;Boot Order&lt;/strong&gt; list.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/boot_order.png&#34;&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Boot to the disk partitioning ISO&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Manually start the Boot2Docker VM in VirtualBox, and the disk partitioning ISO
should start up. Using GParted, choose the &lt;strong&gt;GParted Live (default settings)&lt;/strong&gt;
option. Choose the default keyboard, language, and XWindows settings, and the
GParted tool will start up and display the VDI volume you created. Right click
on the VDI and choose &lt;strong&gt;Resize/Move&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/gparted.png&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Drag the slider representing the volume to the maximum available size.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Click &lt;strong&gt;Resize/Move&lt;/strong&gt; followed by &lt;strong&gt;Apply&lt;/strong&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/gparted2.png&#34;&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Quit GParted and shut down the VM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remove the GParted ISO from the IDE controller for the Boot2Docker VM in
VirtualBox.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Start the Boot2Docker VM&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Fire up the Boot2Docker VM manually in VirtualBox. The VM should log in
automatically, but if it doesn&amp;rsquo;t, the credentials are &lt;code&gt;docker/tcuser&lt;/code&gt;. Using
the &lt;code&gt;df -h&lt;/code&gt; command, verify that your changes took effect.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/b2d_volume_images/verify.png&#34;&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re done!&lt;/p&gt;
</description>
</item>
<item>
<title>Get started with containers</title>
<link>http://localhost/articles/basics/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/basics/</guid>
<description>
&lt;h1 id=&#34;get-started-with-containers&#34;&gt;Get started with containers&lt;/h1&gt;
&lt;p&gt;This guide assumes you have a working installation of Docker. To check
your Docker install, run the following command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Check that you have a working install
$ docker info
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you get &lt;code&gt;docker: command not found&lt;/code&gt; or something like
&lt;code&gt;/var/lib/docker/repositories: permission denied&lt;/code&gt; you may have an
incomplete Docker installation or insufficient privileges to access
Docker on your machine. Please&lt;/p&gt;
&lt;p&gt;Additionally, depending on your Docker system configuration, you may be required
to preface each &lt;code&gt;docker&lt;/code&gt; command with &lt;code&gt;sudo&lt;/code&gt;. To avoid having to use &lt;code&gt;sudo&lt;/code&gt; with
the &lt;code&gt;docker&lt;/code&gt; command, your system administrator can create a Unix group called
&lt;code&gt;docker&lt;/code&gt; and add users to it.&lt;/p&gt;
&lt;p&gt;For more information about installing Docker or &lt;code&gt;sudo&lt;/code&gt; configuration, refer to
the &lt;a href=&#34;http://localhost/articles/articles/installation&#34;&gt;installation&lt;/a&gt; instructions for your operating system.&lt;/p&gt;
&lt;h2 id=&#34;download-a-pre-built-image&#34;&gt;Download a pre-built image&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Download an ubuntu image
$ docker pull ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will find the &lt;code&gt;ubuntu&lt;/code&gt; image by name on
&lt;a href=&#34;http://localhost/userguide/dockerrepos/#searching-for-images&#34;&gt;&lt;em&gt;Docker Hub&lt;/em&gt;&lt;/a&gt;
and download it from &lt;a href=&#34;https://hub.docker.com&#34;&gt;Docker Hub&lt;/a&gt; to a local
image cache.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
When the image has successfully downloaded, you will see a 12 character
hash &lt;code&gt;539c0211cd76: Download complete&lt;/code&gt; which is the
short form of the image ID. These short image IDs are the first 12
characters of the full image ID - which can be found using
&lt;code&gt;docker inspect&lt;/code&gt; or &lt;code&gt;docker images --no-trunc=true&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; if you are using a remote Docker daemon, such as Boot2Docker,
then &lt;em&gt;do not&lt;/em&gt; type the &lt;code&gt;sudo&lt;/code&gt; before the &lt;code&gt;docker&lt;/code&gt; commands shown in the
documentation&amp;rsquo;s examples.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;running-an-interactive-shell&#34;&gt;Running an interactive shell&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Run an interactive shell in the ubuntu image,
# allocate a tty, attach stdin and stdout
# To detach the tty without exiting the shell,
# use the escape sequence Ctrl-p + Ctrl-q
# note: This will continue to exist in a stopped state once exited (see &amp;quot;docker ps -a&amp;quot;)
$ docker run -i -t ubuntu /bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;bind-docker-to-another-host-port-or-a-unix-socket&#34;&gt;Bind Docker to another host/port or a Unix socket&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;:
Changing the default &lt;code&gt;docker&lt;/code&gt; daemon binding to a
TCP port or Unix &lt;em&gt;docker&lt;/em&gt; user group will increase your security risks
by allowing non-root users to gain &lt;em&gt;root&lt;/em&gt; access on the host. Make sure
you control access to &lt;code&gt;docker&lt;/code&gt;. If you are binding
to a TCP port, anyone with access to that port has full Docker access;
so it is not advisable on an open network.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;With &lt;code&gt;-H&lt;/code&gt; it is possible to make the Docker daemon to listen on a
specific IP and port. By default, it will listen on
&lt;code&gt;unix:///var/run/docker.sock&lt;/code&gt; to allow only local connections by the
&lt;em&gt;root&lt;/em&gt; user. You &lt;em&gt;could&lt;/em&gt; set it to &lt;code&gt;0.0.0.0:2375&lt;/code&gt; or a specific host IP
to give access to everybody, but that is &lt;strong&gt;not recommended&lt;/strong&gt; because
then it is trivial for someone to gain root access to the host where the
daemon is running.&lt;/p&gt;
&lt;p&gt;Similarly, the Docker client can use &lt;code&gt;-H&lt;/code&gt; to connect to a custom port.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-H&lt;/code&gt; accepts host and port assignment in the following format:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;tcp://[host][:port]` or `unix://path
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tcp://host:2375&lt;/code&gt; -&amp;gt; TCP connection on
host:2375&lt;/li&gt;
&lt;li&gt;&lt;code&gt;unix://path/to/socket&lt;/code&gt; -&amp;gt; Unix socket located
at &lt;code&gt;path/to/socket&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;-H&lt;/code&gt;, when empty, will default to the same value as
when no &lt;code&gt;-H&lt;/code&gt; was passed in.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;-H&lt;/code&gt; also accepts short form for TCP bindings:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;host[:port]` or `:port
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run Docker in daemon mode:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo &amp;lt;path to&amp;gt;/docker -H 0.0.0.0:5555 -d &amp;amp;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Download an &lt;code&gt;ubuntu&lt;/code&gt; image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker -H :5555 pull ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can use multiple &lt;code&gt;-H&lt;/code&gt;, for example, if you want to listen on both
TCP and a Unix socket&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Run docker in daemon mode
$ sudo &amp;lt;path to&amp;gt;/docker -H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock -d &amp;amp;
# Download an ubuntu image, use default Unix socket
$ docker pull ubuntu
# OR use the TCP port
$ docker -H tcp://127.0.0.1:2375 pull ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;starting-a-long-running-worker-process&#34;&gt;Starting a long-running worker process&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Start a very useful long-running process
$ JOB=$(docker run -d ubuntu /bin/sh -c &amp;quot;while true; do echo Hello world; sleep 1; done&amp;quot;)
# Collect the output of the job so far
$ docker logs $JOB
# Kill the job
$ docker kill $JOB
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;listing-containers&#34;&gt;Listing containers&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;$ docker ps # Lists only running containers
$ docker ps -a # Lists all containers
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;controlling-containers&#34;&gt;Controlling containers&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Start a new container
$ JOB=$(docker run -d ubuntu /bin/sh -c &amp;quot;while true; do echo Hello world; sleep 1; done&amp;quot;)
# Stop the container
$ docker stop $JOB
# Start the container
$ docker start $JOB
# Restart the container
$ docker restart $JOB
# SIGKILL a container
$ docker kill $JOB
# Remove a container
$ docker stop $JOB # Container must be stopped to remove it
$ docker rm $JOB
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;bind-a-service-on-a-tcp-port&#34;&gt;Bind a service on a TCP port&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;# Bind port 4444 of this container, and tell netcat to listen on it
$ JOB=$(docker run -d -p 4444 ubuntu:12.10 /bin/nc -l 4444)
# Which public port is NATed to my container?
$ PORT=$(docker port $JOB 4444 | awk -F: &#39;{ print $2 }&#39;)
# Connect to the public port
$ echo hello world | nc 127.0.0.1 $PORT
# Verify that the network connection worked
$ echo &amp;quot;Daemon received: $(docker logs $JOB)&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;committing-saving-a-container-state&#34;&gt;Committing (saving) a container state&lt;/h2&gt;
&lt;p&gt;Save your containers state to an image, so the state can be
re-used.&lt;/p&gt;
&lt;p&gt;When you commit your container only the differences between the image
the container was created from and the current state of the container
will be stored (as a diff). See which images you already have using the
&lt;code&gt;docker images&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Commit your container to a new named image
$ docker commit &amp;lt;container_id&amp;gt; &amp;lt;some_name&amp;gt;
# List your images
$ docker images
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You now have an image state from which you can create new instances.&lt;/p&gt;
&lt;p&gt;Read more about &lt;a href=&#34;http://localhost/userguide/dockerrepos&#34;&gt;&lt;em&gt;Share Images via
Repositories&lt;/em&gt;&lt;/a&gt; or
continue to the complete &lt;a href=&#34;http://localhost/articles/articles/reference/commandline/cli&#34;&gt;&lt;em&gt;Command
Line&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
</description>
</item>
<item>
<title>Create a base image</title>
<link>http://localhost/articles/baseimages/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/baseimages/</guid>
<description>
&lt;h1 id=&#34;create-a-base-image&#34;&gt;Create a base image&lt;/h1&gt;
&lt;p&gt;So you want to create your own &lt;a href=&#34;http://localhost/terms/image/#base-image&#34;&gt;&lt;em&gt;Base Image&lt;/em&gt;&lt;/a&gt;? Great!&lt;/p&gt;
&lt;p&gt;The specific process will depend heavily on the Linux distribution you
want to package. We have some examples below, and you are encouraged to
submit pull requests to contribute new ones.&lt;/p&gt;
&lt;h2 id=&#34;create-a-full-image-using-tar&#34;&gt;Create a full image using tar&lt;/h2&gt;
&lt;p&gt;In general, you&amp;rsquo;ll want to start with a working machine that is running
the distribution you&amp;rsquo;d like to package as a base image, though that is
not required for some tools like Debian&amp;rsquo;s
&lt;a href=&#34;https://wiki.debian.org/Debootstrap&#34;&gt;Debootstrap&lt;/a&gt;, which you can also
use to build Ubuntu images.&lt;/p&gt;
&lt;p&gt;It can be as simple as this to create an Ubuntu base image:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo debootstrap raring raring &amp;gt; /dev/null
$ sudo tar -C raring -c . | docker import - raring
a29c15f1bf7a
$ docker run raring cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=13.04
DISTRIB_CODENAME=raring
DISTRIB_DESCRIPTION=&amp;quot;Ubuntu 13.04&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are more example scripts for creating base images in the Docker
GitHub Repo:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/docker/docker/blob/master/contrib/mkimage-busybox.sh&#34;&gt;BusyBox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;CentOS / Scientific Linux CERN (SLC) &lt;a href=&#34;https://github.com/docker/docker/blob/master/contrib/mkimage-rinse.sh&#34;&gt;on Debian/Ubuntu&lt;/a&gt; or
&lt;a href=&#34;https://github.com/docker/docker/blob/master/contrib/mkimage-yum.sh&#34;&gt;on CentOS/RHEL/SLC/etc.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/docker/docker/blob/master/contrib/mkimage-debootstrap.sh&#34;&gt;Debian / Ubuntu&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;creating-a-simple-base-image-using-scratch&#34;&gt;Creating a simple base image using &lt;code&gt;scratch&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;There is a special repository in the Docker registry called &lt;code&gt;scratch&lt;/code&gt;, which
was created using an empty tar file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tar cv --files-from /dev/null | docker import - scratch
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;which you can &lt;code&gt;docker pull&lt;/code&gt;. You can then use that
image to base your new minimal containers &lt;code&gt;FROM&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM scratch
COPY true-asm /true
CMD [&amp;quot;/true&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;Dockerfile&lt;/code&gt; above is from an extremely minimal image - &lt;a href=&#34;https://github.com/tianon/dockerfiles/tree/master/true&#34;&gt;tianon/true&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;more-resources&#34;&gt;More resources&lt;/h2&gt;
&lt;p&gt;There are lots more resources available to help you write your &amp;lsquo;Dockerfile`.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There&amp;rsquo;s a &lt;a href=&#34;http://localhost/articles/articles/reference/builder/&#34;&gt;complete guide to all the instructions&lt;/a&gt; available for use in a &lt;code&gt;Dockerfile&lt;/code&gt; in the reference section.&lt;/li&gt;
&lt;li&gt;To help you write a clear, readable, maintainable &lt;code&gt;Dockerfile&lt;/code&gt;, we&amp;rsquo;ve also
written a &lt;a href=&#34;http://localhost/articles/articles/articles/dockerfile_best-practices&#34;&gt;&lt;code&gt;Dockerfile&lt;/code&gt; Best Practices guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;If your goal is to create a new Official Repository, be sure to read up on Docker&amp;rsquo;s &lt;a href=&#34;http://localhost/articles/articles/docker-hub/official_repos/&#34;&gt;Official Repositories&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
</item>
<item>
<title>Using Chef</title>
<link>http://localhost/articles/chef/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/chef/</guid>
<description>
&lt;h1 id=&#34;using-chef&#34;&gt;Using Chef&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
Please note this is a community contributed installation path. The only
&lt;code&gt;official&lt;/code&gt; installation is using the
&lt;a href=&#34;http://localhost/articles/articles/installation/ubuntulinux&#34;&gt;&lt;em&gt;Ubuntu&lt;/em&gt;&lt;/a&gt; installation
path. This version may sometimes be out of date.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;To use this guide you&amp;rsquo;ll need a working installation of
&lt;a href=&#34;http://www.getchef.com/&#34;&gt;Chef&lt;/a&gt;. This cookbook supports a variety of
operating systems.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;The cookbook is available on the &lt;a href=&#34;http://community.opscode.com/cookbooks/docker&#34;&gt;Chef Community
Site&lt;/a&gt; and can be
installed using your favorite cookbook dependency manager.&lt;/p&gt;
&lt;p&gt;The source can be found on
&lt;a href=&#34;https://github.com/bflad/chef-docker&#34;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;The cookbook provides recipes for installing Docker, configuring init
for Docker, and resources for managing images and containers. It
supports almost all Docker functionality.&lt;/p&gt;
&lt;h3 id=&#34;installation-1&#34;&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;include_recipe &#39;docker&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;images&#34;&gt;Images&lt;/h3&gt;
&lt;p&gt;The next step is to pull a Docker image. For this, we have a resource:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker_image &#39;samalba/docker-registry&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is equivalent to running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker pull samalba/docker-registry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are attributes available to control how long the cookbook will
allow for downloading (5 minute default).&lt;/p&gt;
&lt;p&gt;To remove images you no longer need:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker_image &#39;samalba/docker-registry&#39; do
action :remove
end
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;containers&#34;&gt;Containers&lt;/h3&gt;
&lt;p&gt;Now you have an image where you can run commands within a container
managed by Docker.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker_container &#39;samalba/docker-registry&#39; do
detach true
port &#39;5000:5000&#39;
env &#39;SETTINGS_FLAVOR=local&#39;
volume &#39;/mnt/docker:/docker-storage&#39;
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is equivalent to running the following command, but under upstart:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run --detach=true --publish=&#39;5000:5000&#39; --env=&#39;SETTINGS_FLAVOR=local&#39; --volume=&#39;/mnt/docker:/docker-storage&#39; samalba/docker-registry
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The resources will accept a single string or an array of values for any
Docker flags that allow multiple values.&lt;/p&gt;
</description>
</item>
<item>
<title>Using certificates for repository client verification</title>
<link>http://localhost/articles/certificates/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/certificates/</guid>
<description>
&lt;h1 id=&#34;using-certificates-for-repository-client-verification&#34;&gt;Using certificates for repository client verification&lt;/h1&gt;
&lt;p&gt;In &lt;a href=&#34;http://localhost/articles/articles/articles/https&#34;&gt;Running Docker with HTTPS&lt;/a&gt;, you learned that, by default,
Docker runs via a non-networked Unix socket and TLS must be enabled in order
to have the Docker client and the daemon communicate securely over HTTPS.&lt;/p&gt;
&lt;p&gt;Now, you will see how to allow the Docker registry (i.e., &lt;em&gt;a server&lt;/em&gt;) to
verify that the Docker daemon (i.e., &lt;em&gt;a client&lt;/em&gt;) has the right to access the
images being hosted with &lt;em&gt;certificate-based client-server authentication&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;We will show you how to install a Certificate Authority (CA) root certificate
for the registry and how to set the client TLS certificate for verification.&lt;/p&gt;
&lt;h2 id=&#34;understanding-the-configuration&#34;&gt;Understanding the configuration&lt;/h2&gt;
&lt;p&gt;A custom certificate is configured by creating a directory under
&lt;code&gt;/etc/docker/certs.d&lt;/code&gt; using the same name as the registry&amp;rsquo;s hostname (e.g.,
&lt;code&gt;localhost&lt;/code&gt;). All &lt;code&gt;*.crt&lt;/code&gt; files are added to this directory as CA roots.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
In the absence of any root certificate authorities, Docker
will use the system default (i.e., host&amp;rsquo;s root CA set).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The presence of one or more &lt;code&gt;&amp;lt;filename&amp;gt;.key/cert&lt;/code&gt; pairs indicates to Docker
that there are custom certificates required for access to the desired
repository.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
If there are multiple certificates, each will be tried in alphabetical
order. If there is an authentication error (e.g., 403, 404, 5xx, etc.), Docker
will continue to try with the next certificate.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Our example is set up like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;/etc/docker/certs.d/ &amp;lt;-- Certificate directory
└── localhost &amp;lt;-- Hostname
├── client.cert &amp;lt;-- Client certificate
├── client.key &amp;lt;-- Client key
└── localhost.crt &amp;lt;-- Registry certificate
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;creating-the-client-certificates&#34;&gt;Creating the client certificates&lt;/h2&gt;
&lt;p&gt;You will use OpenSSL&amp;rsquo;s &lt;code&gt;genrsa&lt;/code&gt; and &lt;code&gt;req&lt;/code&gt; commands to first generate an RSA
key and then use the key to create the certificate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl genrsa -out client.key 1024
$ openssl req -new -x509 -text -key client.key -out client.cert
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt;:
Using TLS and managing a CA is an advanced topic.
You should be familiar with OpenSSL, x509, and TLS before
attempting to use them in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning:&lt;/strong&gt;
These TLS commands will only generate a working set of certificates on Linux.
The version of OpenSSL in Mac OS X is incompatible with the type of
certificate Docker requires.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;testing-the-verification-setup&#34;&gt;Testing the verification setup&lt;/h2&gt;
&lt;p&gt;You can test this setup by using Apache to host a Docker registry.
For this purpose, you can copy a registry tree (containing images) inside
the Apache root.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
You can find such an example &lt;a href=&#34;http://people.gnome.org/~alexl/v1.tar.gz&#34;&gt;here&lt;/a&gt; - which contains the busybox image.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Once you set up the registry, you can use the following Apache configuration
to implement certificate-based protection.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# This must be in the root context, otherwise it causes a re-negotiation
# which is not supported by the TLS implementation in go
SSLVerifyClient optional_no_ca
&amp;lt;Location /v1&amp;gt;
Action cert-protected /cgi-bin/cert.cgi
SetHandler cert-protected
Header set x-docker-registry-version &amp;quot;0.6.2&amp;quot;
SetEnvIf Host (.*) custom_host=$1
Header set X-Docker-Endpoints &amp;quot;%{custom_host}e&amp;quot;
&amp;lt;/Location&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Save the above content as &lt;code&gt;/etc/httpd/conf.d/registry.conf&lt;/code&gt;, and
continue with creating a &lt;code&gt;cert.cgi&lt;/code&gt; file under &lt;code&gt;/var/www/cgi-bin/&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash
if [ &amp;quot;$HTTPS&amp;quot; != &amp;quot;on&amp;quot; ]; then
echo &amp;quot;Status: 403 Not using SSL&amp;quot;
echo &amp;quot;x-docker-registry-version: 0.6.2&amp;quot;
echo
exit 0
fi
if [ &amp;quot;$SSL_CLIENT_VERIFY&amp;quot; == &amp;quot;NONE&amp;quot; ]; then
echo &amp;quot;Status: 403 Client certificate invalid&amp;quot;
echo &amp;quot;x-docker-registry-version: 0.6.2&amp;quot;
echo
exit 0
fi
echo &amp;quot;Content-length: $(stat --printf=&#39;%s&#39; $PATH_TRANSLATED)&amp;quot;
echo &amp;quot;x-docker-registry-version: 0.6.2&amp;quot;
echo &amp;quot;X-Docker-Endpoints: $SERVER_NAME&amp;quot;
echo &amp;quot;X-Docker-Size: 0&amp;quot;
echo
cat $PATH_TRANSLATED
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This CGI script will ensure that all requests to &lt;code&gt;/v1&lt;/code&gt; &lt;em&gt;without&lt;/em&gt; a valid
certificate will be returned with a &lt;code&gt;403&lt;/code&gt; (i.e., HTTP forbidden) error.&lt;/p&gt;
</description>
</item>
<item>
<title>Process management with CFEngine</title>
<link>http://localhost/articles/cfengine_process_management/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/cfengine_process_management/</guid>
<description>
&lt;h1 id=&#34;process-management-with-cfengine&#34;&gt;Process management with CFEngine&lt;/h1&gt;
&lt;p&gt;Create Docker containers with managed processes.&lt;/p&gt;
&lt;p&gt;Docker monitors one process in each running container and the container
lives or dies with that process. By introducing CFEngine inside Docker
containers, we can alleviate a few of the issues that may arise:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It is possible to easily start multiple processes within a
container, all of which will be managed automatically, with the
normal &lt;code&gt;docker run&lt;/code&gt; command.&lt;/li&gt;
&lt;li&gt;If a managed process dies or crashes, CFEngine will start it again
within 1 minute.&lt;/li&gt;
&lt;li&gt;The container itself will live as long as the CFEngine scheduling
daemon (cf-execd) lives. With CFEngine, we are able to decouple the
life of the container from the uptime of the service it provides.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-it-works&#34;&gt;How it works&lt;/h2&gt;
&lt;p&gt;CFEngine, together with the cfe-docker integration policies, are
installed as part of the Dockerfile. This builds CFEngine into our
Docker image.&lt;/p&gt;
&lt;p&gt;The Dockerfile&amp;rsquo;s &lt;code&gt;ENTRYPOINT&lt;/code&gt; takes an arbitrary
amount of commands (with any desired arguments) as parameters. When we
run the Docker container these parameters get written to CFEngine
policies and CFEngine takes over to ensure that the desired processes
are running in the container.&lt;/p&gt;
&lt;p&gt;CFEngine scans the process table for the &lt;code&gt;basename&lt;/code&gt; of the commands given
to the &lt;code&gt;ENTRYPOINT&lt;/code&gt; and runs the command to start the process if the &lt;code&gt;basename&lt;/code&gt;
is not found. For example, if we start the container with
&lt;code&gt;docker run &amp;quot;/path/to/my/application parameters&amp;quot;&lt;/code&gt;, CFEngine will look for a
process named &lt;code&gt;application&lt;/code&gt; and run the command. If an entry for &lt;code&gt;application&lt;/code&gt;
is not found in the process table at any point in time, CFEngine will execute
&lt;code&gt;/path/to/my/application parameters&lt;/code&gt; to start the application once again. The
check on the process table happens every minute.&lt;/p&gt;
&lt;p&gt;Note that it is therefore important that the command to start your
application leaves a process with the basename of the command. This can
be made more flexible by making some minor adjustments to the CFEngine
policies, if desired.&lt;/p&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;This example assumes you have Docker installed and working. We will
install and manage &lt;code&gt;apache2&lt;/code&gt; and &lt;code&gt;sshd&lt;/code&gt;
in a single container.&lt;/p&gt;
&lt;p&gt;There are three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install CFEngine into the container.&lt;/li&gt;
&lt;li&gt;Copy the CFEngine Docker process management policy into the
containerized CFEngine installation.&lt;/li&gt;
&lt;li&gt;Start your application processes as part of the &lt;code&gt;docker run&lt;/code&gt; command.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;building-the-image&#34;&gt;Building the image&lt;/h3&gt;
&lt;p&gt;The first two steps can be done as part of a Dockerfile, as follows.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;FROM ubuntu
MAINTAINER Eystein Måløy Stenberg &amp;lt;eytein.stenberg@gmail.com&amp;gt;
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y wget lsb-release unzip ca-certificates
# install latest CFEngine
RUN wget -qO- http://cfengine.com/pub/gpg.key | apt-key add -
RUN echo &amp;quot;deb http://cfengine.com/pub/apt $(lsb_release -cs) main&amp;quot; &amp;gt; /etc/apt/sources.list.d/cfengine-community.list
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y cfengine-community
# install cfe-docker process management policy
RUN wget https://github.com/estenberg/cfe-docker/archive/master.zip -P /tmp/ &amp;amp;&amp;amp; unzip /tmp/master.zip -d /tmp/
RUN cp /tmp/cfe-docker-master/cfengine/bin/* /var/cfengine/bin/
RUN cp /tmp/cfe-docker-master/cfengine/inputs/* /var/cfengine/inputs/
RUN rm -rf /tmp/cfe-docker-master /tmp/master.zip
# apache2 and openssh are just for testing purposes, install your own apps here
RUN apt-get update &amp;amp;&amp;amp; apt-get install -y openssh-server apache2
RUN mkdir -p /var/run/sshd
RUN echo &amp;quot;root:password&amp;quot; | chpasswd # need a password for ssh
ENTRYPOINT [&amp;quot;/var/cfengine/bin/docker_processes_run.sh&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;By saving this file as Dockerfile to a working directory, you can then build
your image with the docker build command, e.g.,
&lt;code&gt;docker build -t managed_image&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;testing-the-container&#34;&gt;Testing the container&lt;/h3&gt;
&lt;p&gt;Start the container with &lt;code&gt;apache2&lt;/code&gt; and &lt;code&gt;sshd&lt;/code&gt; running and managed, forwarding
a port to our SSH instance:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run -p 127.0.0.1:222:22 -d managed_image &amp;quot;/usr/sbin/sshd&amp;quot; &amp;quot;/etc/init.d/apache2 start&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We now clearly see one of the benefits of the cfe-docker integration: it
allows to start several processes as part of a normal &lt;code&gt;docker run&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;We can now log in to our new container and see that both &lt;code&gt;apache2&lt;/code&gt; and &lt;code&gt;sshd&lt;/code&gt;
are running. We have set the root password to &amp;ldquo;password&amp;rdquo; in the Dockerfile
above and can use that to log in with ssh:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ssh -p222 root@127.0.0.1
ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 07:48 ? 00:00:00 /bin/bash /var/cfengine/bin/docker_processes_run.sh /usr/sbin/sshd /etc/init.d/apache2 start
root 18 1 0 07:48 ? 00:00:00 /var/cfengine/bin/cf-execd -F
root 20 1 0 07:48 ? 00:00:00 /usr/sbin/sshd
root 32 1 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 34 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 35 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
www-data 36 32 0 07:48 ? 00:00:00 /usr/sbin/apache2 -k start
root 93 20 0 07:48 ? 00:00:00 sshd: root@pts/0
root 105 93 0 07:48 pts/0 00:00:00 -bash
root 112 105 0 07:49 pts/0 00:00:00 ps -ef
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If we stop apache2, it will be started again within a minute by
CFEngine.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service apache2 status
Apache2 is running (pid 32).
service apache2 stop
* Stopping web server apache2 ... waiting [ OK ]
service apache2 status
Apache2 is NOT running.
# ... wait up to 1 minute...
service apache2 status
Apache2 is running (pid 173).
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;adapting-to-your-applications&#34;&gt;Adapting to your applications&lt;/h2&gt;
&lt;p&gt;To make sure your applications get managed in the same manner, there are
just two things you need to adjust from the above example:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In the Dockerfile used above, install your applications instead of
&lt;code&gt;apache2&lt;/code&gt; and &lt;code&gt;sshd&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;When you start the container with &lt;code&gt;docker run&lt;/code&gt;,
specify the command line arguments to your applications rather than
&lt;code&gt;apache2&lt;/code&gt; and &lt;code&gt;sshd&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
</description>
</item>
<item>
<title>Best practices for writing Dockerfiles</title>
<link>http://localhost/articles/dockerfile_best-practices/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/dockerfile_best-practices/</guid>
<description>
&lt;h1 id=&#34;best-practices-for-writing-dockerfiles&#34;&gt;Best practices for writing Dockerfiles&lt;/h1&gt;
&lt;h2 id=&#34;overview&#34;&gt;Overview&lt;/h2&gt;
&lt;p&gt;Docker can build images automatically by reading the instructions from a
&lt;code&gt;Dockerfile&lt;/code&gt;, a text file that contains all the commands, in order, needed to
build a given image. &lt;code&gt;Dockerfile&lt;/code&gt;s adhere to a specific format and use a
specific set of instructions. You can learn the basics on the
&lt;a href=&#34;https://docs.docker.com/reference/builder/&#34;&gt;Dockerfile Reference&lt;/a&gt; page. If
youre new to writing &lt;code&gt;Dockerfile&lt;/code&gt;s, you should start there.&lt;/p&gt;
&lt;p&gt;This document covers the best practices and methods recommended by Docker,
Inc. and the Docker community for creating easy-to-use, effective
&lt;code&gt;Dockerfile&lt;/code&gt;s. We strongly suggest you follow these recommendations (in fact,
if youre creating an Official Image, you &lt;em&gt;must&lt;/em&gt; adhere to these practices).&lt;/p&gt;
&lt;p&gt;You can see many of these practices and recommendations in action in the &lt;a href=&#34;https://github.com/docker-library/buildpack-deps/blob/master/jessie/Dockerfile&#34;&gt;buildpack-deps &lt;code&gt;Dockerfile&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: for more detailed explanations of any of the Dockerfile commands
mentioned here, visit the &lt;a href=&#34;https://docs.docker.com/reference/builder/&#34;&gt;Dockerfile Reference&lt;/a&gt; page.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;general-guidelines-and-recommendations&#34;&gt;General guidelines and recommendations&lt;/h2&gt;
&lt;h3 id=&#34;containers-should-be-ephemeral&#34;&gt;Containers should be ephemeral&lt;/h3&gt;
&lt;p&gt;The container produced by the image your &lt;code&gt;Dockerfile&lt;/code&gt; defines should be as
ephemeral as possible. By “ephemeral,” we mean that it can be stopped and
destroyed and a new one built and put in place with an absolute minimum of
set-up and configuration.&lt;/p&gt;
&lt;h3 id=&#34;use-a-dockerignore-file&#34;&gt;Use a .dockerignore file&lt;/h3&gt;
&lt;p&gt;In most cases, it&amp;rsquo;s best to put each Dockerfile in an empty directory. Then,
add to that directory only the files needed for building the Dockerfile. To
increase the build&amp;rsquo;s performance, you can exclude files and directories by
adding a &lt;code&gt;.dockerignore&lt;/code&gt; file to that directory as well. This file supports
exclusion patterns similar to &lt;code&gt;.gitignore&lt;/code&gt; files. For information on creating one,
see the &lt;a href=&#34;http://localhost/articles/articles/reference/builder/#dockerignore-file&#34;&gt;.dockerignore file&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;avoid-installing-unnecessary-packages&#34;&gt;Avoid installing unnecessary packages&lt;/h3&gt;
&lt;p&gt;In order to reduce complexity, dependencies, file sizes, and build times, you
should avoid installing extra or unnecessary packages just because they
might be “nice to have.” For example, you dont need to include a text editor
in a database image.&lt;/p&gt;
&lt;h3 id=&#34;run-only-one-process-per-container&#34;&gt;Run only one process per container&lt;/h3&gt;
&lt;p&gt;In almost all cases, you should only run a single process in a single
container. Decoupling applications into multiple containers makes it much
easier to scale horizontally and reuse containers. If that service depends on
another service, make use of &lt;a href=&#34;https://docs.docker.com/userguide/dockerlinks/&#34;&gt;container linking&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;minimize-the-number-of-layers&#34;&gt;Minimize the number of layers&lt;/h3&gt;
&lt;p&gt;You need to find the balance between readability (and thus long-term
maintainability) of the &lt;code&gt;Dockerfile&lt;/code&gt; and minimizing the number of layers it
uses. Be strategic and cautious about the number of layers you use.&lt;/p&gt;
&lt;h3 id=&#34;sort-multi-line-arguments&#34;&gt;Sort multi-line arguments&lt;/h3&gt;
&lt;p&gt;Whenever possible, ease later changes by sorting multi-line arguments
alphanumerically. This will help you avoid duplication of packages and make the
list much easier to update. This also makes PRs a lot easier to read and
review. Adding a space before a backslash (&lt;code&gt;\&lt;/code&gt;) helps as well.&lt;/p&gt;
&lt;p&gt;Heres an example from the &lt;a href=&#34;https://github.com/docker-library/buildpack-deps&#34;&gt;&lt;code&gt;buildpack-deps&lt;/code&gt; image&lt;/a&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
bzr \
cvs \
git \
mercurial \
subversion
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;build-cache&#34;&gt;Build cache&lt;/h3&gt;
&lt;p&gt;During the process of building an image Docker will step through the
instructions in your &lt;code&gt;Dockerfile&lt;/code&gt; executing each in the order specified.
As each instruction is examined Docker will look for an existing image in its
cache that it can reuse, rather than creating a new (duplicate) image.
If you do not want to use the cache at all you can use the &lt;code&gt;--no-cache=true&lt;/code&gt;
option on the &lt;code&gt;docker build&lt;/code&gt; command.&lt;/p&gt;
&lt;p&gt;However, if you do let Docker use its cache then it is very important to
understand when it will, and will not, find a matching image. The basic rules
that Docker will follow are outlined below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Starting with a base image that is already in the cache, the next
instruction is compared against all child images derived from that base
image to see if one of them was built using the exact same instruction. If
not, the cache is invalidated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In most cases simply comparing the instruction in the &lt;code&gt;Dockerfile&lt;/code&gt; with one
of the child images is sufficient. However, certain instructions require
a little more examination and explanation.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;In the case of the &lt;code&gt;ADD&lt;/code&gt; and &lt;code&gt;COPY&lt;/code&gt; instructions, the contents of the file(s)
being put into the image are examined. Specifically, a checksum is done
of the file(s) and then that checksum is used during the cache lookup.
If anything has changed in the file(s), including its metadata,
then the cache is invalidated.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Aside from the &lt;code&gt;ADD&lt;/code&gt; and &lt;code&gt;COPY&lt;/code&gt; commands cache checking will not look at the
files in the container to determine a cache match. For example, when processing
a &lt;code&gt;RUN apt-get -y update&lt;/code&gt; command the files updated in the container
will not be examined to determine if a cache hit exists. In that case just
the command string itself will be used to find a match.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once the cache is invalidated, all subsequent &lt;code&gt;Dockerfile&lt;/code&gt; commands will
generate new images and the cache will not be used.&lt;/p&gt;
&lt;h2 id=&#34;the-dockerfile-instructions&#34;&gt;The Dockerfile instructions&lt;/h2&gt;
&lt;p&gt;Below you&amp;rsquo;ll find recommendations for the best way to write the
various instructions available for use in a &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;from-https-docs-docker-com-reference-builder-from&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#from&#34;&gt;&lt;code&gt;FROM&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Whenever possible, use current Official Repositories as the basis for your
image. We recommend the &lt;a href=&#34;https://registry.hub.docker.com/_/debian/&#34;&gt;Debian image&lt;/a&gt;
since its very tightly controlled and kept extremely minimal (currently under
100 mb), while still being a full distribution.&lt;/p&gt;
&lt;h3 id=&#34;run-https-docs-docker-com-reference-builder-run&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#run&#34;&gt;&lt;code&gt;RUN&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;As always, to make your &lt;code&gt;Dockerfile&lt;/code&gt; more readable, understandable, and
maintainable, put long or complex &lt;code&gt;RUN&lt;/code&gt; statements on multiple lines separated
with backslashes.&lt;/p&gt;
&lt;p&gt;Probably the most common use-case for &lt;code&gt;RUN&lt;/code&gt; is an application of &lt;code&gt;apt-get&lt;/code&gt;.
When using &lt;code&gt;apt-get&lt;/code&gt;, here are a few things to keep in mind:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Dont do &lt;code&gt;RUN apt-get update&lt;/code&gt; on a single line. This will cause
caching issues if the referenced archive gets updated, which will make your
subsequent &lt;code&gt;apt-get install&lt;/code&gt; fail without comment.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Avoid &lt;code&gt;RUN apt-get upgrade&lt;/code&gt; or &lt;code&gt;dist-upgrade&lt;/code&gt;, since many of the “essential”
packages from the base images will fail to upgrade inside an unprivileged
container. If a base package is out of date, you should contact its
maintainers. If you know theres a particular package, &lt;code&gt;foo&lt;/code&gt;, that needs to be
updated, use &lt;code&gt;apt-get install -y foo&lt;/code&gt; and it will update automatically.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do write instructions like:&lt;/p&gt;
&lt;p&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y package-bar package-foo package-baz&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Writing the instruction this way not only makes it easier to read
and maintain, but also, by including &lt;code&gt;apt-get update&lt;/code&gt;, ensures that the cache
will naturally be busted and the latest versions will be installed with no
further coding or manual intervention required.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Further natural cache-busting can be realized by version-pinning packages
(e.g., &lt;code&gt;package-foo=1.3.*&lt;/code&gt;). This will force retrieval of that version
regardless of whats in the cache.
Writing your &lt;code&gt;apt-get&lt;/code&gt; code this way will greatly ease maintenance and reduce
failures due to unanticipated changes in required packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;example&#34;&gt;Example&lt;/h4&gt;
&lt;p&gt;Below is a well-formed &lt;code&gt;RUN&lt;/code&gt; instruction that demonstrates the above
recommendations. Note that the last package, &lt;code&gt;s3cmd&lt;/code&gt;, specifies a version
&lt;code&gt;1.1.0*&lt;/code&gt;. If the image previously used an older version, specifying the new one
will cause a cache bust of &lt;code&gt;apt-get update&lt;/code&gt; and ensure the installation of
the new version (which in this case had a new, required feature).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN apt-get update &amp;amp;&amp;amp; apt-get install -y \
aufs-tools \
automake \
btrfs-tools \
build-essential \
curl \
dpkg-sig \
git \
iptables \
libapparmor-dev \
libcap-dev \
libsqlite3-dev \
lxc=1.0* \
mercurial \
parallel \
reprepro \
ruby1.9.1 \
ruby1.9.1-dev \
s3cmd=1.1.0*
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Writing the instruction this way also helps you avoid potential duplication of
a given package because it is much easier to read than an instruction like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN apt-get install -y package-foo &amp;amp;&amp;amp; apt-get install -y package-bar
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;cmd-https-docs-docker-com-reference-builder-cmd&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#cmd&#34;&gt;&lt;code&gt;CMD&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;CMD&lt;/code&gt; instruction should be used to run the software contained by your
image, along with any arguments. &lt;code&gt;CMD&lt;/code&gt; should almost always be used in the
form of &lt;code&gt;CMD [“executable”, “param1”, “param2”…]&lt;/code&gt;. Thus, if the image is for a
service (Apache, Rails, etc.), you would run something like
&lt;code&gt;CMD [&amp;quot;apache2&amp;quot;,&amp;quot;-DFOREGROUND&amp;quot;]&lt;/code&gt;. Indeed, this form of the instruction is
recommended for any service-based image.&lt;/p&gt;
&lt;p&gt;In most other cases, &lt;code&gt;CMD&lt;/code&gt; should be given an interactive shell (bash, python,
perl, etc), for example, &lt;code&gt;CMD [&amp;quot;perl&amp;quot;, &amp;quot;-de0&amp;quot;]&lt;/code&gt;, &lt;code&gt;CMD [&amp;quot;python&amp;quot;]&lt;/code&gt;, or
&lt;code&gt;CMD [“php”, “-a”]&lt;/code&gt;. Using this form means that when you execute something like
&lt;code&gt;docker run -it python&lt;/code&gt;, youll get dropped into a usable shell, ready to go.
&lt;code&gt;CMD&lt;/code&gt; should rarely be used in the manner of &lt;code&gt;CMD [“param”, “param”]&lt;/code&gt; in
conjunction with &lt;a href=&#34;https://docs.docker.com/reference/builder/#entrypoint&#34;&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt;&lt;/a&gt;, unless
you and your expected users are already quite familiar with how &lt;code&gt;ENTRYPOINT&lt;/code&gt;
works.&lt;/p&gt;
&lt;h3 id=&#34;expose-https-docs-docker-com-reference-builder-expose&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#expose&#34;&gt;&lt;code&gt;EXPOSE&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;EXPOSE&lt;/code&gt; instruction indicates the ports on which a container will listen
for connections. Consequently, you should use the common, traditional port for
your application. For example, an image containing the Apache web server would
use &lt;code&gt;EXPOSE 80&lt;/code&gt;, while an image containing MongoDB would use &lt;code&gt;EXPOSE 27017&lt;/code&gt; and
so on.&lt;/p&gt;
&lt;p&gt;For external access, your users can execute &lt;code&gt;docker run&lt;/code&gt; with a flag indicating
how to map the specified port to the port of their choice.
For container linking, Docker provides environment variables for the path from
the recipient container back to the source (ie, &lt;code&gt;MYSQL_PORT_3306_TCP&lt;/code&gt;).&lt;/p&gt;
&lt;h3 id=&#34;env-https-docs-docker-com-reference-builder-env&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#env&#34;&gt;&lt;code&gt;ENV&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;In order to make new software easier to run, you can use &lt;code&gt;ENV&lt;/code&gt; to update the
&lt;code&gt;PATH&lt;/code&gt; environment variable for the software your container installs. For
example, &lt;code&gt;ENV PATH /usr/local/nginx/bin:$PATH&lt;/code&gt; will ensure that &lt;code&gt;CMD [“nginx”]&lt;/code&gt;
just works.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ENV&lt;/code&gt; instruction is also useful for providing required environment
variables specific to services you wish to containerize, such as Postgress
&lt;code&gt;PGDATA&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lastly, &lt;code&gt;ENV&lt;/code&gt; can also be used to set commonly used version numbers so that
version bumps are easier to maintain, as seen in the following example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ENV PG_MAJOR 9.3
ENV PG_VERSION 9.3.4
RUN curl -SL http://example.com/postgres-$PG_VERSION.tar.xz | tar -xJC /usr/src/postgress &amp;amp;&amp;amp; …
ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Similar to having constant variables in a program (as opposed to hard-coding
values), this approach lets you change a single &lt;code&gt;ENV&lt;/code&gt; instruction to
auto-magically bump the version of the software in your container.&lt;/p&gt;
&lt;h3 id=&#34;add-https-docs-docker-com-reference-builder-add-or-copy-https-docs-docker-com-reference-builder-copy&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#add&#34;&gt;&lt;code&gt;ADD&lt;/code&gt;&lt;/a&gt; or &lt;a href=&#34;https://docs.docker.com/reference/builder/#copy&#34;&gt;&lt;code&gt;COPY&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Although &lt;code&gt;ADD&lt;/code&gt; and &lt;code&gt;COPY&lt;/code&gt; are functionally similar, generally speaking, &lt;code&gt;COPY&lt;/code&gt;
is preferred. Thats because its more transparent than &lt;code&gt;ADD&lt;/code&gt;. &lt;code&gt;COPY&lt;/code&gt; only
supports the basic copying of local files into the container, while &lt;code&gt;ADD&lt;/code&gt; has
some features (like local-only tar extraction and remote URL support) that are
not immediately obvious. Consequently, the best use for &lt;code&gt;ADD&lt;/code&gt; is local tar file
auto-extraction into the image, as in &lt;code&gt;ADD rootfs.tar.xz /&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you have multiple &lt;code&gt;Dockerfile&lt;/code&gt; steps that use different files from your
context, &lt;code&gt;COPY&lt;/code&gt; them individually, rather than all at once. This will ensure that
each step&amp;rsquo;s build cache is only invalidated (forcing the step to be re-run) if the
specifically required files change.&lt;/p&gt;
&lt;p&gt;For example:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;COPY requirements.txt /tmp/
RUN pip install /tmp/requirements.txt
COPY . /tmp/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Results in fewer cache invalidations for the &lt;code&gt;RUN&lt;/code&gt; step, than if you put the
&lt;code&gt;COPY . /tmp/&lt;/code&gt; before it.&lt;/p&gt;
&lt;p&gt;Because image size matters, using &lt;code&gt;ADD&lt;/code&gt; to fetch packages from remote URLs is
strongly discouraged; you should use &lt;code&gt;curl&lt;/code&gt; or &lt;code&gt;wget&lt;/code&gt; instead. That way you can
delete the files you no longer need after they&amp;rsquo;ve been extracted and you won&amp;rsquo;t
have to add another layer in your image. For example, you should avoid doing
things like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And instead, do something like:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;RUN mkdir -p /usr/src/things \
&amp;amp;&amp;amp; curl -SL http://example.com/big.tar.gz \
| tar -xJC /usr/src/things \
&amp;amp;&amp;amp; make -C /usr/src/things all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For other items (files, directories) that do not require &lt;code&gt;ADD&lt;/code&gt;s tar
auto-extraction capability, you should always use &lt;code&gt;COPY&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&#34;entrypoint-https-docs-docker-com-reference-builder-entrypoint&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#entrypoint&#34;&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The best use for &lt;code&gt;ENTRYPOINT&lt;/code&gt; is to set the image&amp;rsquo;s main command, allowing that
image to be run as though it was that command (and then use &lt;code&gt;CMD&lt;/code&gt; as the
default flags).&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with an example of an image for the command line tool &lt;code&gt;s3cmd&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ENTRYPOINT [&amp;quot;s3cmd&amp;quot;]
CMD [&amp;quot;--help&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now the image can be run like this to show the command&amp;rsquo;s help:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run s3cmd
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or using the right parameters to execute a command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run s3cmd ls s3://mybucket
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is useful because the image name can double as a reference to the binary as
shown in the command above.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;ENTRYPOINT&lt;/code&gt; instruction can also be used in combination with a helper
script, allowing it to function in a similar way to the command above, even
when starting the tool may require more than one step.&lt;/p&gt;
&lt;p&gt;For example, the &lt;a href=&#34;https://registry.hub.docker.com/_/postgres/&#34;&gt;Postgres Official Image&lt;/a&gt;
uses the following script as its &lt;code&gt;ENTRYPOINT&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-bash&#34;&gt;#!/bin/bash
set -e
if [ &amp;quot;$1&amp;quot; = &#39;postgres&#39; ]; then
chown -R postgres &amp;quot;$PGDATA&amp;quot;
if [ -z &amp;quot;$(ls -A &amp;quot;$PGDATA&amp;quot;)&amp;quot; ]; then
gosu postgres initdb
fi
exec gosu postgres &amp;quot;$@&amp;quot;
fi
exec &amp;quot;$@&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
This script uses &lt;a href=&#34;http://wiki.bash-hackers.org/commands/builtin/exec&#34;&gt;the &lt;code&gt;exec&lt;/code&gt; Bash command&lt;/a&gt;
so that the final running application becomes the container&amp;rsquo;s PID 1. This allows
the application to receive any Unix signals sent to the container.
See the &lt;a href=&#34;https://docs.docker.com/reference/builder/#ENTRYPOINT&#34;&gt;&lt;code&gt;ENTRYPOINT&lt;/code&gt;&lt;/a&gt;
help for more details.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The helper script is copied into the container and run via &lt;code&gt;ENTRYPOINT&lt;/code&gt; on
container start:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;COPY ./docker-entrypoint.sh /
ENTRYPOINT [&amp;quot;/docker-entrypoint.sh&amp;quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This script allows the user to interact with Postgres in several ways.&lt;/p&gt;
&lt;p&gt;It can simply start Postgres:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run postgres
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or, it can be used to run Postgres and pass parameters to the server:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run postgres postgres --help
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Lastly, it could also be used to start a totally different tool, such Bash:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run --rm -it postgres bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;volume-https-docs-docker-com-reference-builder-volume&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#volume&#34;&gt;&lt;code&gt;VOLUME&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;VOLUME&lt;/code&gt; instruction should be used to expose any database storage area,
configuration storage, or files/folders created by your docker container. You
are strongly encouraged to use &lt;code&gt;VOLUME&lt;/code&gt; for any mutable and/or user-serviceable
parts of your image.&lt;/p&gt;
&lt;h3 id=&#34;user-https-docs-docker-com-reference-builder-user&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#user&#34;&gt;&lt;code&gt;USER&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;If a service can run without privileges, use &lt;code&gt;USER&lt;/code&gt; to change to a non-root
user. Start by creating the user and group in the &lt;code&gt;Dockerfile&lt;/code&gt; with something
like &lt;code&gt;RUN groupadd -r postgres &amp;amp;&amp;amp; useradd -r -g postgres postgres&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Users and groups in an image get a non-deterministic
UID/GID in that the “next” UID/GID gets assigned regardless of image
rebuilds. So, if its critical, you should assign an explicit UID/GID.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You should avoid installing or using &lt;code&gt;sudo&lt;/code&gt; since it has unpredictable TTY and
signal-forwarding behavior that can cause more problems than it solves. If
you absolutely need functionality similar to &lt;code&gt;sudo&lt;/code&gt; (e.g., initializing the
daemon as root but running it as non-root), you may be able to use
&lt;a href=&#34;https://github.com/tianon/gosu&#34;&gt;“gosu”&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lastly, to reduce layers and complexity, avoid switching &lt;code&gt;USER&lt;/code&gt; back
and forth frequently.&lt;/p&gt;
&lt;h3 id=&#34;workdir-https-docs-docker-com-reference-builder-workdir&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#workdir&#34;&gt;&lt;code&gt;WORKDIR&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;For clarity and reliability, you should always use absolute paths for your
&lt;code&gt;WORKDIR&lt;/code&gt;. Also, you should use &lt;code&gt;WORKDIR&lt;/code&gt; instead of proliferating
instructions like &lt;code&gt;RUN cd … &amp;amp;&amp;amp; do-something&lt;/code&gt;, which are hard to read,
troubleshoot, and maintain.&lt;/p&gt;
&lt;h3 id=&#34;onbuild-https-docs-docker-com-reference-builder-onbuild&#34;&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#onbuild&#34;&gt;&lt;code&gt;ONBUILD&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;An &lt;code&gt;ONBUILD&lt;/code&gt; command executes after the current &lt;code&gt;Dockerfile&lt;/code&gt; build completes.
&lt;code&gt;ONBUILD&lt;/code&gt; executes in any child image derived &lt;code&gt;FROM&lt;/code&gt; the current image. Think
of the &lt;code&gt;ONBUILD&lt;/code&gt; command as an instruction the parent &lt;code&gt;Dockerfile&lt;/code&gt; gives
to the child &lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;A Docker build executes &lt;code&gt;ONBUILD&lt;/code&gt; commands before any command in a child
&lt;code&gt;Dockerfile&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ONBUILD&lt;/code&gt; is useful for images that are going to be built &lt;code&gt;FROM&lt;/code&gt; a given
image. For example, you would use &lt;code&gt;ONBUILD&lt;/code&gt; for a language stack image that
builds arbitrary user software written in that language within the
&lt;code&gt;Dockerfile&lt;/code&gt;, as you can see in &lt;a href=&#34;https://github.com/docker-library/ruby/blob/master/2.1/onbuild/Dockerfile&#34;&gt;Rubys &lt;code&gt;ONBUILD&lt;/code&gt; variants&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Images built from &lt;code&gt;ONBUILD&lt;/code&gt; should get a separate tag, for example:
&lt;code&gt;ruby:1.9-onbuild&lt;/code&gt; or &lt;code&gt;ruby:2.0-onbuild&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Be careful when putting &lt;code&gt;ADD&lt;/code&gt; or &lt;code&gt;COPY&lt;/code&gt; in &lt;code&gt;ONBUILD&lt;/code&gt;. The “onbuild” image will
fail catastrophically if the new build&amp;rsquo;s context is missing the resource being
added. Adding a separate tag, as recommended above, will help mitigate this by
allowing the &lt;code&gt;Dockerfile&lt;/code&gt; author to make a choice.&lt;/p&gt;
&lt;h2 id=&#34;examples-for-official-repositories&#34;&gt;Examples for Official Repositories&lt;/h2&gt;
&lt;p&gt;These Official Repositories have exemplary &lt;code&gt;Dockerfile&lt;/code&gt;s:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://registry.hub.docker.com/_/golang/&#34;&gt;Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://registry.hub.docker.com/_/perl/&#34;&gt;Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://registry.hub.docker.com/_/hylang/&#34;&gt;Hy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://registry.hub.docker.com/_/rails&#34;&gt;Rails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;additional-resources&#34;&gt;Additional resources:&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/reference/builder/#onbuild&#34;&gt;Dockerfile Reference&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/articles/baseimages/&#34;&gt;More about Base Images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/docker-hub/builds/&#34;&gt;More about Automated Builds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.docker.com/docker-hub/official_repos/&#34;&gt;Guidelines for Creating Official
Repositories&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
</item>
<item>
<title></title>
<link>http://localhost/articles/https/README/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/https/README/</guid>
<description>&lt;p&gt;This is an initial attempt to make it easier to test the examples in the https.md
doc&lt;/p&gt;
&lt;p&gt;at this point, it has to be a manual thing, and I&amp;rsquo;ve been running it in boot2docker&lt;/p&gt;
&lt;p&gt;so my process is&lt;/p&gt;
&lt;p&gt;$ boot2docker ssh
$$ git clone &lt;a href=&#34;https://github.com/docker/docker&#34;&gt;https://github.com/docker/docker&lt;/a&gt;
$$ cd docker/docs/articles/https
$$ make cert
lots of things to see and manually answer, as openssl wants to be interactive
&lt;strong&gt;NOTE:&lt;/strong&gt; make sure you enter the hostname (&lt;code&gt;boot2docker&lt;/code&gt; in my case) when prompted for &lt;code&gt;Computer Name&lt;/code&gt;)
$$ sudo make run&lt;/p&gt;
&lt;p&gt;start another terminal&lt;/p&gt;
&lt;p&gt;$ boot2docker ssh
$$ cd docker/docs/articles/https
$$ make client&lt;/p&gt;
&lt;p&gt;the last will connect first with &lt;code&gt;--tls&lt;/code&gt; and then with &lt;code&gt;--tlsverify&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;both should succeed&lt;/p&gt;
</description>
</item>
<item>
<title>Configuring and running Docker</title>
<link>http://localhost/articles/configuring/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/configuring/</guid>
<description>
&lt;h1 id=&#34;configuring-and-running-docker-on-various-distributions&#34;&gt;Configuring and running Docker on various distributions&lt;/h1&gt;
&lt;p&gt;After successfully installing Docker, the &lt;code&gt;docker&lt;/code&gt; daemon runs with its default
configuration.&lt;/p&gt;
&lt;p&gt;In a production environment, system administrators typically configure the
&lt;code&gt;docker&lt;/code&gt; daemon to start and stop according to an organization&amp;rsquo;s requirements. In most
cases, the system administrator configures a process manager such as &lt;code&gt;SysVinit&lt;/code&gt;, &lt;code&gt;Upstart&lt;/code&gt;,
or &lt;code&gt;systemd&lt;/code&gt; to manage the &lt;code&gt;docker&lt;/code&gt; daemon&amp;rsquo;s start and stop.&lt;/p&gt;
&lt;h3 id=&#34;running-the-docker-daemon-directly&#34;&gt;Running the docker daemon directly&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;docker&lt;/code&gt; daemon can be run directly using the &lt;code&gt;-d&lt;/code&gt; option. By default it listens on
the Unix socket &lt;code&gt;unix:///var/run/docker.sock&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker -d
INFO[0000] +job init_networkdriver()
INFO[0000] +job serveapi(unix:///var/run/docker.sock)
INFO[0000] Listening for HTTP on unix (/var/run/docker.sock)
...
...
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configuring-the-docker-daemon-directly&#34;&gt;Configuring the docker daemon directly&lt;/h3&gt;
&lt;p&gt;If you&amp;rsquo;re running the &lt;code&gt;docker&lt;/code&gt; daemon directly by running &lt;code&gt;docker -d&lt;/code&gt; instead
of using a process manager, you can append the configuration options to the &lt;code&gt;docker&lt;/code&gt; run
command directly. Just like the &lt;code&gt;-d&lt;/code&gt; option, other options can be passed to the &lt;code&gt;docker&lt;/code&gt;
daemon to configure it.&lt;/p&gt;
&lt;p&gt;Some of the daemon&amp;rsquo;s options are:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Flag&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-D&lt;/code&gt;, &lt;code&gt;--debug=false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable or disable debug mode. By default, this is false.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;-H&lt;/code&gt;,&lt;code&gt;--host=[]&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Daemon socket(s) to connect to.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;--tls=false&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Enable or disable TLS. By default, this is false.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Here is a an example of running the &lt;code&gt;docker&lt;/code&gt; daemon with configuration options:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker -d -D --tls=true --tlscert=/var/docker/server.pem --tlskey=/var/docker/serverkey.pem -H tcp://192.168.59.3:2376
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These options :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable &lt;code&gt;-D&lt;/code&gt; (debug) mode&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;tls&lt;/code&gt; to true with the server certificate and key specified using &lt;code&gt;--tlscert&lt;/code&gt; and &lt;code&gt;--tlskey&lt;/code&gt; respectively&lt;/li&gt;
&lt;li&gt;Listen for connections on &lt;code&gt;tcp://192.168.59.3:2376&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The command line reference has the &lt;a href=&#34;http://localhost/articles/articles/reference/commandline/cli/#daemon&#34;&gt;complete list of daemon flags&lt;/a&gt;
with explanations.&lt;/p&gt;
&lt;h2 id=&#34;ubuntu&#34;&gt;Ubuntu&lt;/h2&gt;
&lt;p&gt;As of &lt;code&gt;14.04&lt;/code&gt;, Ubuntu uses Upstart as a process manager. By default, Upstart jobs
are located in &lt;code&gt;/etc/init&lt;/code&gt; and the &lt;code&gt;docker&lt;/code&gt; Upstart job can be found at &lt;code&gt;/etc/init/docker.conf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;After successfully &lt;a href=&#34;http://localhost/articles/articles/installation/ubuntulinux/&#34;&gt;installing Docker for Ubuntu&lt;/a&gt;,
you can check the running status using Upstart in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo status docker
docker start/running, process 989
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;running-docker&#34;&gt;Running Docker&lt;/h3&gt;
&lt;p&gt;You can start/stop/restart the &lt;code&gt;docker&lt;/code&gt; daemon using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo start docker
$ sudo stop docker
$ sudo restart docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configuring-docker&#34;&gt;Configuring Docker&lt;/h3&gt;
&lt;p&gt;You configure the &lt;code&gt;docker&lt;/code&gt; daemon in the &lt;code&gt;/etc/default/docker&lt;/code&gt; file on your
system. You do this by specifying values in a &lt;code&gt;DOCKER_OPTS&lt;/code&gt; variable.&lt;/p&gt;
&lt;p&gt;To configure Docker options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log into your host as a user with &lt;code&gt;sudo&lt;/code&gt; or &lt;code&gt;root&lt;/code&gt; privileges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you don&amp;rsquo;t have one, create the &lt;code&gt;/etc/default/docker&lt;/code&gt; file on your host. Depending on how
you installed Docker, you may already have this file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the file with your favorite editor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo vi /etc/default/docker
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a &lt;code&gt;DOCKER_OPTS&lt;/code&gt; variable with the following options. These options are appended to the
&lt;code&gt;docker&lt;/code&gt; daemon&amp;rsquo;s run command.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; DOCKER_OPTS=&amp;quot;-D --tls=true --tlscert=/var/docker/server.pem --tlskey=/var/docker/serverkey.pem -H tcp://192.168.59.3:2376&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These options :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable &lt;code&gt;-D&lt;/code&gt; (debug) mode&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;tls&lt;/code&gt; to true with the server certificate and key specified using &lt;code&gt;--tlscert&lt;/code&gt; and &lt;code&gt;--tlskey&lt;/code&gt; respectively&lt;/li&gt;
&lt;li&gt;Listen for connections on &lt;code&gt;tcp://192.168.59.3:2376&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The command line reference has the &lt;a href=&#34;http://localhost/articles/articles/reference/commandline/cli/#daemon&#34;&gt;complete list of daemon flags&lt;/a&gt;
with explanations.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Save and close the file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the &lt;code&gt;docker&lt;/code&gt; daemon.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo restart docker
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that the &lt;code&gt;docker&lt;/code&gt; daemon is running as specified with the &lt;code&gt;ps&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ps aux | grep docker | grep -v grep
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;logs&#34;&gt;Logs&lt;/h3&gt;
&lt;p&gt;By default logs for Upstart jobs are located in &lt;code&gt;/var/log/upstart&lt;/code&gt; and the logs for &lt;code&gt;docker&lt;/code&gt; daemon
can be located at &lt;code&gt;/var/log/upstart/docker.log&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ tail -f /var/log/upstart/docker.log
INFO[0000] Loading containers: done.
INFO[0000] docker daemon: 1.6.0 4749651; execdriver: native-0.2; graphdriver: aufs
INFO[0000] +job acceptconnections()
INFO[0000] -job acceptconnections() = OK (0)
INFO[0000] Daemon has completed initialization
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;centos-red-hat-enterprise-linux-fedora&#34;&gt;CentOS / Red Hat Enterprise Linux / Fedora&lt;/h2&gt;
&lt;p&gt;As of &lt;code&gt;7.x&lt;/code&gt;, CentOS and RHEL use &lt;code&gt;systemd&lt;/code&gt; as the process manager. As of &lt;code&gt;21&lt;/code&gt;, Fedora uses
&lt;code&gt;systemd&lt;/code&gt; as its process manager.&lt;/p&gt;
&lt;p&gt;After successfully installing Docker for &lt;a href=&#34;http://localhost/articles/articles/installation/centos/&#34;&gt;CentOS&lt;/a&gt;/&lt;a href=&#34;http://localhost/installation/rhel/&#34;&gt;Red Hat Enterprise Linux&lt;/a&gt;/&lt;a href=&#34;http://localhost/articles/articles/installation/fedora&#34;&gt;Fedora&lt;/a&gt;, you can check the running status in this way:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo systemctl status docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;running-docker-1&#34;&gt;Running Docker&lt;/h3&gt;
&lt;p&gt;You can start/stop/restart the &lt;code&gt;docker&lt;/code&gt; daemon using&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo systemctl start docker
$ sudo systemctl stop docker
$ sudo systemctl restart docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you want Docker to start at boot, you should also:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo systemctl enable docker
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;configuring-docker-1&#34;&gt;Configuring Docker&lt;/h3&gt;
&lt;p&gt;You configure the &lt;code&gt;docker&lt;/code&gt; daemon in the &lt;code&gt;/etc/sysconfig/docker&lt;/code&gt; file on your
host. You do this by specifying values in a variable. For CentOS 7.x and RHEL 7.x, the name
of the variable is &lt;code&gt;OPTIONS&lt;/code&gt; and for CentOS 6.x and RHEL 6.x, the name of the variable is
&lt;code&gt;other_args&lt;/code&gt;. For this section, we will use CentOS 7.x as an example to configure the &lt;code&gt;docker&lt;/code&gt;
daemon.&lt;/p&gt;
&lt;p&gt;By default, systemd services are located either in &lt;code&gt;/etc/systemd/service&lt;/code&gt;, &lt;code&gt;/lib/systemd/system&lt;/code&gt;
or &lt;code&gt;/usr/lib/systemd/system&lt;/code&gt;. The &lt;code&gt;docker.service&lt;/code&gt; file can be found in either of these three
directories depending on your host.&lt;/p&gt;
&lt;p&gt;To configure Docker options:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Log into your host as a user with &lt;code&gt;sudo&lt;/code&gt; or &lt;code&gt;root&lt;/code&gt; privileges.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you don&amp;rsquo;t have one, create the &lt;code&gt;/etc/sysconfig/docker&lt;/code&gt; file on your host. Depending on how
you installed Docker, you may already have this file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the file with your favorite editor.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo vi /etc/sysconfig/docker
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a &lt;code&gt;OPTIONS&lt;/code&gt; variable with the following options. These options are appended to the
command that starts the &lt;code&gt;docker&lt;/code&gt; daemon.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code&gt; OPTIONS=&amp;quot;-D --tls=true --tlscert=/var/docker/server.pem --tlskey=/var/docker/serverkey.pem -H tcp://192.168.59.3:2376&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;These options :&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Enable &lt;code&gt;-D&lt;/code&gt; (debug) mode&lt;/li&gt;
&lt;li&gt;Set &lt;code&gt;tls&lt;/code&gt; to true with the server certificate and key specified using &lt;code&gt;--tlscert&lt;/code&gt; and &lt;code&gt;--tlskey&lt;/code&gt; respectively&lt;/li&gt;
&lt;li&gt;Listen for connections on &lt;code&gt;tcp://192.168.59.3:2376&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The command line reference has the &lt;a href=&#34;http://localhost/articles/articles/reference/commandline/cli/#daemon&#34;&gt;complete list of daemon flags&lt;/a&gt;
with explanations.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Save and close the file.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Restart the &lt;code&gt;docker&lt;/code&gt; daemon.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo service docker restart
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify that the &lt;code&gt;docker&lt;/code&gt; daemon is running as specified with the &lt;code&gt;ps&lt;/code&gt; command.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ps aux | grep docker | grep -v grep
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;logs-1&#34;&gt;Logs&lt;/h3&gt;
&lt;p&gt;systemd has its own logging system called the journal. The logs for the &lt;code&gt;docker&lt;/code&gt; daemon can
be viewed using &lt;code&gt;journalctl -u docker&lt;/code&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo journalctl -u docker
May 06 00:22:05 localhost.localdomain systemd[1]: Starting Docker Application Container Engine...
May 06 00:22:05 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:05Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;+job serveapi(unix:///var/run/docker.sock)&amp;quot;
May 06 00:22:05 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:05Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;Listening for HTTP on unix (/var/run/docker.sock)&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;+job init_networkdriver()&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;-job init_networkdriver() = OK (0)&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;Loading containers: start.&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;Loading containers: done.&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;docker daemon: 1.5.0-dev fc0329b/1.5.0; execdriver: native-0.2; graphdriver: devicemapper&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;+job acceptconnections()&amp;quot;
May 06 00:22:06 localhost.localdomain docker[2495]: time=&amp;quot;2015-05-06T00:22:06Z&amp;quot; level=&amp;quot;info&amp;quot; msg=&amp;quot;-job acceptconnections() = OK (0)&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;em&gt;Note: Using and configuring journal is an advanced topic and is beyond the scope of this article.&lt;/em&gt;&lt;/p&gt;
</description>
</item>
<item>
<title>Automatically start containers</title>
<link>http://localhost/articles/host_integration/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/host_integration/</guid>
<description>
&lt;h1 id=&#34;automatically-start-containers&#34;&gt;Automatically start containers&lt;/h1&gt;
&lt;p&gt;As of Docker 1.2,
&lt;a href=&#34;http://localhost/articles/articles/reference/commandline/cli/#restart-policies&#34;&gt;restart policies&lt;/a&gt; are the
built-in Docker mechanism for restarting containers when they exit. If set,
restart policies will be used when the Docker daemon starts up, as typically
happens after a system boot. Restart policies will ensure that linked containers
are started in the correct order.&lt;/p&gt;
&lt;p&gt;If restart policies don&amp;rsquo;t suit your needs (i.e., you have non-Docker processes
that depend on Docker containers), you can use a process manager like
&lt;a href=&#34;http://upstart.ubuntu.com/&#34;&gt;upstart&lt;/a&gt;,
&lt;a href=&#34;http://freedesktop.org/wiki/Software/systemd/&#34;&gt;systemd&lt;/a&gt; or
&lt;a href=&#34;http://supervisord.org/&#34;&gt;supervisor&lt;/a&gt; instead.&lt;/p&gt;
&lt;h2 id=&#34;using-a-process-manager&#34;&gt;Using a process manager&lt;/h2&gt;
&lt;p&gt;Docker does not set any restart policies by default, but be aware that they will
conflict with most process managers. So don&amp;rsquo;t set restart policies if you are
using a process manager.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Prior to Docker 1.2, restarting of Docker containers had to be
explicitly disabled. Refer to the
&lt;a href=&#34;http://localhost/articles/articles/v1.1/articles/host_integration/&#34;&gt;previous version&lt;/a&gt; of this article for the
details on how to do that.&lt;/p&gt;
&lt;p&gt;When you have finished setting up your image and are happy with your
running container, you can then attach a process manager to manage it.
When you run &lt;code&gt;docker start -a&lt;/code&gt;, Docker will automatically attach to the
running container, or start it if needed and forward all signals so that
the process manager can detect when a container stops and correctly
restart it.&lt;/p&gt;
&lt;p&gt;Here are a few sample scripts for systemd and upstart to integrate with
Docker.&lt;/p&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;p&gt;The examples below show configuration files for two popular process managers,
upstart and systemd. In these examples, we&amp;rsquo;ll assume that we have already
created a container to run Redis with &lt;code&gt;--name=redis_server&lt;/code&gt;. These files define
a new service that will be started after the docker daemon service has started.&lt;/p&gt;
&lt;h3 id=&#34;upstart&#34;&gt;upstart&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;description &amp;quot;Redis container&amp;quot;
author &amp;quot;Me&amp;quot;
start on filesystem and started docker
stop on runlevel [!2345]
respawn
script
/usr/bin/docker start -a redis_server
end script
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;systemd&#34;&gt;systemd&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;[Unit]
Description=Redis container
Requires=docker.service
After=docker.service
[Service]
Restart=always
ExecStart=/usr/bin/docker start -a redis_server
ExecStop=/usr/bin/docker stop -t 2 redis_server
[Install]
WantedBy=local.target
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you need to pass options to the redis container (such as &lt;code&gt;--env&lt;/code&gt;),
then you&amp;rsquo;ll need to use &lt;code&gt;docker run&lt;/code&gt; rather than &lt;code&gt;docker start&lt;/code&gt;. This will
create a new container every time the service is started, which will be stopped
and removed when the service is stopped.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;[Service]
...
ExecStart=/usr/bin/docker run --env foo=bar --name redis_server redis
ExecStop=/usr/bin/docker stop -t 2 redis_server ; /usr/bin/docker rm -f redis_server
...
&lt;/code&gt;&lt;/pre&gt;
</description>
</item>
<item>
<title>PowerShell DSC Usage</title>
<link>http://localhost/articles/dsc/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/dsc/</guid>
<description>
&lt;h1 id=&#34;using-powershell-dsc&#34;&gt;Using PowerShell DSC&lt;/h1&gt;
&lt;p&gt;Windows PowerShell Desired State Configuration (DSC) is a configuration
management tool that extends the existing functionality of Windows PowerShell.
DSC uses a declarative syntax to define the state in which a target should be
configured. More information about PowerShell DSC can be found at
&lt;a href=&#34;http://technet.microsoft.com/en-us/library/dn249912.aspx&#34;&gt;http://technet.microsoft.com/en-us/library/dn249912.aspx&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;To use this guide you&amp;rsquo;ll need a Windows host with PowerShell v4.0 or newer.&lt;/p&gt;
&lt;p&gt;The included DSC configuration script also uses the official PPA so
only an Ubuntu target is supported. The Ubuntu target must already have the
required OMI Server and PowerShell DSC for Linux providers installed. More
information can be found at &lt;a href=&#34;https://github.com/MSFTOSSMgmt/WPSDSCLinux&#34;&gt;https://github.com/MSFTOSSMgmt/WPSDSCLinux&lt;/a&gt;.
The source repository listed below also includes PowerShell DSC for Linux
installation and init scripts along with more detailed installation information.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;The DSC configuration example source is available in the following repository:
&lt;a href=&#34;https://github.com/anweiss/DockerClientDSC&#34;&gt;https://github.com/anweiss/DockerClientDSC&lt;/a&gt;. It can be cloned with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ git clone https://github.com/anweiss/DockerClientDSC.git
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;The DSC configuration utilizes a set of shell scripts to determine whether or
not the specified Docker components are configured on the target node(s). The
source repository also includes a script (&lt;code&gt;RunDockerClientConfig.ps1&lt;/code&gt;) that can
be used to establish the required CIM session(s) and execute the
&lt;code&gt;Set-DscConfiguration&lt;/code&gt; cmdlet.&lt;/p&gt;
&lt;p&gt;More detailed usage information can be found at
&lt;a href=&#34;https://github.com/anweiss/DockerClientDSC&#34;&gt;https://github.com/anweiss/DockerClientDSC&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;install-docker&#34;&gt;Install Docker&lt;/h3&gt;
&lt;p&gt;The Docker installation configuration is equivalent to running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys\
36A1D7869245C8950F966E92D8576A8BA88D21E9
sh -c &amp;quot;echo deb https://get.docker.com/ubuntu docker main\
&amp;gt; /etc/apt/sources.list.d/docker.list&amp;quot;
apt-get update
apt-get install lxc-docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Ensure that your current working directory is set to the &lt;code&gt;DockerClientDSC&lt;/code&gt;
source and load the DockerClient configuration into the current PowerShell
session&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;. .\DockerClient.ps1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generate the required DSC configuration .mof file for the targeted node&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;A sample DSC configuration data file has also been included and can be modified
and used in conjunction with or in place of the &lt;code&gt;Hostname&lt;/code&gt; parameter:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -ConfigurationData .\DockerConfigData.psd1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Start the configuration application process on the targeted node&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;.\RunDockerClientConfig.ps1 -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;RunDockerClientConfig.ps1&lt;/code&gt; script can also parse a DSC configuration data
file and execute configurations against multiple nodes as such:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;.\RunDockerClientConfig.ps1 -ConfigurationData .\DockerConfigData.psd1
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;images&#34;&gt;Images&lt;/h3&gt;
&lt;p&gt;Image configuration is equivalent to running: &lt;code&gt;docker pull [image]&lt;/code&gt; or
&lt;code&gt;docker rmi -f [IMAGE]&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Using the same steps defined above, execute &lt;code&gt;DockerClient&lt;/code&gt; with the &lt;code&gt;Image&lt;/code&gt;
parameter and apply the configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -Hostname &amp;quot;myhost&amp;quot; -Image &amp;quot;node&amp;quot;
.\RunDockerClientConfig.ps1 -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also configure the host to pull multiple images:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -Hostname &amp;quot;myhost&amp;quot; -Image &amp;quot;node&amp;quot;,&amp;quot;mongo&amp;quot;
.\RunDockerClientConfig.ps1 -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To remove images, use a hashtable as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -Hostname &amp;quot;myhost&amp;quot; -Image @{Name=&amp;quot;node&amp;quot;; Remove=$true}
.\RunDockerClientConfig.ps1 -Hostname $hostname
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;containers&#34;&gt;Containers&lt;/h3&gt;
&lt;p&gt;Container configuration is equivalent to running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -d --name=&amp;quot;[containername]&amp;quot; -p &#39;[port]&#39; -e &#39;[env]&#39; --link &#39;[link]&#39;\
&#39;[image]&#39; &#39;[command]&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;or&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker rm -f [containername]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To create or remove containers, you can use the &lt;code&gt;Container&lt;/code&gt; parameter with one
or more hashtables. The hashtable(s) passed to this parameter can have the
following properties:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Name (required)&lt;/li&gt;
&lt;li&gt;Image (required unless Remove property is set to &lt;code&gt;$true&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Port&lt;/li&gt;
&lt;li&gt;Env&lt;/li&gt;
&lt;li&gt;Link&lt;/li&gt;
&lt;li&gt;Command&lt;/li&gt;
&lt;li&gt;Remove&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For example, create a hashtable with the settings for your container:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;$webContainer = @{Name=&amp;quot;web&amp;quot;; Image=&amp;quot;anweiss/docker-platynem&amp;quot;; Port=&amp;quot;80:80&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, using the same steps defined above, execute
&lt;code&gt;DockerClient&lt;/code&gt; with the &lt;code&gt;-Image&lt;/code&gt; and &lt;code&gt;-Container&lt;/code&gt; parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;DockerClient -Hostname &amp;quot;myhost&amp;quot; -Image node -Container $webContainer
.\RunDockerClientConfig.ps1 -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Existing containers can also be removed as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;$containerToRemove = @{Name=&amp;quot;web&amp;quot;; Remove=$true}
DockerClient -Hostname &amp;quot;myhost&amp;quot; -Container $containerToRemove
.\RunDockerClientConfig.ps1 -Hostname &amp;quot;myhost&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Here is a hashtable with all of the properties that can be used to create a
container:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;$containerProps = @{Name=&amp;quot;web&amp;quot;; Image=&amp;quot;node:latest&amp;quot;; Port=&amp;quot;80:80&amp;quot;; `
Env=&amp;quot;PORT=80&amp;quot;; Link=&amp;quot;db:db&amp;quot;; Command=&amp;quot;grunt&amp;quot;}
&lt;/code&gt;&lt;/pre&gt;
</description>
</item>
<item>
<title>Protect the Docker daemon socket</title>
<link>http://localhost/articles/https/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/https/</guid>
<description>
&lt;h1 id=&#34;protect-the-docker-daemon-socket&#34;&gt;Protect the Docker daemon socket&lt;/h1&gt;
&lt;p&gt;By default, Docker runs via a non-networked Unix socket. It can also
optionally communicate using a HTTP socket.&lt;/p&gt;
&lt;p&gt;If you need Docker to be reachable via the network in a safe manner, you can
enable TLS by specifying the &lt;code&gt;tlsverify&lt;/code&gt; flag and pointing Docker&amp;rsquo;s
&lt;code&gt;tlscacert&lt;/code&gt; flag to a trusted CA certificate.&lt;/p&gt;
&lt;p&gt;In the daemon mode, it will only allow connections from clients
authenticated by a certificate signed by that CA. In the client mode,
it will only connect to servers with a certificate signed by that CA.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;:
Using TLS and managing a CA is an advanced topic. Please familiarize yourself
with OpenSSL, x509 and TLS before using it in production.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;:
These TLS commands will only generate a working set of certificates on Linux.
Mac OS X comes with a version of OpenSSL that is incompatible with the
certificates that Docker requires.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;create-a-ca-server-and-client-keys-with-openssl&#34;&gt;Create a CA, server and client keys with OpenSSL&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: replace all instances of &lt;code&gt;$HOST&lt;/code&gt; in the following example with the
DNS name of your Docker daemon&amp;rsquo;s host.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;First generate CA private and public keys:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl genrsa -aes256 -out ca-key.pem 2048
Generating RSA private key, 2048 bit long modulus
......+++
...............+++
e is 65537 (0x10001)
Enter pass phrase for ca-key.pem:
Verifying - Enter pass phrase for ca-key.pem:
$ openssl req -new -x509 -days 365 -key ca-key.pem -sha256 -out ca.pem
Enter pass phrase for ca-key.pem:
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter &#39;.&#39;, the field will be left blank.
-----
Country Name (2 letter code) [AU]:
State or Province Name (full name) [Some-State]:Queensland
Locality Name (eg, city) []:Brisbane
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Docker Inc
Organizational Unit Name (eg, section) []:Boot2Docker
Common Name (e.g. server FQDN or YOUR name) []:$HOST
Email Address []:Sven@home.org.au
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now that we have a CA, you can create a server key and certificate
signing request (CSR). Make sure that &amp;ldquo;Common Name&amp;rdquo; (i.e., server FQDN or YOUR
name) matches the hostname you will use to connect to Docker:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: replace all instances of &lt;code&gt;$HOST&lt;/code&gt; in the following example with the
DNS name of your Docker daemon&amp;rsquo;s host.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;$ openssl genrsa -out server-key.pem 2048
Generating RSA private key, 2048 bit long modulus
......................................................+++
............................................+++
e is 65537 (0x10001)
$ openssl req -subj &amp;quot;/CN=$HOST&amp;quot; -new -key server-key.pem -out server.csr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Next, we&amp;rsquo;re going to sign the public key with our CA:&lt;/p&gt;
&lt;p&gt;Since TLS connections can be made via IP address as well as DNS name, they need
to be specified when creating the certificate. For example, to allow connections
using &lt;code&gt;10.10.10.20&lt;/code&gt; and &lt;code&gt;127.0.0.1&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo subjectAltName = IP:10.10.10.20,IP:127.0.0.1 &amp;gt; extfile.cnf
$ openssl x509 -req -days 365 -in server.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out server-cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=your.host.com
Getting CA Private Key
Enter pass phrase for ca-key.pem:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For client authentication, create a client key and certificate signing
request:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl genrsa -out key.pem 2048
Generating RSA private key, 2048 bit long modulus
...............................................+++
...............................................................+++
e is 65537 (0x10001)
$ openssl req -subj &#39;/CN=client&#39; -new -key key.pem -out client.csr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To make the key suitable for client authentication, create an extensions
config file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo extendedKeyUsage = clientAuth &amp;gt; extfile.cnf
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now sign the public key:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ openssl x509 -req -days 365 -in client.csr -CA ca.pem -CAkey ca-key.pem \
-CAcreateserial -out cert.pem -extfile extfile.cnf
Signature ok
subject=/CN=client
Getting CA Private Key
Enter pass phrase for ca-key.pem:
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After generating &lt;code&gt;cert.pem&lt;/code&gt; and &lt;code&gt;server-cert.pem&lt;/code&gt; you can safely remove the
two certificate signing requests:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ rm -v client.csr server.csr
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;With a default &lt;code&gt;umask&lt;/code&gt; of 022, your secret keys will be &lt;em&gt;world-readable&lt;/em&gt; and
writable for you and your group.&lt;/p&gt;
&lt;p&gt;In order to protect your keys from accidental damage, you will want to remove their
write permissions. To make them only readable by you, change file modes as follows:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ chmod -v 0400 ca-key.pem key.pem server-key.pem
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Certificates can be world-readable, but you might want to remove write access to
prevent accidental damage:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ chmod -v 0444 ca.pem server-cert.pem cert.pem
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can make the Docker daemon only accept connections from clients
providing a certificate trusted by our CA:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker -d --tlsverify --tlscacert=ca.pem --tlscert=server-cert.pem --tlskey=server-key.pem \
-H=0.0.0.0:2376
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To be able to connect to Docker and validate its certificate, you now
need to provide your client keys, certificates and trusted CA:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: replace all instances of &lt;code&gt;$HOST&lt;/code&gt; in the following example with the
DNS name of your Docker daemon&amp;rsquo;s host.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre&gt;&lt;code&gt;$ docker --tlsverify --tlscacert=ca.pem --tlscert=cert.pem --tlskey=key.pem \
-H=$HOST:2376 version
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
Docker over TLS should run on TCP port 2376.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;:
As shown in the example above, you don&amp;rsquo;t have to run the &lt;code&gt;docker&lt;/code&gt; client
with &lt;code&gt;sudo&lt;/code&gt; or the &lt;code&gt;docker&lt;/code&gt; group when you use certificate authentication.
That means anyone with the keys can give any instructions to your Docker
daemon, giving them root access to the machine hosting the daemon. Guard
these keys as you would a root password!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;secure-by-default&#34;&gt;Secure by default&lt;/h2&gt;
&lt;p&gt;If you want to secure your Docker client connections by default, you can move
the files to the &lt;code&gt;.docker&lt;/code&gt; directory in your home directory &amp;ndash; and set the
&lt;code&gt;DOCKER_HOST&lt;/code&gt; and &lt;code&gt;DOCKER_TLS_VERIFY&lt;/code&gt; variables as well (instead of passing
&lt;code&gt;-H=tcp://$HOST:2376&lt;/code&gt; and &lt;code&gt;--tlsverify&lt;/code&gt; on every call).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ mkdir -pv ~/.docker
$ cp -v {ca,cert,key}.pem ~/.docker
$ export DOCKER_HOST=tcp://$HOST:2376 DOCKER_TLS_VERIFY=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Docker will now connect securely by default:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker ps
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;other-modes&#34;&gt;Other modes&lt;/h2&gt;
&lt;p&gt;If you don&amp;rsquo;t want to have complete two-way authentication, you can run
Docker in various other modes by mixing the flags.&lt;/p&gt;
&lt;h3 id=&#34;daemon-modes&#34;&gt;Daemon modes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tlsverify&lt;/code&gt;, &lt;code&gt;tlscacert&lt;/code&gt;, &lt;code&gt;tlscert&lt;/code&gt;, &lt;code&gt;tlskey&lt;/code&gt; set: Authenticate clients&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls&lt;/code&gt;, &lt;code&gt;tlscert&lt;/code&gt;, &lt;code&gt;tlskey&lt;/code&gt;: Do not authenticate clients&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;client-modes&#34;&gt;Client modes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;tls&lt;/code&gt;: Authenticate server based on public/default CA pool&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tlsverify&lt;/code&gt;, &lt;code&gt;tlscacert&lt;/code&gt;: Authenticate server based on given CA&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tls&lt;/code&gt;, &lt;code&gt;tlscert&lt;/code&gt;, &lt;code&gt;tlskey&lt;/code&gt;: Authenticate with client certificate, do not
authenticate server based on given CA&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tlsverify&lt;/code&gt;, &lt;code&gt;tlscacert&lt;/code&gt;, &lt;code&gt;tlscert&lt;/code&gt;, &lt;code&gt;tlskey&lt;/code&gt;: Authenticate with client
certificate and authenticate server based on given CA&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If found, the client will send its client certificate, so you just need
to drop your keys into &lt;code&gt;~/.docker/{ca,cert,key}.pem&lt;/code&gt;. Alternatively,
if you want to store your keys in another location, you can specify that
location using the environment variable &lt;code&gt;DOCKER_CERT_PATH&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ export DOCKER_CERT_PATH=~/.docker/zone1/
$ docker --tlsverify ps
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;connecting-to-the-secure-docker-port-using-curl&#34;&gt;Connecting to the secure Docker port using &lt;code&gt;curl&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;To use &lt;code&gt;curl&lt;/code&gt; to make test API requests, you need to use three extra command line
flags:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ curl https://$HOST:2376/images/json \
--cert ~/.docker/cert.pem \
--key ~/.docker/key.pem \
--cacert ~/.docker/ca.pem
&lt;/code&gt;&lt;/pre&gt;
</description>
</item>
<item>
<title>Network configuration</title>
<link>http://localhost/articles/networking/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/networking/</guid>
<description>
&lt;h1 id=&#34;network-configuration&#34;&gt;Network configuration&lt;/h1&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;When Docker starts, it creates a virtual interface named &lt;code&gt;docker0&lt;/code&gt; on
the host machine. It randomly chooses an address and subnet from the
private range defined by &lt;a href=&#34;http://tools.ietf.org/html/rfc1918&#34;&gt;RFC 1918&lt;/a&gt;
that are not in use on the host machine, and assigns it to &lt;code&gt;docker0&lt;/code&gt;.
Docker made the choice &lt;code&gt;172.17.42.1/16&lt;/code&gt; when I started it a few minutes
ago, for example — a 16-bit netmask providing 65,534 addresses for the
host machine and its containers. The MAC address is generated using the
IP address allocated to the container to avoid ARP collisions, using a
range from &lt;code&gt;02:42:ac:11:00:00&lt;/code&gt; to &lt;code&gt;02:42:ac:11:ff:ff&lt;/code&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt;
This document discusses advanced networking configuration
and options for Docker. In most cases you won&amp;rsquo;t need this information.
If you&amp;rsquo;re looking to get started with a simpler explanation of Docker
networking and an introduction to the concept of container linking see
the &lt;a href=&#34;http://localhost/userguide/dockerlinks/&#34;&gt;Docker User Guide&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But &lt;code&gt;docker0&lt;/code&gt; is no ordinary interface. It is a virtual &lt;em&gt;Ethernet
bridge&lt;/em&gt; that automatically forwards packets between any other network
interfaces that are attached to it. This lets containers communicate
both with the host machine and with each other. Every time Docker
creates a container, it creates a pair of “peer” interfaces that are
like opposite ends of a pipe — a packet sent on one will be received on
the other. It gives one of the peers to the container to become its
&lt;code&gt;eth0&lt;/code&gt; interface and keeps the other peer, with a unique name like
&lt;code&gt;vethAQI2QT&lt;/code&gt;, out in the namespace of the host machine. By binding
every &lt;code&gt;veth*&lt;/code&gt; interface to the &lt;code&gt;docker0&lt;/code&gt; bridge, Docker creates a
virtual subnet shared between the host machine and every Docker
container.&lt;/p&gt;
&lt;p&gt;The remaining sections of this document explain all of the ways that you
can use Docker options and — in advanced cases — raw Linux networking
commands to tweak, supplement, or entirely replace Docker&amp;rsquo;s default
networking configuration.&lt;/p&gt;
&lt;h2 id=&#34;quick-guide-to-the-options&#34;&gt;Quick guide to the options&lt;/h2&gt;
&lt;p&gt;Here is a quick list of the networking-related Docker command-line
options, in case it helps you find the section below that you are
looking for.&lt;/p&gt;
&lt;p&gt;Some networking command-line options can only be supplied to the Docker
server when it starts up, and cannot be changed once it is running:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-b BRIDGE&lt;/code&gt; or &lt;code&gt;--bridge=BRIDGE&lt;/code&gt; — see
&lt;a href=&#34;#bridge-building&#34;&gt;Building your own bridge&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--bip=CIDR&lt;/code&gt; — see
&lt;a href=&#34;#docker0&#34;&gt;Customizing docker0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--default-gateway=IP_ADDRESS&lt;/code&gt; — see
&lt;a href=&#34;#container-networking&#34;&gt;How Docker networks a container&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--default-gateway-v6=IP_ADDRESS&lt;/code&gt; — see
&lt;a href=&#34;#ipv6&#34;&gt;IPv6&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--fixed-cidr&lt;/code&gt; — see
&lt;a href=&#34;#docker0&#34;&gt;Customizing docker0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--fixed-cidr-v6&lt;/code&gt; — see
&lt;a href=&#34;#ipv6&#34;&gt;IPv6&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-H SOCKET...&lt;/code&gt; or &lt;code&gt;--host=SOCKET...&lt;/code&gt;
This might sound like it would affect container networking,
but it actually faces in the other direction:
it tells the Docker server over what channels
it should be willing to receive commands
like “run container” and “stop container.”&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--icc=true|false&lt;/code&gt; — see
&lt;a href=&#34;#between-containers&#34;&gt;Communication between containers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--ip=IP_ADDRESS&lt;/code&gt; — see
&lt;a href=&#34;#binding-ports&#34;&gt;Binding container ports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--ipv6=true|false&lt;/code&gt; — see
&lt;a href=&#34;#ipv6&#34;&gt;IPv6&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--ip-forward=true|false&lt;/code&gt; — see
&lt;a href=&#34;#the-world&#34;&gt;Communication between containers and the wider world&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--iptables=true|false&lt;/code&gt; — see
&lt;a href=&#34;#between-containers&#34;&gt;Communication between containers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--mtu=BYTES&lt;/code&gt; — see
&lt;a href=&#34;#docker0&#34;&gt;Customizing docker0&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--userland-proxy=true|false&lt;/code&gt; — see
&lt;a href=&#34;#binding-ports&#34;&gt;Binding container ports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are two networking options that can be supplied either at startup
or when &lt;code&gt;docker run&lt;/code&gt; is invoked. When provided at startup, set the
default value that &lt;code&gt;docker run&lt;/code&gt; will later use if the options are not
specified:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--dns=IP_ADDRESS...&lt;/code&gt; — see
&lt;a href=&#34;#dns&#34;&gt;Configuring DNS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--dns-search=DOMAIN...&lt;/code&gt; — see
&lt;a href=&#34;#dns&#34;&gt;Configuring DNS&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Finally, several networking options can only be provided when calling
&lt;code&gt;docker run&lt;/code&gt; because they specify something specific to one container:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-h HOSTNAME&lt;/code&gt; or &lt;code&gt;--hostname=HOSTNAME&lt;/code&gt; — see
&lt;a href=&#34;#dns&#34;&gt;Configuring DNS&lt;/a&gt; and
&lt;a href=&#34;#container-networking&#34;&gt;How Docker networks a container&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--link=CONTAINER_NAME_or_ID:ALIAS&lt;/code&gt; — see
&lt;a href=&#34;#dns&#34;&gt;Configuring DNS&lt;/a&gt; and
&lt;a href=&#34;#between-containers&#34;&gt;Communication between containers&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--net=bridge|none|container:NAME_or_ID|host&lt;/code&gt; — see
&lt;a href=&#34;#container-networking&#34;&gt;How Docker networks a container&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--mac-address=MACADDRESS...&lt;/code&gt; — see
&lt;a href=&#34;#container-networking&#34;&gt;How Docker networks a container&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-p SPEC&lt;/code&gt; or &lt;code&gt;--publish=SPEC&lt;/code&gt; — see
&lt;a href=&#34;#binding-ports&#34;&gt;Binding container ports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-P&lt;/code&gt; or &lt;code&gt;--publish-all=true|false&lt;/code&gt; — see
&lt;a href=&#34;#binding-ports&#34;&gt;Binding container ports&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To supply networking options to the Docker server at startup, use the
&lt;code&gt;DOCKER_OPTS&lt;/code&gt; variable in the Docker upstart configuration file. For Ubuntu, edit the
variable in &lt;code&gt;/etc/default/docker&lt;/code&gt; or &lt;code&gt;/etc/sysconfig/docker&lt;/code&gt; for CentOS.&lt;/p&gt;
&lt;p&gt;The following example illustrates how to configure Docker on Ubuntu to recognize a
newly built bridge.&lt;/p&gt;
&lt;p&gt;Edit the &lt;code&gt;/etc/default/docker&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ echo &#39;DOCKER_OPTS=&amp;quot;-b=bridge0&amp;quot;&#39; &amp;gt;&amp;gt; /etc/default/docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then restart the Docker server.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sudo service docker start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For additional information on bridges, see &lt;a href=&#34;#building-your-own-bridge&#34;&gt;building your own
bridge&lt;/a&gt; later on this page.&lt;/p&gt;
&lt;p&gt;The following sections tackle all of the above topics in an order that we can move roughly from simplest to most complex.&lt;/p&gt;
&lt;h2 id=&#34;configuring-dns&#34;&gt;Configuring DNS&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;dns&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;How can Docker supply each container with a hostname and DNS
configuration, without having to build a custom image with the hostname
written inside? Its trick is to overlay three crucial &lt;code&gt;/etc&lt;/code&gt; files
inside the container with virtual files where it can write fresh
information. You can see this by running &lt;code&gt;mount&lt;/code&gt; inside a container:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$$ mount
...
/dev/disk/by-uuid/1fec...ebdf on /etc/hostname type ext4 ...
/dev/disk/by-uuid/1fec...ebdf on /etc/hosts type ext4 ...
/dev/disk/by-uuid/1fec...ebdf on /etc/resolv.conf type ext4 ...
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This arrangement allows Docker to do clever things like keep
&lt;code&gt;resolv.conf&lt;/code&gt; up to date across all containers when the host machine
receives new configuration over DHCP later. The exact details of how
Docker maintains these files inside the container can change from one
Docker version to the next, so you should leave the files themselves
alone and use the following Docker options instead.&lt;/p&gt;
&lt;p&gt;Four different options affect container domain name services.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-h HOSTNAME&lt;/code&gt; or &lt;code&gt;--hostname=HOSTNAME&lt;/code&gt; — sets the hostname by which
the container knows itself. This is written into &lt;code&gt;/etc/hostname&lt;/code&gt;,
into &lt;code&gt;/etc/hosts&lt;/code&gt; as the name of the container&amp;rsquo;s host-facing IP
address, and is the name that &lt;code&gt;/bin/bash&lt;/code&gt; inside the container will
display inside its prompt. But the hostname is not easy to see from
outside the container. It will not appear in &lt;code&gt;docker ps&lt;/code&gt; nor in the
&lt;code&gt;/etc/hosts&lt;/code&gt; file of any other container.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--link=CONTAINER_NAME_or_ID:ALIAS&lt;/code&gt; — using this option as you &lt;code&gt;run&lt;/code&gt; a
container gives the new container&amp;rsquo;s &lt;code&gt;/etc/hosts&lt;/code&gt; an extra entry
named &lt;code&gt;ALIAS&lt;/code&gt; that points to the IP address of the container identified by
&lt;code&gt;CONTAINER_NAME_or_ID&lt;/code&gt;. This lets processes inside the new container
connect to the hostname &lt;code&gt;ALIAS&lt;/code&gt; without having to know its IP. The
&lt;code&gt;--link=&lt;/code&gt; option is discussed in more detail below, in the section
&lt;a href=&#34;#between-containers&#34;&gt;Communication between containers&lt;/a&gt;. Because
Docker may assign a different IP address to the linked containers
on restart, Docker updates the &lt;code&gt;ALIAS&lt;/code&gt; entry in the &lt;code&gt;/etc/hosts&lt;/code&gt; file
of the recipient containers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--dns=IP_ADDRESS...&lt;/code&gt; — sets the IP addresses added as &lt;code&gt;server&lt;/code&gt;
lines to the container&amp;rsquo;s &lt;code&gt;/etc/resolv.conf&lt;/code&gt; file. Processes in the
container, when confronted with a hostname not in &lt;code&gt;/etc/hosts&lt;/code&gt;, will
connect to these IP addresses on port 53 looking for name resolution
services.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--dns-search=DOMAIN...&lt;/code&gt; — sets the domain names that are searched
when a bare unqualified hostname is used inside of the container, by
writing &lt;code&gt;search&lt;/code&gt; lines into the container&amp;rsquo;s &lt;code&gt;/etc/resolv.conf&lt;/code&gt;.
When a container process attempts to access &lt;code&gt;host&lt;/code&gt; and the search
domain &lt;code&gt;example.com&lt;/code&gt; is set, for instance, the DNS logic will not
only look up &lt;code&gt;host&lt;/code&gt; but also &lt;code&gt;host.example.com&lt;/code&gt;.
Use &lt;code&gt;--dns-search=.&lt;/code&gt; if you don&amp;rsquo;t wish to set the search domain.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Regarding DNS settings, in the absence of either the &lt;code&gt;--dns=IP_ADDRESS...&lt;/code&gt;
or the &lt;code&gt;--dns-search=DOMAIN...&lt;/code&gt; option, Docker makes each container&amp;rsquo;s
&lt;code&gt;/etc/resolv.conf&lt;/code&gt; look like the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; of the host machine (where
the &lt;code&gt;docker&lt;/code&gt; daemon runs). When creating the container&amp;rsquo;s &lt;code&gt;/etc/resolv.conf&lt;/code&gt;,
the daemon filters out all localhost IP address &lt;code&gt;nameserver&lt;/code&gt; entries from
the host&amp;rsquo;s original file.&lt;/p&gt;
&lt;p&gt;Filtering is necessary because all localhost addresses on the host are
unreachable from the container&amp;rsquo;s network. After this filtering, if there
are no more &lt;code&gt;nameserver&lt;/code&gt; entries left in the container&amp;rsquo;s &lt;code&gt;/etc/resolv.conf&lt;/code&gt;
file, the daemon adds public Google DNS nameservers
(8.8.8.8 and 8.8.4.4) to the container&amp;rsquo;s DNS configuration. If IPv6 is
enabled on the daemon, the public IPv6 Google DNS nameservers will also
be added (2001:4860:4860::8888 and 2001:4860:4860::8844).&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
If you need access to a host&amp;rsquo;s localhost resolver, you must modify your
DNS service on the host to listen on a non-localhost address that is
reachable from within the container.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You might wonder what happens when the host machine&amp;rsquo;s
&lt;code&gt;/etc/resolv.conf&lt;/code&gt; file changes. The &lt;code&gt;docker&lt;/code&gt; daemon has a file change
notifier active which will watch for changes to the host DNS configuration.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
The file change notifier relies on the Linux kernel&amp;rsquo;s inotify feature.
Because this feature is currently incompatible with the overlay filesystem
driver, a Docker daemon using &amp;ldquo;overlay&amp;rdquo; will not be able to take advantage
of the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; auto-update feature.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;When the host file changes, all stopped containers which have a matching
&lt;code&gt;resolv.conf&lt;/code&gt; to the host will be updated immediately to this newest host
configuration. Containers which are running when the host configuration
changes will need to stop and start to pick up the host changes due to lack
of a facility to ensure atomic writes of the &lt;code&gt;resolv.conf&lt;/code&gt; file while the
container is running. If the container&amp;rsquo;s &lt;code&gt;resolv.conf&lt;/code&gt; has been edited since
it was started with the default configuration, no replacement will be
attempted as it would overwrite the changes performed by the container.
If the options (&lt;code&gt;--dns&lt;/code&gt; or &lt;code&gt;--dns-search&lt;/code&gt;) have been used to modify the
default host configuration, then the replacement with an updated host&amp;rsquo;s
&lt;code&gt;/etc/resolv.conf&lt;/code&gt; will not happen as well.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
For containers which were created prior to the implementation of
the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; update feature in Docker 1.5.0: those
containers will &lt;strong&gt;not&lt;/strong&gt; receive updates when the host &lt;code&gt;resolv.conf&lt;/code&gt;
file changes. Only containers created with Docker 1.5.0 and above
will utilize this auto-update feature.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;communication-between-containers-and-the-wider-world&#34;&gt;Communication between containers and the wider world&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;the-world&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Whether a container can talk to the world is governed by two factors.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Is the host machine willing to forward IP packets? This is governed
by the &lt;code&gt;ip_forward&lt;/code&gt; system parameter. Packets can only pass between
containers if this parameter is &lt;code&gt;1&lt;/code&gt;. Usually you will simply leave
the Docker server at its default setting &lt;code&gt;--ip-forward=true&lt;/code&gt; and
Docker will go set &lt;code&gt;ip_forward&lt;/code&gt; to &lt;code&gt;1&lt;/code&gt; for you when the server
starts up. To check the setting or turn it on manually:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 0
$ sysctl net.ipv4.conf.all.forwarding=1
$ sysctl net.ipv4.conf.all.forwarding
net.ipv4.conf.all.forwarding = 1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Many using Docker will want &lt;code&gt;ip_forward&lt;/code&gt; to be on, to at
least make communication &lt;em&gt;possible&lt;/em&gt; between containers and
the wider world.&lt;/p&gt;
&lt;p&gt;May also be needed for inter-container communication if you are
in a multiple bridge setup.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do your &lt;code&gt;iptables&lt;/code&gt; allow this particular connection? Docker will
never make changes to your system &lt;code&gt;iptables&lt;/code&gt; rules if you set
&lt;code&gt;--iptables=false&lt;/code&gt; when the daemon starts. Otherwise the Docker
server will append forwarding rules to the &lt;code&gt;DOCKER&lt;/code&gt; filter chain.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Docker will not delete or modify any pre-existing rules from the &lt;code&gt;DOCKER&lt;/code&gt;
filter chain. This allows the user to create in advance any rules required
to further restrict access to the containers.&lt;/p&gt;
&lt;p&gt;Docker&amp;rsquo;s forward rules permit all external source IPs by default. To allow
only a specific IP or network to access the containers, insert a negated
rule at the top of the &lt;code&gt;DOCKER&lt;/code&gt; filter chain. For example, to restrict
external access such that &lt;em&gt;only&lt;/em&gt; source IP 8.8.8.8 can access the
containers, the following rule could be added:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ iptables -I DOCKER -i ext_if ! -s 8.8.8.8 -j DROP
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&#34;communication-between-containers&#34;&gt;Communication between containers&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;between-containers&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Whether two containers can communicate is governed, at the operating
system level, by two factors.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Does the network topology even connect the containers&amp;rsquo; network
interfaces? By default Docker will attach all containers to a
single &lt;code&gt;docker0&lt;/code&gt; bridge, providing a path for packets to travel
between them. See the later sections of this document for other
possible topologies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Do your &lt;code&gt;iptables&lt;/code&gt; allow this particular connection? Docker will never
make changes to your system &lt;code&gt;iptables&lt;/code&gt; rules if you set
&lt;code&gt;--iptables=false&lt;/code&gt; when the daemon starts. Otherwise the Docker server
will add a default rule to the &lt;code&gt;FORWARD&lt;/code&gt; chain with a blanket &lt;code&gt;ACCEPT&lt;/code&gt;
policy if you retain the default &lt;code&gt;--icc=true&lt;/code&gt;, or else will set the
policy to &lt;code&gt;DROP&lt;/code&gt; if &lt;code&gt;--icc=false&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It is a strategic question whether to leave &lt;code&gt;--icc=true&lt;/code&gt; or change it to
&lt;code&gt;--icc=false&lt;/code&gt; so that
&lt;code&gt;iptables&lt;/code&gt; will protect other containers — and the main host — from
having arbitrary ports probed or accessed by a container that gets
compromised.&lt;/p&gt;
&lt;p&gt;If you choose the most secure setting of &lt;code&gt;--icc=false&lt;/code&gt;, then how can
containers communicate in those cases where you &lt;em&gt;want&lt;/em&gt; them to provide
each other services?&lt;/p&gt;
&lt;p&gt;The answer is the &lt;code&gt;--link=CONTAINER_NAME_or_ID:ALIAS&lt;/code&gt; option, which was
mentioned in the previous section because of its effect upon name
services. If the Docker daemon is running with both &lt;code&gt;--icc=false&lt;/code&gt; and
&lt;code&gt;--iptables=true&lt;/code&gt; then, when it sees &lt;code&gt;docker run&lt;/code&gt; invoked with the
&lt;code&gt;--link=&lt;/code&gt; option, the Docker server will insert a pair of &lt;code&gt;iptables&lt;/code&gt;
&lt;code&gt;ACCEPT&lt;/code&gt; rules so that the new container can connect to the ports
exposed by the other container — the ports that it mentioned in the
&lt;code&gt;EXPOSE&lt;/code&gt; lines of its &lt;code&gt;Dockerfile&lt;/code&gt;. Docker has more documentation on
this subject — see the &lt;a href=&#34;http://localhost/userguide/dockerlinks&#34;&gt;linking Docker containers&lt;/a&gt;
page for further details.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
The value &lt;code&gt;CONTAINER_NAME&lt;/code&gt; in &lt;code&gt;--link=&lt;/code&gt; must either be an
auto-assigned Docker name like &lt;code&gt;stupefied_pare&lt;/code&gt; or else the name you
assigned with &lt;code&gt;--name=&lt;/code&gt; when you ran &lt;code&gt;docker run&lt;/code&gt;. It cannot be a
hostname, which Docker will not recognize in the context of the
&lt;code&gt;--link=&lt;/code&gt; option.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You can run the &lt;code&gt;iptables&lt;/code&gt; command on your Docker host to see whether
the &lt;code&gt;FORWARD&lt;/code&gt; chain has a default policy of &lt;code&gt;ACCEPT&lt;/code&gt; or &lt;code&gt;DROP&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# When --icc=false, you should see a DROP rule:
$ sudo iptables -L -n
...
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
...
# When a --link= has been created under --icc=false,
# you should see port-specific ACCEPT rules overriding
# the subsequent DROP policy for all other packets:
$ sudo iptables -L -n
...
Chain FORWARD (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0
DROP all -- 0.0.0.0/0 0.0.0.0/0
Chain DOCKER (1 references)
target prot opt source destination
ACCEPT tcp -- 172.17.0.2 172.17.0.3 tcp spt:80
ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
Docker is careful that its host-wide &lt;code&gt;iptables&lt;/code&gt; rules fully expose
containers to each other&amp;rsquo;s raw IP addresses, so connections from one
container to another should always appear to be originating from the
first container&amp;rsquo;s own IP address.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;binding-container-ports-to-the-host&#34;&gt;Binding container ports to the host&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;binding-ports&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By default Docker containers can make connections to the outside world,
but the outside world cannot connect to containers. Each outgoing
connection will appear to originate from one of the host machine&amp;rsquo;s own
IP addresses thanks to an &lt;code&gt;iptables&lt;/code&gt; masquerading rule on the host
machine that the Docker server creates when it starts:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# You can see that the Docker server creates a
# masquerade rule that let containers connect
# to IP addresses in the outside world:
$ sudo iptables -t nat -L -n
...
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
...
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But if you want containers to accept incoming connections, you will need
to provide special options when invoking &lt;code&gt;docker run&lt;/code&gt;. These options
are covered in more detail in the &lt;a href=&#34;http://localhost/userguide/dockerlinks&#34;&gt;Docker User Guide&lt;/a&gt;
page. There are two approaches.&lt;/p&gt;
&lt;p&gt;First, you can supply &lt;code&gt;-P&lt;/code&gt; or &lt;code&gt;--publish-all=true|false&lt;/code&gt; to &lt;code&gt;docker run&lt;/code&gt; which
is a blanket operation that identifies every port with an &lt;code&gt;EXPOSE&lt;/code&gt; line in the
image&amp;rsquo;s &lt;code&gt;Dockerfile&lt;/code&gt; or &lt;code&gt;--expose &amp;lt;port&amp;gt;&lt;/code&gt; commandline flag and maps it to a
host port somewhere within an &lt;em&gt;ephemeral port range&lt;/em&gt;. The &lt;code&gt;docker port&lt;/code&gt; command
then needs to be used to inspect created mapping. The &lt;em&gt;ephemeral port range&lt;/em&gt; is
configured by &lt;code&gt;/proc/sys/net/ipv4/ip_local_port_range&lt;/code&gt; kernel parameter,
typically ranging from 32768 to 61000.&lt;/p&gt;
&lt;p&gt;Mapping can be specified explicitly using &lt;code&gt;-p SPEC&lt;/code&gt; or &lt;code&gt;--publish=SPEC&lt;/code&gt; option.
It allows you to particularize which port on docker server - which can be any
port at all, not just one within the &lt;em&gt;ephemeral port range&lt;/em&gt; — you want mapped
to which port in the container.&lt;/p&gt;
&lt;p&gt;Either way, you should be able to peek at what Docker has accomplished
in your network stack by examining your NAT tables.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# What your NAT rules might look like when Docker
# is finished setting up a -P forward:
$ iptables -t nat -L -n
...
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80
# What your NAT rules might look like when Docker
# is finished setting up a -p 80:80 forward:
Chain DOCKER (2 references)
target prot opt source destination
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see that Docker has exposed these container ports on &lt;code&gt;0.0.0.0&lt;/code&gt;,
the wildcard IP address that will match any possible incoming port on
the host machine. If you want to be more restrictive and only allow
container services to be contacted through a specific external interface
on the host machine, you have two choices. When you invoke &lt;code&gt;docker run&lt;/code&gt;
you can use either &lt;code&gt;-p IP:host_port:container_port&lt;/code&gt; or &lt;code&gt;-p IP::port&lt;/code&gt; to
specify the external interface for one particular binding.&lt;/p&gt;
&lt;p&gt;Or if you always want Docker port forwards to bind to one specific IP
address, you can edit your system-wide Docker server settings and add the
option &lt;code&gt;--ip=IP_ADDRESS&lt;/code&gt;. Remember to restart your Docker server after
editing this setting.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;:
With hairpin NAT enabled (&lt;code&gt;--userland-proxy=false&lt;/code&gt;), containers port exposure
is achieved purely through iptables rules, and no attempt to bind the exposed
port is ever made. This means that nothing prevents shadowing a previously
listening service outside of Docker through exposing the same port for a
container. In such conflicting situation, Docker created iptables rules will
take precedence and route to the container.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The &lt;code&gt;--userland-proxy&lt;/code&gt; parameter, true by default, provides a userland
implementation for inter-container and outside-to-container communication. When
disabled, Docker uses both an additional &lt;code&gt;MASQUERADE&lt;/code&gt; iptable rule and the
&lt;code&gt;net.ipv4.route_localnet&lt;/code&gt; kernel parameter which allow the host machine to
connect to a local container exposed port through the commonly used loopback
address: this alternative is preferred for performance reason.&lt;/p&gt;
&lt;p&gt;Again, this topic is covered without all of these low-level networking
details in the &lt;a href=&#34;http://localhost/userguide/dockerlinks/&#34;&gt;Docker User Guide&lt;/a&gt; document if you
would like to use that as your port redirection reference instead.&lt;/p&gt;
&lt;h2 id=&#34;ipv6&#34;&gt;IPv6&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;ipv6&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As we are &lt;a href=&#34;http://en.wikipedia.org/wiki/IPv4_address_exhaustion&#34;&gt;running out of IPv4 addresses&lt;/a&gt;
the IETF has standardized an IPv4 successor, &lt;a href=&#34;http://en.wikipedia.org/wiki/IPv6&#34;&gt;Internet Protocol Version 6&lt;/a&gt;
, in &lt;a href=&#34;https://www.ietf.org/rfc/rfc2460.txt&#34;&gt;RFC 2460&lt;/a&gt;. Both protocols, IPv4 and
IPv6, reside on layer 3 of the &lt;a href=&#34;http://en.wikipedia.org/wiki/OSI_model&#34;&gt;OSI model&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;ipv6-with-docker&#34;&gt;IPv6 with Docker&lt;/h3&gt;
&lt;p&gt;By default, the Docker server configures the container network for IPv4 only.
You can enable IPv4/IPv6 dualstack support by running the Docker daemon with the
&lt;code&gt;--ipv6&lt;/code&gt; flag. Docker will set up the bridge &lt;code&gt;docker0&lt;/code&gt; with the IPv6
&lt;a href=&#34;http://en.wikipedia.org/wiki/Link-local_address&#34;&gt;link-local address&lt;/a&gt; &lt;code&gt;fe80::1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;By default, containers that are created will only get a link-local IPv6 address.
To assign globally routable IPv6 addresses to your containers you have to
specify an IPv6 subnet to pick the addresses from. Set the IPv6 subnet via the
&lt;code&gt;--fixed-cidr-v6&lt;/code&gt; parameter when starting Docker daemon:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker -d --ipv6 --fixed-cidr-v6=&amp;quot;2001:db8:1::/64&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The subnet for Docker containers should at least have a size of &lt;code&gt;/80&lt;/code&gt;. This way
an IPv6 address can end with the container&amp;rsquo;s MAC address and you prevent NDP
neighbor cache invalidation issues in the Docker layer.&lt;/p&gt;
&lt;p&gt;With the &lt;code&gt;--fixed-cidr-v6&lt;/code&gt; parameter set Docker will add a new route to the
routing table. Further IPv6 routing will be enabled (you may prevent this by
starting Docker daemon with &lt;code&gt;--ip-forward=false&lt;/code&gt;):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ip -6 route add 2001:db8:1::/64 dev docker0
$ sysctl net.ipv6.conf.default.forwarding=1
$ sysctl net.ipv6.conf.all.forwarding=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;All traffic to the subnet &lt;code&gt;2001:db8:1::/64&lt;/code&gt; will now be routed
via the &lt;code&gt;docker0&lt;/code&gt; interface.&lt;/p&gt;
&lt;p&gt;Be aware that IPv6 forwarding may interfere with your existing IPv6
configuration: If you are using Router Advertisements to get IPv6 settings for
your host&amp;rsquo;s interfaces you should set &lt;code&gt;accept_ra&lt;/code&gt; to &lt;code&gt;2&lt;/code&gt;. Otherwise IPv6
enabled forwarding will result in rejecting Router Advertisements. E.g., if you
want to configure &lt;code&gt;eth0&lt;/code&gt; via Router Advertisements you should set:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sysctl net.ipv6.conf.eth0.accept_ra=2
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/articles/article-img/ipv6_basic_host_config.svg&#34; alt=&#34;&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;Every new container will get an IPv6 address from the defined subnet. Further
a default route will be added on &lt;code&gt;eth0&lt;/code&gt; in the container via the address
specified by the daemon option &lt;code&gt;--default-gateway-v6&lt;/code&gt; if present, otherwise
via &lt;code&gt;fe80::1&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker run -it ubuntu bash -c &amp;quot;ip -6 addr show dev eth0; ip -6 route show&amp;quot;
15: eth0: &amp;lt;BROADCAST,UP,LOWER_UP&amp;gt; mtu 1500
inet6 2001:db8:1:0:0:242:ac11:3/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::42:acff:fe11:3/64 scope link
valid_lft forever preferred_lft forever
2001:db8:1::/64 dev eth0 proto kernel metric 256
fe80::/64 dev eth0 proto kernel metric 256
default via fe80::1 dev eth0 metric 1024
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;In this example the Docker container is assigned a link-local address with the
network suffix &lt;code&gt;/64&lt;/code&gt; (here: &lt;code&gt;fe80::42:acff:fe11:3/64&lt;/code&gt;) and a globally routable
IPv6 address (here: &lt;code&gt;2001:db8:1:0:0:242:ac11:3/64&lt;/code&gt;). The container will create
connections to addresses outside of the &lt;code&gt;2001:db8:1::/64&lt;/code&gt; network via the
link-local gateway at &lt;code&gt;fe80::1&lt;/code&gt; on &lt;code&gt;eth0&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Often servers or virtual machines get a &lt;code&gt;/64&lt;/code&gt; IPv6 subnet assigned (e.g.
&lt;code&gt;2001:db8:23:42::/64&lt;/code&gt;). In this case you can split it up further and provide
Docker a &lt;code&gt;/80&lt;/code&gt; subnet while using a separate &lt;code&gt;/80&lt;/code&gt; subnet for other
applications on the host:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/articles/article-img/ipv6_slash64_subnet_config.svg&#34; alt=&#34;&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;In this setup the subnet &lt;code&gt;2001:db8:23:42::/80&lt;/code&gt; with a range from &lt;code&gt;2001:db8:23:42:0:0:0:0&lt;/code&gt;
to &lt;code&gt;2001:db8:23:42:0:ffff:ffff:ffff&lt;/code&gt; is attached to &lt;code&gt;eth0&lt;/code&gt;, with the host listening
at &lt;code&gt;2001:db8:23:42::1&lt;/code&gt;. The subnet &lt;code&gt;2001:db8:23:42:1::/80&lt;/code&gt; with an address range from
&lt;code&gt;2001:db8:23:42:1:0:0:0&lt;/code&gt; to &lt;code&gt;2001:db8:23:42:1:ffff:ffff:ffff&lt;/code&gt; is attached to
&lt;code&gt;docker0&lt;/code&gt; and will be used by containers.&lt;/p&gt;
&lt;h4 id=&#34;using-ndp-proxying&#34;&gt;Using NDP proxying&lt;/h4&gt;
&lt;p&gt;If your Docker host is only part of an IPv6 subnet but has not got an IPv6
subnet assigned you can use NDP proxying to connect your containers via IPv6 to
the internet.
For example your host has the IPv6 address &lt;code&gt;2001:db8::c001&lt;/code&gt;, is part of the
subnet &lt;code&gt;2001:db8::/64&lt;/code&gt; and your IaaS provider allows you to configure the IPv6
addresses &lt;code&gt;2001:db8::c000&lt;/code&gt; to &lt;code&gt;2001:db8::c00f&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ip -6 addr show
1: lo: &amp;lt;LOOPBACK,UP,LOWER_UP&amp;gt; mtu 65536
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: &amp;lt;BROADCAST,MULTICAST,UP,LOWER_UP&amp;gt; mtu 1500 qlen 1000
inet6 2001:db8::c001/64 scope global
valid_lft forever preferred_lft forever
inet6 fe80::601:3fff:fea1:9c01/64 scope link
valid_lft forever preferred_lft forever
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Let&amp;rsquo;s split up the configurable address range into two subnets
&lt;code&gt;2001:db8::c000/125&lt;/code&gt; and &lt;code&gt;2001:db8::c008/125&lt;/code&gt;. The first one can be used by the
host itself, the latter by Docker:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker -d --ipv6 --fixed-cidr-v6 2001:db8::c008/125
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You notice the Docker subnet is within the subnet managed by your router that
is connected to &lt;code&gt;eth0&lt;/code&gt;. This means all devices (containers) with the addresses
from the Docker subnet are expected to be found within the router subnet.
Therefore the router thinks it can talk to these containers directly.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/articles/article-img/ipv6_ndp_proxying.svg&#34; alt=&#34;&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;As soon as the router wants to send an IPv6 packet to the first container it
will transmit a neighbor solicitation request, asking, who has
&lt;code&gt;2001:db8::c009&lt;/code&gt;? But it will get no answer because no one on this subnet has
this address. The container with this address is hidden behind the Docker host.
The Docker host has to listen to neighbor solicitation requests for the container
address and send a response that itself is the device that is responsible for
the address. This is done by a Kernel feature called &lt;code&gt;NDP Proxy&lt;/code&gt;. You can
enable it by executing&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ sysctl net.ipv6.conf.eth0.proxy_ndp=1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can add the container&amp;rsquo;s IPv6 address to the NDP proxy table:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ip -6 neigh add proxy 2001:db8::c009 dev eth0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This command tells the Kernel to answer to incoming neighbor solicitation requests
regarding the IPv6 address &lt;code&gt;2001:db8::c009&lt;/code&gt; on the device &lt;code&gt;eth0&lt;/code&gt;. As a
consequence of this all traffic to this IPv6 address will go into the Docker
host and it will forward it according to its routing table via the &lt;code&gt;docker0&lt;/code&gt;
device to the container network:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ ip -6 route show
2001:db8::c008/125 dev docker0 metric 1
2001:db8::/64 dev eth0 proto kernel metric 256
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You have to execute the &lt;code&gt;ip -6 neigh add proxy ...&lt;/code&gt; command for every IPv6
address in your Docker subnet. Unfortunately there is no functionality for
adding a whole subnet by executing one command.&lt;/p&gt;
&lt;h3 id=&#34;docker-ipv6-cluster&#34;&gt;Docker IPv6 cluster&lt;/h3&gt;
&lt;h4 id=&#34;switched-network-environment&#34;&gt;Switched network environment&lt;/h4&gt;
&lt;p&gt;Using routable IPv6 addresses allows you to realize communication between
containers on different hosts. Let&amp;rsquo;s have a look at a simple Docker IPv6 cluster
example:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/articles/article-img/ipv6_switched_network_example.svg&#34; alt=&#34;&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;The Docker hosts are in the &lt;code&gt;2001:db8:0::/64&lt;/code&gt; subnet. Host1 is configured
to provide addresses from the &lt;code&gt;2001:db8:1::/64&lt;/code&gt; subnet to its containers. It
has three routes configured:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:0::/64&lt;/code&gt; via &lt;code&gt;eth0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:1::/64&lt;/code&gt; via &lt;code&gt;docker0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:2::/64&lt;/code&gt; via Host2 with IP &lt;code&gt;2001:db8::2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Host1 also acts as a router on OSI layer 3. When one of the network clients
tries to contact a target that is specified in Host1&amp;rsquo;s routing table Host1 will
forward the traffic accordingly. It acts as a router for all networks it knows:
&lt;code&gt;2001:db8::/64&lt;/code&gt;, &lt;code&gt;2001:db8:1::/64&lt;/code&gt; and &lt;code&gt;2001:db8:2::/64&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;On Host2 we have nearly the same configuration. Host2&amp;rsquo;s containers will get
IPv6 addresses from &lt;code&gt;2001:db8:2::/64&lt;/code&gt;. Host2 has three routes configured:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:0::/64&lt;/code&gt; via &lt;code&gt;eth0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:2::/64&lt;/code&gt; via &lt;code&gt;docker0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Route all traffic to &lt;code&gt;2001:db8:1::/64&lt;/code&gt; via Host1 with IP &lt;code&gt;2001:db8:0::1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The difference to Host1 is that the network &lt;code&gt;2001:db8:2::/64&lt;/code&gt; is directly
attached to the host via its &lt;code&gt;docker0&lt;/code&gt; interface whereas it reaches
&lt;code&gt;2001:db8:1::/64&lt;/code&gt; via Host1&amp;rsquo;s IPv6 address &lt;code&gt;2001:db8::1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This way every container is able to contact every other container. The
containers &lt;code&gt;Container1-*&lt;/code&gt; share the same subnet and contact each other directly.
The traffic between &lt;code&gt;Container1-*&lt;/code&gt; and &lt;code&gt;Container2-*&lt;/code&gt; will be routed via Host1
and Host2 because those containers do not share the same subnet.&lt;/p&gt;
&lt;p&gt;In a switched environment every host has to know all routes to every subnet. You
always have to update the hosts&amp;rsquo; routing tables once you add or remove a host
to the cluster.&lt;/p&gt;
&lt;p&gt;Every configuration in the diagram that is shown below the dashed line is
handled by Docker: The &lt;code&gt;docker0&lt;/code&gt; bridge IP address configuration, the route to
the Docker subnet on the host, the container IP addresses and the routes on the
containers. The configuration above the line is up to the user and can be
adapted to the individual environment.&lt;/p&gt;
&lt;h4 id=&#34;routed-network-environment&#34;&gt;Routed network environment&lt;/h4&gt;
&lt;p&gt;In a routed network environment you replace the layer 2 switch with a layer 3
router. Now the hosts just have to know their default gateway (the router) and
the route to their own containers (managed by Docker). The router holds all
routing information about the Docker subnets. When you add or remove a host to
this environment you just have to update the routing table in the router - not
on every host.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;http://localhost/articles/articles/article-img/ipv6_routed_network_example.svg&#34; alt=&#34;&#34; /&gt;
&lt;/p&gt;
&lt;p&gt;In this scenario containers of the same host can communicate directly with each
other. The traffic between containers on different hosts will be routed via
their hosts and the router. For example packet from &lt;code&gt;Container1-1&lt;/code&gt; to
&lt;code&gt;Container2-1&lt;/code&gt; will be routed through &lt;code&gt;Host1&lt;/code&gt;, &lt;code&gt;Router&lt;/code&gt; and &lt;code&gt;Host2&lt;/code&gt; until it
arrives at &lt;code&gt;Container2-1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;To keep the IPv6 addresses short in this example a &lt;code&gt;/48&lt;/code&gt; network is assigned to
every host. The hosts use a &lt;code&gt;/64&lt;/code&gt; subnet of this for its own services and one
for Docker. When adding a third host you would add a route for the subnet
&lt;code&gt;2001:db8:3::/48&lt;/code&gt; in the router and configure Docker on Host3 with
&lt;code&gt;--fixed-cidr-v6=2001:db8:3:1::/64&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Remember the subnet for Docker containers should at least have a size of &lt;code&gt;/80&lt;/code&gt;.
This way an IPv6 address can end with the container&amp;rsquo;s MAC address and you
prevent NDP neighbor cache invalidation issues in the Docker layer. So if you
have a &lt;code&gt;/64&lt;/code&gt; for your whole environment use &lt;code&gt;/78&lt;/code&gt; subnets for the hosts and
&lt;code&gt;/80&lt;/code&gt; for the containers. This way you can use 4096 hosts with 16 &lt;code&gt;/80&lt;/code&gt; subnets
each.&lt;/p&gt;
&lt;p&gt;Every configuration in the diagram that is visualized below the dashed line is
handled by Docker: The &lt;code&gt;docker0&lt;/code&gt; bridge IP address configuration, the route to
the Docker subnet on the host, the container IP addresses and the routes on the
containers. The configuration above the line is up to the user and can be
adapted to the individual environment.&lt;/p&gt;
&lt;h2 id=&#34;customizing-docker0&#34;&gt;Customizing docker0&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;docker0&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By default, the Docker server creates and configures the host system&amp;rsquo;s
&lt;code&gt;docker0&lt;/code&gt; interface as an &lt;em&gt;Ethernet bridge&lt;/em&gt; inside the Linux kernel that
can pass packets back and forth between other physical or virtual
network interfaces so that they behave as a single Ethernet network.&lt;/p&gt;
&lt;p&gt;Docker configures &lt;code&gt;docker0&lt;/code&gt; with an IP address, netmask and IP
allocation range. The host machine can both receive and send packets to
containers connected to the bridge, and gives it an MTU — the &lt;em&gt;maximum
transmission unit&lt;/em&gt; or largest packet length that the interface will
allow — of either 1,500 bytes or else a more specific value copied from
the Docker host&amp;rsquo;s interface that supports its default route. These
options are configurable at server startup:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--bip=CIDR&lt;/code&gt; — supply a specific IP address and netmask for the
&lt;code&gt;docker0&lt;/code&gt; bridge, using standard CIDR notation like
&lt;code&gt;192.168.1.5/24&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--fixed-cidr=CIDR&lt;/code&gt; — restrict the IP range from the &lt;code&gt;docker0&lt;/code&gt; subnet,
using the standard CIDR notation like &lt;code&gt;172.167.1.0/28&lt;/code&gt;. This range must
be and IPv4 range for fixed IPs (ex: 10.20.0.0/16) and must be a subset
of the bridge IP range (&lt;code&gt;docker0&lt;/code&gt; or set using &lt;code&gt;--bridge&lt;/code&gt;). For example
with &lt;code&gt;--fixed-cidr=192.168.1.0/25&lt;/code&gt;, IPs for your containers will be chosen
from the first half of &lt;code&gt;192.168.1.0/24&lt;/code&gt; subnet.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--mtu=BYTES&lt;/code&gt; — override the maximum packet length on &lt;code&gt;docker0&lt;/code&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once you have one or more containers up and running, you can confirm
that Docker has properly connected them to the &lt;code&gt;docker0&lt;/code&gt; bridge by
running the &lt;code&gt;brctl&lt;/code&gt; command on the host machine and looking at the
&lt;code&gt;interfaces&lt;/code&gt; column of the output. Here is a host with two different
containers connected:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Display bridge info
$ sudo brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.3a1d7362b4ee no veth65f9
vethdda6
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If the &lt;code&gt;brctl&lt;/code&gt; command is not installed on your Docker host, then on
Ubuntu you should be able to run &lt;code&gt;sudo apt-get install bridge-utils&lt;/code&gt; to
install it.&lt;/p&gt;
&lt;p&gt;Finally, the &lt;code&gt;docker0&lt;/code&gt; Ethernet bridge settings are used every time you
create a new container. Docker selects a free IP address from the range
available on the bridge each time you &lt;code&gt;docker run&lt;/code&gt; a new container, and
configures the container&amp;rsquo;s &lt;code&gt;eth0&lt;/code&gt; interface with that IP address and the
bridge&amp;rsquo;s netmask. The Docker host&amp;rsquo;s own IP address on the bridge is
used as the default gateway by which each container reaches the rest of
the Internet.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# The network, as seen from a container
$ docker run -i -t --rm base /bin/bash
$$ ip addr show eth0
24: eth0: &amp;lt;BROADCAST,UP,LOWER_UP&amp;gt; mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
link/ether 32:6f:e0:35:57:91 brd ff:ff:ff:ff:ff:ff
inet 172.17.0.3/16 scope global eth0
valid_lft forever preferred_lft forever
inet6 fe80::306f:e0ff:fe35:5791/64 scope link
valid_lft forever preferred_lft forever
$$ ip route
default via 172.17.42.1 dev eth0
172.17.0.0/16 dev eth0 proto kernel scope link src 172.17.0.3
$$ exit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember that the Docker host will not be willing to forward container
packets out on to the Internet unless its &lt;code&gt;ip_forward&lt;/code&gt; system setting is
&lt;code&gt;1&lt;/code&gt; — see the section above on &lt;a href=&#34;#between-containers&#34;&gt;Communication between
containers&lt;/a&gt; for details.&lt;/p&gt;
&lt;h2 id=&#34;building-your-own-bridge&#34;&gt;Building your own bridge&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;bridge-building&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to take Docker out of the business of creating its own
Ethernet bridge entirely, you can set up your own bridge before starting
Docker and use &lt;code&gt;-b BRIDGE&lt;/code&gt; or &lt;code&gt;--bridge=BRIDGE&lt;/code&gt; to tell Docker to use
your bridge instead. If you already have Docker up and running with its
old &lt;code&gt;docker0&lt;/code&gt; still configured, you will probably want to begin by
stopping the service and removing the interface:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Stopping Docker and removing docker0
$ sudo service docker stop
$ sudo ip link set dev docker0 down
$ sudo brctl delbr docker0
$ sudo iptables -t nat -F POSTROUTING
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, before starting the Docker service, create your own bridge and
give it whatever configuration you want. Here we will create a simple
enough bridge that we really could just have used the options in the
previous section to customize &lt;code&gt;docker0&lt;/code&gt;, but it will be enough to
illustrate the technique.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Create our own bridge
$ sudo brctl addbr bridge0
$ sudo ip addr add 192.168.5.1/24 dev bridge0
$ sudo ip link set dev bridge0 up
# Confirming that our bridge is up and running
$ ip addr show bridge0
4: bridge0: &amp;lt;BROADCAST,MULTICAST&amp;gt; mtu 1500 qdisc noop state UP group default
link/ether 66:38:d0:0d:76:18 brd ff:ff:ff:ff:ff:ff
inet 192.168.5.1/24 scope global bridge0
valid_lft forever preferred_lft forever
# Tell Docker about it and restart (on Ubuntu)
$ echo &#39;DOCKER_OPTS=&amp;quot;-b=bridge0&amp;quot;&#39; &amp;gt;&amp;gt; /etc/default/docker
$ sudo service docker start
# Confirming new outgoing NAT masquerade is set up
$ sudo iptables -t nat -L -n
...
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 192.168.5.0/24 0.0.0.0/0
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The result should be that the Docker server starts successfully and is
now prepared to bind containers to the new bridge. After pausing to
verify the bridge&amp;rsquo;s configuration, try creating a container — you will
see that its IP address is in your new IP address range, which Docker
will have auto-detected.&lt;/p&gt;
&lt;p&gt;Just as we learned in the previous section, you can use the &lt;code&gt;brctl show&lt;/code&gt;
command to see Docker add and remove interfaces from the bridge as you
start and stop containers, and can run &lt;code&gt;ip addr&lt;/code&gt; and &lt;code&gt;ip route&lt;/code&gt; inside a
container to see that it has been given an address in the bridge&amp;rsquo;s IP
address range and has been told to use the Docker host&amp;rsquo;s IP address on
the bridge as its default gateway to the rest of the Internet.&lt;/p&gt;
&lt;h2 id=&#34;how-docker-networks-a-container&#34;&gt;How Docker networks a container&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;container-networking&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;While Docker is under active development and continues to tweak and
improve its network configuration logic, the shell commands in this
section are rough equivalents to the steps that Docker takes when
configuring networking for each new container.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s review a few basics.&lt;/p&gt;
&lt;p&gt;To communicate using the Internet Protocol (IP), a machine needs access
to at least one network interface at which packets can be sent and
received, and a routing table that defines the range of IP addresses
reachable through that interface. Network interfaces do not have to be
physical devices. In fact, the &lt;code&gt;lo&lt;/code&gt; loopback interface available on
every Linux machine (and inside each Docker container) is entirely
virtual — the Linux kernel simply copies loopback packets directly from
the sender&amp;rsquo;s memory into the receiver&amp;rsquo;s memory.&lt;/p&gt;
&lt;p&gt;Docker uses special virtual interfaces to let containers communicate
with the host machine — pairs of virtual interfaces called “peers” that
are linked inside of the host machine&amp;rsquo;s kernel so that packets can
travel between them. They are simple to create, as we will see in a
moment.&lt;/p&gt;
&lt;p&gt;The steps with which Docker configures a container are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Create a pair of peer virtual interfaces.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give one of them a unique name like &lt;code&gt;veth65f9&lt;/code&gt;, keep it inside of
the main Docker host, and bind it to &lt;code&gt;docker0&lt;/code&gt; or whatever bridge
Docker is supposed to be using.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Toss the other interface over the wall into the new container (which
will already have been provided with an &lt;code&gt;lo&lt;/code&gt; interface) and rename
it to the much prettier name &lt;code&gt;eth0&lt;/code&gt; since, inside of the container&amp;rsquo;s
separate and unique network interface namespace, there are no
physical interfaces with which this name could collide.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set the interface&amp;rsquo;s MAC address according to the &lt;code&gt;--mac-address&lt;/code&gt;
parameter or generate a random one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Give the container&amp;rsquo;s &lt;code&gt;eth0&lt;/code&gt; a new IP address from within the
bridge&amp;rsquo;s range of network addresses. The default route is set to the
IP address passed to the Docker daemon using the &lt;code&gt;--default-gateway&lt;/code&gt;
option if specified, otherwise to the IP address that the Docker host
owns on the bridge. The MAC address is generated from the IP address
unless otherwise specified. This prevents ARP cache invalidation
problems, when a new container comes up with an IP used in the past by
another container with another MAC.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;With these steps complete, the container now possesses an &lt;code&gt;eth0&lt;/code&gt;
(virtual) network card and will find itself able to communicate with
other containers and the rest of the Internet.&lt;/p&gt;
&lt;p&gt;You can opt out of the above process for a particular container by
giving the &lt;code&gt;--net=&lt;/code&gt; option to &lt;code&gt;docker run&lt;/code&gt;, which takes four possible
values.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--net=bridge&lt;/code&gt; — The default action, that connects the container to
the Docker bridge as described above.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--net=host&lt;/code&gt; — Tells Docker to skip placing the container inside of
a separate network stack. In essence, this choice tells Docker to
&lt;strong&gt;not containerize the container&amp;rsquo;s networking&lt;/strong&gt;! While container
processes will still be confined to their own filesystem and process
list and resource limits, a quick &lt;code&gt;ip addr&lt;/code&gt; command will show you
that, network-wise, they live “outside” in the main Docker host and
have full access to its network interfaces. Note that this does
&lt;strong&gt;not&lt;/strong&gt; let the container reconfigure the host network stack — that
would require &lt;code&gt;--privileged=true&lt;/code&gt; — but it does let container
processes open low-numbered ports like any other root process.
It also allows the container to access local network services
like D-bus. This can lead to processes in the container being
able to do unexpected things like
&lt;a href=&#34;https://github.com/docker/docker/issues/6401&#34;&gt;restart your computer&lt;/a&gt;.
You should use this option with caution.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--net=container:NAME_or_ID&lt;/code&gt; — Tells Docker to put this container&amp;rsquo;s
processes inside of the network stack that has already been created
inside of another container. The new container&amp;rsquo;s processes will be
confined to their own filesystem and process list and resource
limits, but will share the same IP address and port numbers as the
first container, and processes on the two containers will be able to
connect to each other over the loopback interface.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;--net=none&lt;/code&gt; — Tells Docker to put the container inside of its own
network stack but not to take any steps to configure its network,
leaving you free to build any of the custom configurations explored
in the last few sections of this document.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To get an idea of the steps that are necessary if you use &lt;code&gt;--net=none&lt;/code&gt;
as described in that last bullet point, here are the commands that you
would run to reach roughly the same configuration as if you had let
Docker do all of the configuration:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# At one shell, start a container and
# leave its shell idle and running
$ docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#
# At another shell, learn the container process ID
# and create its namespace entry in /var/run/netns/
# for the &amp;quot;ip netns&amp;quot; command we will be using below
$ docker inspect -f &#39;{{.State.Pid}}&#39; 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
# Check the bridge&#39;s IP address and netmask
$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...
# Create a pair of &amp;quot;peer&amp;quot; interfaces A and B,
# bind the A end to the bridge, and bring it up
$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up
# Place B inside the container&#39;s network namespace,
# rename to eth0, and activate it with a free IP
$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At this point your container should be able to perform networking
operations as usual.&lt;/p&gt;
&lt;p&gt;When you finally exit the shell and Docker cleans up the container, the
network namespace is destroyed along with our virtual &lt;code&gt;eth0&lt;/code&gt; — whose
destruction in turn destroys interface &lt;code&gt;A&lt;/code&gt; out in the Docker host and
automatically un-registers it from the &lt;code&gt;docker0&lt;/code&gt; bridge. So everything
gets cleaned up without our having to run any extra commands! Well,
almost everything:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Clean up dangling symlinks in /var/run/netns
find -L /var/run/netns -type l -delete
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also note that while the script above used modern &lt;code&gt;ip&lt;/code&gt; command instead
of old deprecated wrappers like &lt;code&gt;ipconfig&lt;/code&gt; and &lt;code&gt;route&lt;/code&gt;, these older
commands would also have worked inside of our container. The &lt;code&gt;ip addr&lt;/code&gt;
command can be typed as &lt;code&gt;ip a&lt;/code&gt; if you are in a hurry.&lt;/p&gt;
&lt;p&gt;Finally, note the importance of the &lt;code&gt;ip netns exec&lt;/code&gt; command, which let
us reach inside and configure a network namespace as root. The same
commands would not have worked if run inside of the container, because
part of safe containerization is that Docker strips container processes
of the right to configure their own networks. Using &lt;code&gt;ip netns exec&lt;/code&gt; is
what let us finish up the configuration without having to take the
dangerous step of running the container itself with &lt;code&gt;--privileged=true&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id=&#34;tools-and-examples&#34;&gt;Tools and examples&lt;/h2&gt;
&lt;p&gt;Before diving into the following sections on custom network topologies,
you might be interested in glancing at a few external tools or examples
of the same kinds of configuration. Here are two:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Jérôme Petazzoni has created a &lt;code&gt;pipework&lt;/code&gt; shell script to help you
connect together containers in arbitrarily complex scenarios:
&lt;a href=&#34;https://github.com/jpetazzo/pipework&#34;&gt;https://github.com/jpetazzo/pipework&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Brandon Rhodes has created a whole network topology of Docker
containers for the next edition of Foundations of Python Network
Programming that includes routing, NAT&amp;rsquo;d firewalls, and servers that
offer HTTP, SMTP, POP, IMAP, Telnet, SSH, and FTP:
&lt;a href=&#34;https://github.com/brandon-rhodes/fopnp/tree/m/playground&#34;&gt;https://github.com/brandon-rhodes/fopnp/tree/m/playground&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both tools use networking commands very much like the ones you saw in
the previous section, and will see in the following sections.&lt;/p&gt;
&lt;h2 id=&#34;building-a-point-to-point-connection&#34;&gt;Building a point-to-point connection&lt;/h2&gt;
&lt;p&gt;&lt;a name=&#34;point-to-point&#34;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By default, Docker attaches all containers to the virtual subnet
implemented by &lt;code&gt;docker0&lt;/code&gt;. You can create containers that are each
connected to some different virtual subnet by creating your own bridge
as shown in &lt;a href=&#34;#bridge-building&#34;&gt;Building your own bridge&lt;/a&gt;, starting each
container with &lt;code&gt;docker run --net=none&lt;/code&gt;, and then attaching the
containers to your bridge with the shell commands shown in &lt;a href=&#34;#container-networking&#34;&gt;How Docker
networks a container&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But sometimes you want two particular containers to be able to
communicate directly without the added complexity of both being bound to
a host-wide Ethernet bridge.&lt;/p&gt;
&lt;p&gt;The solution is simple: when you create your pair of peer interfaces,
simply throw &lt;em&gt;both&lt;/em&gt; of them into containers, and configure them as
classic point-to-point links. The two containers will then be able to
communicate directly (provided you manage to tell each container the
other&amp;rsquo;s IP address, of course). You might adjust the instructions of
the previous section to go something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;# Start up two containers in two terminal windows
$ docker run -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/#
$ docker run -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/#
# Learn the container process IDs
# and create their namespace entries
$ docker inspect -f &#39;{{.State.Pid}}&#39; 1f1f4c1f931a
2989
$ docker inspect -f &#39;{{.State.Pid}}&#39; 12e343489d2f
3004
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/2989/ns/net /var/run/netns/2989
$ sudo ln -s /proc/3004/ns/net /var/run/netns/3004
# Create the &amp;quot;peer&amp;quot; interfaces and hand them out
$ sudo ip link add A type veth peer name B
$ sudo ip link set A netns 2989
$ sudo ip netns exec 2989 ip addr add 10.1.1.1/32 dev A
$ sudo ip netns exec 2989 ip link set A up
$ sudo ip netns exec 2989 ip route add 10.1.1.2/32 dev A
$ sudo ip link set B netns 3004
$ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netns exec 3004 ip link set B up
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The two containers should now be able to ping each other and make
connections successfully. Point-to-point links like this do not depend
on a subnet nor a netmask, but on the bare assertion made by &lt;code&gt;ip route&lt;/code&gt;
that some other single IP address is connected to a particular network
interface.&lt;/p&gt;
&lt;p&gt;Note that point-to-point links can be safely combined with other kinds
of network connectivity — there is no need to start the containers with
&lt;code&gt;--net=none&lt;/code&gt; if you want point-to-point links to be an addition to the
container&amp;rsquo;s normal networking instead of a replacement.&lt;/p&gt;
&lt;p&gt;A final permutation of this pattern is to create the point-to-point link
between the Docker host and one container, which would allow the host to
communicate with that one container on some single IP address and thus
communicate “out-of-band” of the bridge that connects the other, more
usual containers. But unless you have very specific networking needs
that drive you to such a solution, it is probably far preferable to use
&lt;code&gt;--icc=false&lt;/code&gt; to lock down inter-container communication, as we explored
earlier.&lt;/p&gt;
&lt;h2 id=&#34;editing-networking-config-files&#34;&gt;Editing networking config files&lt;/h2&gt;
&lt;p&gt;Starting with Docker v.1.2.0, you can now edit &lt;code&gt;/etc/hosts&lt;/code&gt;, &lt;code&gt;/etc/hostname&lt;/code&gt;
and &lt;code&gt;/etc/resolve.conf&lt;/code&gt; in a running container. This is useful if you need
to install bind or other services that might override one of those files.&lt;/p&gt;
&lt;p&gt;Note, however, that changes to these files will not be saved by
&lt;code&gt;docker commit&lt;/code&gt;, nor will they be saved during &lt;code&gt;docker run&lt;/code&gt;.
That means they won&amp;rsquo;t be saved in the image, nor will they persist when a
container is restarted; they will only &amp;ldquo;stick&amp;rdquo; in a running container.&lt;/p&gt;
</description>
</item>
<item>
<title>Using Puppet</title>
<link>http://localhost/articles/puppet/</link>
<pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
<guid>http://localhost/articles/puppet/</guid>
<description>
&lt;h1 id=&#34;using-puppet&#34;&gt;Using Puppet&lt;/h1&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt; Please note this is a community contributed installation path. The
only &lt;code&gt;official&lt;/code&gt; installation is using the
&lt;a href=&#34;http://localhost/articles/articles/installation/ubuntulinux&#34;&gt;&lt;em&gt;Ubuntu&lt;/em&gt;&lt;/a&gt; installation
path. This version may sometimes be out of date.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;requirements&#34;&gt;Requirements&lt;/h2&gt;
&lt;p&gt;To use this guide you&amp;rsquo;ll need a working installation of Puppet from
&lt;a href=&#34;https://puppetlabs.com&#34;&gt;Puppet Labs&lt;/a&gt; .&lt;/p&gt;
&lt;p&gt;The module also currently uses the official PPA so only works with
Ubuntu.&lt;/p&gt;
&lt;h2 id=&#34;installation&#34;&gt;Installation&lt;/h2&gt;
&lt;p&gt;The module is available on the &lt;a href=&#34;https://forge.puppetlabs.com/garethr/docker/&#34;&gt;Puppet
Forge&lt;/a&gt; and can be
installed using the built-in module tool.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ puppet module install garethr/docker
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It can also be found on
&lt;a href=&#34;https://github.com/garethr/garethr-docker&#34;&gt;GitHub&lt;/a&gt; if you would rather
download the source.&lt;/p&gt;
&lt;h2 id=&#34;usage&#34;&gt;Usage&lt;/h2&gt;
&lt;p&gt;The module provides a puppet class for installing Docker and two defined
types for managing images and containers.&lt;/p&gt;
&lt;h3 id=&#34;installation-1&#34;&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code&gt;include &#39;docker&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;images&#34;&gt;Images&lt;/h3&gt;
&lt;p&gt;The next step is probably to install a Docker image. For this, we have a
defined type which can be used like so:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker::image { &#39;ubuntu&#39;: }
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is equivalent to running:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker pull ubuntu
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Note that it will only be downloaded if an image of that name does not
already exist. This is downloading a large binary so on first run can
take a while. For that reason this define turns off the default 5 minute
timeout for the exec type. Note that you can also remove images you no
longer need with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker::image { &#39;ubuntu&#39;:
ensure =&amp;gt; &#39;absent&#39;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&#34;containers&#34;&gt;Containers&lt;/h3&gt;
&lt;p&gt;Now you have an image where you can run commands within a container
managed by Docker.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker::run { &#39;helloworld&#39;:
image =&amp;gt; &#39;ubuntu&#39;,
command =&amp;gt; &#39;/bin/sh -c &amp;quot;while true; do echo hello world; sleep 1; done&amp;quot;&#39;,
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is equivalent to running the following command, but under upstart:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ docker run -d ubuntu /bin/sh -c &amp;quot;while true; do echo hello world; sleep 1; done&amp;quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run also contains a number of optional parameters:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;docker::run { &#39;helloworld&#39;:
image =&amp;gt; &#39;ubuntu&#39;,
command =&amp;gt; &#39;/bin/sh -c &amp;quot;while true; do echo hello world; sleep 1; done&amp;quot;&#39;,
ports =&amp;gt; [&#39;4444&#39;, &#39;4555&#39;],
volumes =&amp;gt; [&#39;/var/lib/couchdb&#39;, &#39;/var/log&#39;],
volumes_from =&amp;gt; &#39;6446ea52fbc9&#39;,
memory_limit =&amp;gt; 10485760, # bytes
username =&amp;gt; &#39;example&#39;,
hostname =&amp;gt; &#39;example.com&#39;,
env =&amp;gt; [&#39;FOO=BAR&#39;, &#39;FOO2=BAR2&#39;],
dns =&amp;gt; [&#39;8.8.8.8&#39;, &#39;8.8.4.4&#39;],
}
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note:&lt;/em&gt;
The &lt;code&gt;ports&lt;/code&gt;, &lt;code&gt;env&lt;/code&gt;, &lt;code&gt;dns&lt;/code&gt; and &lt;code&gt;volumes&lt;/code&gt; attributes can be set with either a single
string or as above with an array of values.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
</item>
</channel>
</rss>