Use Custom Docker Images to Speed Up Tugboat Builds

🚤💨

Tugboat is our tool of choice at Chromatic for building a preview environment for each of our pull requests. For an introduction to Tugboat, see A Testing Environment For Every Pull Request.

Out of the Box

One of Tugboat’s most compelling features is that it is fast, but that hasn’t stopped us from pursuing making it even faster. We wanted to turn our tugboat into a speedboat.

The Tugboat-provided Docker images do a great job of providing most of what you will need, but it is common for us to install a few additional tools during Tugboat’s init step so that they’re available for our builds. For example, we install awscli to download database dumps, yarn to build our front-end assets, and redis-tools so we can talk to our cache service.

commands:
init:
- apt-get update
- apt-get install --yes google-chrome-stable python3-pip redis-tools software-properties-common yarn
- pip3 install ansible awscli

Custom Docker Images

When using Tugboat’s base preview functionality, the speed at which these tools install is only a minor concern as it does not happen on every build, but if you are frequently building previews from scratch, there is an opportunity for improvement by building a custom Docker image. We took all of the tools that we were installing in our init step and created a custom Docker image with them already installed. Since our image is based on an official tugboatqa image, we get to retain all of the features that they have already built-in.

ARG PHP_VERSION
FROM tugboatqa/php:${PHP_VERSION}-apache
ENV COMPOSER_DISCARD_CHANGES=true
ENV COMPOSER_NO_INTERACTION=true
ENV COMPOSER_ALLOW_SUPERUSER=true
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - \
&& curl -sL https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - \
&& echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list \
&& wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add - \
&& echo "deb http://dl.google.com/linux/chrome/deb/ stable main" > /etc/apt/sources.list.d/google.list \
&& apt-get update \
&& apt-get --quiet install -y --no-install-recommends \
google-chrome-stable \
nodejs \
python3-pip \
redis-tools \
software-properties-common \
yarn \
&& pip3 install --upgrade setuptools \
&& pip3 install ansible awscli \
&& yes '' | pecl install -fo redis \
&& rm -rf /tmp/pear \
&& docker-php-ext-install opcache \
&& docker-php-ext-enable opcache \
&& docker-php-ext-enable redis \
&& a2enmod headers rewrite \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

Now, when our Tugboat environment builds, it pulls this custom image and can move right on past the init stage because we have pre-packaged everything within the image. Your build-time savings will vary based on how much you are currently installing in the init step, but in the example above, we improved our build speed by approximately 5 minutes when building previews from scratch. 🚤💨