[Braindump – warning]
So I’ve been playing with devcontainers
for Visual Studio Code, they’re awesome… go play with them. They let you use a Dockerfile
to describe all the tooling needed for devs to get started with your project.
One of the side effects is that you have a nice Dockerfile
which you can then also use it for your build server meaning that you never have an inconsistency between your local setup and your CI server.
In this example I build a golang
project and use Azure DevOps and use caching to minimize the amount of time for each build.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
trigger: | |
– master | |
pool: | |
vmImage: 'Ubuntu-16.04' | |
steps: | |
# Cache the docker image file | |
– task: CacheBeta@0 | |
inputs: | |
key: go-cache | go.sum | |
path: ".gocache" | |
restoreKeys: go-cache | |
displayName: Cache go mod cache | |
# Cache the docker image file | |
– task: CacheBeta@0 | |
inputs: | |
key: docker-image | .devcontainer/** | |
path: ".dockercache" | |
restoreKeys: docker-image | |
cacheHitVar: DOCKER_CACHE_HIT | |
displayName: Cache docker layers | |
– script: | | |
bash -f ./ci.sh | |
displayName: 'Run CI' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /bin/bash | |
set -e | |
set -x | |
# Get storage drive details | |
docker info | |
# Create .dockercache directory | |
mkdir -p ./.dockercache/ | |
# Import devcontainer from cache to speed up build | |
if [ -f ".dockercache/devcontainer.tar" ]; | |
then | |
echo "——-> Restoring docker image" | |
time docker load -i .dockercache/devcontainer.tar | |
fi | |
echo "——-> Building devcontainer" | |
# Use the devcontainer to run the build as it has all the environment setup that we need | |
time docker build –cache-from devcontainer:latest -t devcontainer -f ./.devcontainer/Dockerfile ./.devcontainer | |
# Create a directory for go mod cache | |
mkdir -p ${PWD}/.gocache | |
echo "——-> Building code" | |
# Run `make` to build and test the code | |
time docker run -v ${PWD}/.gocache:/go/pkg/ -v /var/run/docker.sock:/var/run/docker.sock -v ${PWD}:/src –workdir /src –entrypoint /bin/bash devcontainer -c "make" | |
# Ensure .gocache permmissions correct for build to save cache | |
sudo chown -R $USER ./.gocache | |
# If the current cached image is out of date save devcontainer so it can be cached | |
if [ $DOCKER_CACHE_HIT != "true" ]; | |
then | |
echo "——-> Saving docker image" | |
time docker image save -o ./.dockercache/devcontainer.tar devcontainer | |
fi |