This document sums up how to set up cascading builds of multiple Dockerfiles in the same repository running on docker hub infrastructure.
Achieved using docker hooks and docker environment variables.
Imagine three Dockerfiles in a repository named example
with the following directory structure, producing images example:a
, example:b
, example:c
.
├── docker
│ ├── b
│ │ ├── Dockerfile
│ │ └── hooks
│ │ ├── build
│ │ └── post_push
│ └── c
│ ├── Dockerfile
│ └── hooks
│ ├── build
│ └── post_push
├── Dockerfile
└── hooks
└── post_push
./Dockerfile
builds example:a
./docker/b/Dockerfile
builds example:b
./docker/c/Dockerfile
builds example:c
We wish to build the images in a given order, because c
depends on b
depends on a
, so we have cascading builds such that a
triggers b
triggers c
.
Achived by using hooks/post_push
to trigger the next build in line. Note that this requires the build context to be in the respective folders, to activate the correct hooks. Example hook below
#!/bin/bash
curl -v -H "Content-Type: application/json" --data '{"docker_tag": "latest-a"}' -X POST $CASCADING_BUILD_TRIGGER_URL
$CASCADING_BUILD_TRIGGER_URL
, because the webhook is secret and should not be exposed.
The docker hub interface under builds->Configure automated builds
enables configuring of the webhook (Build triggers
) and the environment variable (Build Environment Variables
).
The resulting tags will be what you have specified in the configuration. For instance
a
b
c
It can be a good idea to version images with the commit hash of the source it was built from. Use the post_push
hook to achieve this.
#!/bin/bash
TAG="${SOURCE_COMMIT:0:7}-a"
docker tag $IMAGE_NAME $DOCKER_REPO:$TAG
docker push $DOCKER_REPO:$TAG
Note that TAG is postfixed with -a
and will need equivalent hooks for the other images b
and c
.
For a commit abcd123
the tags will then be
abcd123-a
abcd123-b
abcd123-c
To build FROM
a tag that contains a dynamic part like the source commit, the build will need that information passed from the build context env (the shell that runs docker build
) to the image build context. This can be done with the --build-arg=VAR
flag. Use a build hook to achieve this. Example docker/b/hooks/build
below
#!/bin/bash
docker build --build-arg IMAGE=$DOCKER_REPO --build-arg TAG=$SOURCE_COMMIT-b -t $IMAGE_NAME .
Note again the tag postfixed -b
, so an equivalent build hook is necessary for c
.
Use env vars in the Dockerfile
with
ARG IMAGE
ARG TAG
FROM $IMAGE:$TAG