Browse files

first commit, yo!

  • Loading branch information...
jpetazzo committed Aug 19, 2013
0 parents commit bfbe19c0eec634f66c9f8bac53c6b7c7e0fdb063
Showing with 153 additions and 0 deletions.
  1. +1 −0 .gitignore
  2. +13 −0 Dockerfile
  3. +87 −0
  4. BIN spintop.jpg
  5. +52 −0 wrapdocker
@@ -0,0 +1 @@
@@ -0,0 +1,13 @@
FROM ubuntu
RUN echo deb precise universe > /etc/apt/sources.list.d/universe.list
RUN apt-get update -qq
RUN apt-get install -qqy iptables ca-certificates lxc
# This will use the latest public release. To use your own, comment it out...
ADD /usr/local/bin/docker
# ...then uncomment the following line, and copy your docker binary to current dir.
#ADD ./docker /usr/local/bin/docker
ADD ./wrapdocker /usr/local/bin/wrapdocker
RUN chmod +x /usr/local/bin/docker /usr/local/bin/wrapdocker
VOLUME /var/lib/docker
CMD wrapdocker
@@ -0,0 +1,87 @@
# Docker-in-Docker
This recipe lets you run Docker within Docker.
![Inception's Spinning Top](spintop.jpg)
There is only one requirement: your Docker version should support the
`-privileged` flag.
## Quickstart
Build the image:
docker build -t dind .
Run Docker-in-Docker and get a shell where you can play:
docker run -privileged -t -i dind
Run Docker-in-Docker and expose the inside Docker to the outside world:
docker run -privileged -d -p 4444 -e PORT=4444 dind
Note: when started with the `PORT` environment variable, the image will just
the Docker daemon and expose it over said port. When started *without* the
`PORT` environment variable, the image will run the Docker daemon in the
background and execute a shell for you to play.
## How It Works
The main trick is to have the `-privileged` flag. Then, there are a few things
to care about:
- cgroups have to be properly mounted; this is done by the default entrypoint,
in a way inspired by `cgroups-mount`;
- `/var/lib/docker` cannot be on AUFS, so we make it a volume.
That's it.
## Important Warning About Disk Usage
Since AUFS cannot use an AUFS mount as a branch, it means that we have to
use a volume. Therefore, all inner Docker data (images, containers, etc.)
will be in the volume. Remember: volumes are not cleaned up when you
`docker rm`, so if you wonder where did your disk space go after nesting
10 Dockers within each other, look no further :-)
## Which Version Of Docker Does It Run?
Outside: it will use your installed version.
Inside: the Dockerfile will retrieve the latest `docker` binary from; so if you want to include *your* own `docker`
build, you will have to edit it. If you want to always use your local
version, you could change the `ADD` line to be e.g.:
ADD /usr/bin/docker /usr/local/bin/docker
## Can I Run Docker-in-Docker-in-Docker?
Yes. Note, however, that there seems to be a weird FD leakage issue.
To work around it, the `wrapdocker` script carefully closes all the
file descriptors inherited from the parent Docker and `lxc-start`
(except stdio). I'm mentioning this in case you were relying on
those inherited file descriptors, or if you're trying to repeat
the experiment at home.
Also, when you will be exiting a nested Docker, this will happen:
root@975423921ac5:/# exit
root@6b2ae8bf2f10:/# exit
root@419a67dfdf27:/# exit
root@bc9f450caf22:/# exit
At that point, you should blast Hans Zimmer's [Dream Is Collapsing]( on your loudspeakers while twirling
a spinning top.
Binary file not shown.
@@ -0,0 +1,52 @@
# First, make sure that cgroups are mounted correctly.
[ -d $CGROUP ] ||
mkdir $CGROUP
mountpoint -q $CGROUP ||
mount -n -t tmpfs -o uid=0,gid=0,mode=0755 cgroup $CGROUP || {
echo "Could not make a tmpfs mount. Did you use -privileged?"
exit 1
[ "$ENABLED" = 0 ] && continue
[ "$ENABLED" = enabled ] && continue
# Those guys are special. Let's skip them for now.
[ "$SUBSYS" = cpu ] && continue
[ "$SUBSYS" = cpuacct ] && continue
mountpoint -q $CGROUP/$SUBSYS ||
mount -n -t cgroup -o $SUBSYS cgroup $CGROUP/$SUBSYS
done </proc/cgroups
# Now, close extraneous file descriptors.
pushd /proc/self/fd
for FD in *
case "$FD" in
# Keep stdin/stdout/stderr
# Nuke everything else
eval exec "$FD>&-"
# If we were given a PORT environment variable, start as a simple daemon;
# otherwise, spawn a shell as well
if [ "$PORT" ]
exec docker -d -H$PORT
docker -d &
exec bash

0 comments on commit bfbe19c

Please sign in to comment.