• +43 660 1453541
  • contact@germaniumhq.com

Containerizing the Build Process


Containerizing the Build Process

Having the adhesive build process as code it’s a nice feature to have. In combination with containers it makes the source code the only truth on how the build is being performed. But that still means we have a dependency now on the build system itself. So how do we get rid of it? We’re going to containerize the local build system.

In order to achieve that we need two things:

  1. To have the build system available and callable as a container,

  2. To wrap the call so it works from the local system without friction.

1. Containerized Adhesive

Starting with version 0.11.3, on each release, a docker container is now automatically built for adhesive as: germaniumhq/adhesive:release_version

Docker Release

So whenever a version gets released to pypi, we ensure we also have a docker container built around that version.

2. Wrap The Call

The next step is containerizing the call itself. For that we’ll create a shell script that ensures the same environment gets passed around for the container:

docker run -it \
    --rm \
    -v /tmp:/tmp \                                    # (1)
    -v $HOME:$HOME \                                  # (2)
    -v /var/run/docker.sock:/var/run/docker.sock \    # (3)
    -v /etc/passwd:/etc/passwd:ro \                   # (4)
    -v /etc/group:/etc/group:ro \
    -e HOME=$HOME \                                   # (5)
    -w $(pwd) \                                       # (6)
    -u $(id -u):$(id -g) \                            # (7)
    $(id -G | perl -pe 's/(\d+)/--group-add \1/g') \
    germaniumhq/adhesive:0.11.3 \
    adhesive $@                                       # (8)
  1. /tmp is the folder used by adhesive for local workspaces and builds. We need to have access to mount workspaces created there in the sibling containers that we’ll create.

  2. We assume the builds are started from $HOME. This allows also plugins if they are configured in the .adhesive/config.yml to be available.

  3. We mount the docker socket in, so the build system can create sibling containers.

  4. We ensure the same users/groups are visible in the container. That’s not 100% required, but if someone expects whoami to return the actual name, better err on the safe side.

  5. We export the current HOME env variable, since it’s used to detect where the user’s .adhesive folder is.

  6. We change the working directory to the folder we’re currently in.

  7. We pass the same user/group ids into the container process. This also ensures we can access the docker socket shared inside the container.

  8. We pass whatever extra adhesive parameters to adhesive itself.

Conclusion

So to build a project now, it becomes:

  1. Checkout

  2. Install docker

  3. ./adhesive.sh

You don’t have to take my word for it. Here’s adhesive itself building with this approach:

Feel free to try it. You only need docker. ;)