dotcloud/docker — pull request #3251 by gabrtv (2013-12-17 23:16:33+00:00)
Title: Build multiple tagged images per Dockerfile

As discussed with @creack, the goal of this PR is to allow a single `Dockerfile` to build multiple flavors of an image using the current build environment. This is useful for:

* Creating lightweight image layers that customize metadata (ENV, ENTRYPOINT, etc)
* Adding layers to a base image from arbitrary points in the current build
* Modeling Heroku-style process types as specified in a `Procfile`

## Example Usage

A developer is creating a `Dockerfile` to deploy a web application. The application has 3 main flavors of usage:

1. Run an interactive shell
1. Run a web server
2. Run a worker

With the TAG instruction, developers can create multiple tagged images for each flavor from a single `Dockerfile`:

```
FROM stackbrew/ubuntu:12.04
ENV DEFAULT value
TAG :latest

FROM :latest
ENV WEB 1
ENTRYPOINT ["/bin/echo", "web"]
TAG :web

FROM :latest
ENV WORKER 1
ENTRYPOINT ["/bin/echo", "worker"]
TAG :worker
```

Building the `Dockerfile` results in the following output:

```
# docker build -t gabrtv/test .
Uploading context 204.8 kB
Step 1 : FROM stackbrew/ubuntu:12.04
---> 4fc5ba8a5b33
Step 2 : ENV DEFAULT value
---> Running in 0787811a7674
---> e2e373ff1a73
Step 3 : TAG :latest
---> e2e373ff1a73
Step 4 : FROM :latest
---> e2e373ff1a73
Step 5 : ENV WEB 1
---> Running in 715022e443a5
---> be2cd6668a56
Step 6 : ENTRYPOINT ["/bin/echo", "web"]
---> Running in ba94a225079b
---> 09484a63e190
Step 7 : TAG :web
---> 09484a63e190
Step 8 : FROM :latest
---> e2e373ff1a73
Step 9 : ENV WORKER 1
---> Running in a0d0154804af
---> 76cb1d83b7bd
Step 10 : ENTRYPOINT ["/bin/echo", "worker"]
---> Running in f370e833e660
---> 2ff2d5c7942b
Step 11 : TAG :worker
---> 2ff2d5c7942b
Successfully built 2ff2d5c7942b
```

.. which results in the following new images:

```
# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
gabrtv/test latest e2e373ff1a73 38 seconds ago 93.66 MB
gabrtv/test worker 2ff2d5c7942b 38 seconds ago 93.66 MB
gabrtv/test web 09484a63e190 38 seconds ago 93.66 MB
```

Playing with the images demonstrates their unique flavors:

```
# docker run -t -i gabrtv/test bash
root@3b527e5a0c8c:/# echo $DEFAULT
value

# docker run gabrtv/test:web
web

# docker run gabrtv/test:worker
worker

# docker run -entrypoint=/usr/bin/env gabrtv/test:worker
HOME=/
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=af87e9b3306e
DEFAULT=value
WORKER=1
container=lxc
```

The PR includes integration tests and should be backwards compatible.