itentidock example from O'Reilly _Using Docker_
Python Shell
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


itentidock example app from

cover Using Docker by Adrian Mouat

Examples below are using boot2docker on Mac running OS X 10.10.3.

It might be helpful to refer to these Docker User Guide docs once you get stuck:

Step 1. Simple Hello World


Using this Dockerfile.

  • Example of using the code bundled inside the identidock image within the container.
docker build -t identidock .
DID=$(docker run -d -p 5000:5000 identidock)
curl $(boot2docker ip):5000 # expect Hello World!
docker rm -f $DID
  • Example of using the code in our current directory referenced as volume bind mounted in identidock container, occluding the code bundled inside the image.
DID=$(docker run -d -p 5000:5000 -v $(pwd)/app:/app identidock)
curl $(boot2docker ip):5000 # expect Hello World!
sed -i s/World/Docker/ app/ # undo this change after the test
curl $(boot2docker ip):5000 # expect Hello Docker!
docker rm -f $DID

Step 2 add uWSGI

Using this Dockerfile.

  • Start new uwsgi tagged instance of identidock docker image.
docker build -t identidock:uwsgi .
DID=$(docker run -d -p 9090:9090 -p 9191:9191 identidock:uwsgi)
curl $(boot2docker ip):9090          # expect Hello World!
curl $(boot2docker ip):9191          # expect JSON block of stats
docker logs $DID 2>&1 | grep WARNING # expect to get yelled at for using root
docker rm -f $DID

BTW Here are the images we have made at this point. Not that lastest is from step 1 and uwsgi is from step 2:

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
identidock          uwsgi               cf36ee739e9c        12 minutes ago      767.2 MB
identidock          latest              fd04dbc88df1        43 minutes ago      765.1 MB

Step 3 Run uWSGI as someone other than root and auto-map ports

Using this Dockerfile run the container as uwsgi user and designate ports in Dockerfile instead of on the command line.

docker build -t identidock:user .
docker run identidock:uwsgi whoami
docker run identidock:user whoami
DID=$(docker run -d -P --name port-test identidock:user)
docker port port-test
9090/tcp ->
9191/tcp ->
curl $(boot2docker ip):32768
Hello World!

Step 4 Delegate app start to cmd shell script which determines environment first


Using this Dockerfile build and run a dev instance of identidock.

docker build -t identidock:cmd .
DID=$(docker run -e "ENV=DEV" -d -P identidock:cmd)
docker port $DID
5000/tcp ->
9090/tcp ->
9191/tcp ->
# curl port 5000 in the container
curl $(boot2docker ip):32782
Hello World!
# there is nothing listening on 9090 in this container
curl $(boot2docker ip):32783
curl: (7) Failed to connect to port 32783: Connection refused

Now stop that container and run a production instance.

docker rm -f $DID
DID=$(docker run -e "ENV=PROD" -d -P identidock:cmd)
docker port $DID
9191/tcp ->
5000/tcp ->
9090/tcp ->
# there is nothing listening on 5000 in this container
curl $(boot2docker ip):32785
curl: (7) Failed to connect to port 32785: Connection refused
# curl port 9090 in the container
curl $(boot2docker ip):32786
Hello World!
# shortcut
curl $(boot2docker ip):$(docker port $DID 9090 | cut -d: -f2)
Hello World!

The cut in the shortcut above is needed since docker port returns something like I there a better way to do that?

Step 5 Use docker-compose to launch container

Install docker-compose before continuing.

curl -o docker-compose -L`uname -s`-`uname -m`
chmod 755 docker-compose
sudo mv docker-compose /usr/local/bin
docker-compose --help
Illegal instruction: 4

Oh no! It didn't work!

It turns out that you can pip install docker-compose to work around this.

brew update
brew install python
pip install docker-compose

Create a docker-compose.yml which looks like this.

  build: .
    - "5000:5000"
    ENV: DEV
    - ./app:/app

Now, start up the container.

docker-compose up

Using docker-compose v1.2.0, I got a python traceback:

Successfully built bb9620f3a5b1
Attaching to identidock_identidock_1
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 810, in __bootstrap_inner
  File "/usr/local/Cellar/python/2.7.6_1/Frameworks/Python.framework/Versions/2.7/lib/python2.7/", line 763, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/local/lib/python2.7/site-packages/compose/cli/", line 41, in _enqueue_output
    for item in generator:
  File "/usr/local/lib/python2.7/site-packages/compose/cli/", line 59, in _make_log_generator
    for line in line_generator:
  File "/usr/local/lib/python2.7/site-packages/compose/cli/", line 77, in split_buffer
    for data in reader:
  File "/usr/local/lib/python2.7/site-packages/docker/", line 225, in _multiplexed_response_stream_helper
    socket = self._get_raw_response_socket(response)
  File "/usr/local/lib/python2.7/site-packages/docker/", line 167, in _get_raw_response_socket
  File "/usr/local/lib/python2.7/site-packages/docker/", line 119, in _raise_for_status
    raise errors.APIError(e, response, explanation=explanation)
APIError: 500 Server Error: Internal Server Error ("http: Hijack is incompatible with use of CloseNotifier")

I'm not sure what that is from, but everything is working. A new image was built and a development version of the identidock app is up and running. Let's look around.

docker images
REPOSITORY              TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
identidock_identidock   latest              bb9620f3a5b1        42 seconds ago      767.5 MB

docker ps -l
CONTAINER ID        IMAGE                          COMMAND             CREATED             STATUS              PORTS                                        NAMES
9113a34dcce9        identidock_identidock:latest   "/"           5 minutes ago       Up 5 minutes        9090/tcp,>5000/tcp, 9191/tcp   identidock_identidock_1

curl $(boot2docker ip):5000
Hello World!

docker-compose logs
Attaching to identidock_identidock_1
identidock_1 | Running Development Server
identidock_1 |  * Running on (Press CTRL+C to quit)
identidock_1 |  * Restarting with stat
identidock_1 | - - [26/Apr/2015 22:13:14] "GET / HTTP/1.1" 200 -
identidock_1 |  * Detected change in '/app/', reloading
identidock_1 |  * Restarting with stat
identidock_1 | - - [26/Apr/2015 22:14:46] "GET / HTTP/1.1" 200 -

Since we mapped our app directory as a volume in the container, we can make changes to which will be picked up immediately. Try it.

Step 6 Link to dnmonster container and update app to generate images


Moving beyond 'Hello World!' now we'll update the app to call out to another web server to request a generated image for display. The webserver will be a linked container called dnmonster.

  • Update to generate an html page and form
  • Update the Dockerfile to add requests library to the pip install layer.
  • Rebuild the image and pull the amouat/dnmonster image.
# rebuild image with 'link' tag
docker build -t identidock:link .
# automatically pull and run the image found on
docker run -d --name dnmonster amouat/dnmonster

The Dockerfile for that image is basically as follows. Note that it exposes port 8080.

FROM node:0.11
RUN apt-get update && apt-get install -yy libcairo2-dev \
    libjpeg62-turbo-dev libpango1.0-dev libgif-dev build-essential g++
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY ./src /usr/src/app
CMD [ "npm", "start" ]

Now create a container from the identidock:link image and link it to the newly started dnmonster container.

docker run -d -p 5000:5000 -e "ENV=DEV" --link dnmonster:dnmonster identidock:link

If you use exec -ti to run bash in the identidock container you can see that /etc/hosts has an entry for dnmonster automatically and you can ping it by name. Pretty cool.