Tugboat is a system that builds a working preview of a website for any branch, tag, commit, or pull request in a git repository. It can automatically create these previews for pull requests by integrating with GitHub, GitLab, or Bitbucket git repositories.
Tugboat creates customizable, containerized environments for engineering teams. These ephemeral environments are called Previews, and can be created automatically when a new pull or merge request is made to GitHub, GitLab, or Bitbucket.
Tugboat complements existing CI/CD pipelines by adding critical last-mile audits, and turning manual reviews into automated, fool-proof deployments.
Less time troubleshooting and maintaining a build process that “just works” versus the more complex CI/CD pipeline for deploying to permanent infrastructure. Not all git pull request builders are alike, but with an option like Tugboat, a git pull request builder using an infrastructure-as-code approach can replace complex, internally-maintained CI/CD pipelines for pre-production deployment. Conduct integration testing early and often.
Verify database backups and the deployment process in deploy previews.
When you kick off a Preview build, Tugboat grabs the config file from your linked repository. Tugboat follows the instructions to set up each Service in your config file, grabbing the specified Docker images and then executing the Service Commands in three phases:
During the init phase, you might use commands that set up the basic preview infrastructure. This might include things like installing required packages or tools, or overriding default configuration files.
During the update phase, you might use commands that import data or other assets into a service. This might include things like importing a database, or syncing image files into a service.
During the build phase, you might use commands that build or generate the actual site. This might include things like compiling Sass files, updating 3rd party libraries, or running database updates that the current code in the preview depends on.
In the process of building your Preview, you’ll specify a default service, and that’s the service where your git repository is cloned. If you want to clone it into other services, see: cloning git repositories into your Services.
By the time the build is complete, Tugboat has configured Services according to your config file, including pulling the Docker images you want it to use for each Service, and has pulled in your code to execute your Preview.
When you build a regular Preview, the configuration file typically instructs Tugboat to pull in databases, image files, or other assets. This process can take a while; the larger the assets, the longer the build.
When you mark a Preview as a Base Preview, Tugboat uses that Preview’s build snapshot as a starting point for every new Preview build that matches that Base Preview type. None of the new Previews need to re-download copies of databases, image files, or other assets. Base Previews can dramatically reduce the amount of time required to generate a working Preview.
In addition to speeding up your Preview builds, Tugboat saves disk space by storing only a binary difference between the Base Preview and Previews built from that Base Preview. A new Preview only uses whatever space it needs that differs from the Base Preview. Often, this means a Base Preview might use 2-3GB of space, and a Preview built from it might only use 100-200MB. This is a great way to keep a Tugboat Project under your billing tier’s storage limit, even when you’re building multiple Previews.
Wondering how to configure Tugboat for a typical Drupal 10 repository? Every Drupal site tends to have slightly different requirements, so you may need to do more customizing, but this should get you started.
The following documentation assumes you are using Composer to manage your Drupal 10 project
Steps
Configuration file
The Tugboat configuration is managed by a YAML file at .tugboat/config.yml in the git repository. Here’s a basic Drupal 10 configuration for our testing project.
services:
# What to call the service hosting MySQL. This name also acts as the
# hostname to access the service by from the php service.
database:
image: tugboatqa/mariadb:10.6.5-focal
commands:
init:
# Increase the allowed packet size to 512MB.
- mysql -e "SET GLOBAL max_allowed_packet=2147483648;"
# Ensure this packet size persists even if MySQL restarts.
- echo "max_allowed_packet=2147483648" >> /etc/mysql/tugboat.cnf
# Define the webserver service.
webserver:
# This uses PHP 8.1.x with Apache: update to match your version of PHP
image: tugboatqa/php:8.1-apache
# Set this as the default service. This does a few things
# 1. Clones the git repository into the service container
# 2. Exposes port 80 to the Tugboat HTTP proxy
# 3. Routes requests to the preview URL to this service
default: true
# Wait until the mysql service is done building
depends: database
# A set of commands to run while building this service
commands:
# Commands that set up the basic preview infrastructure
init:
# Install opcache and mod-rewrite.
- docker-php-ext-install opcache
- apt-get update && apt-get -y install libzip-dev nano
- docker-php-ext-install bcmath
- docker-php-ext-install zip
- a2enmod headers rewrite
# Set composer to version 2.
- composer self-update ${COMPOSER_VERSION:-2.3.10}
# If desired, create a global drush symlink
- ln -snf "${TUGBOAT_ROOT}/vendor/bin/drush" /usr/local/bin/drush
# Link the document root to the expected path. This example links /web
# to the docroot.
- ln -snf "${TUGBOAT_ROOT}/web" "${DOCROOT}"
# increase php memory limit to 256M
- echo "memory_limit = 256M" >> /usr/local/etc/php/conf.d/my-php.ini
# enable display errors.
- echo "display_errors = On" >> /usr/local/etc/php/conf.d/my-php.ini
# Enable colored terminal and some aliases
- sed -e '9,13 s/#//' -i ~/.bashrc
- sed -e '16,19 s/#//' -i ~/.bashrc
# Commands that import files, databases, or other assets. When an
# existing preview is refreshed, the build workflow starts here,
# skipping the init step, because the results of that step will
# already be present.
update:
# Use the tugboat-specific Drupal settings.
- cp "${TUGBOAT_ROOT}/.tugboat/settings.local.php" "${DOCROOT}/sites/default/"
# Install/update packages managed by composer, including drush.
- composer install --optimize-autoloader
# Create drupal files directories.
- mkdir -p "${DOCROOT}/sites/default/files"
- mkdir -p "${DOCROOT}/sites/default/files-private"
- mkdir -p "${DOCROOT}https://cms.rootstack.com/sites/default/files/translations"
# Copy Drupal's public files directory and database from an external server. The
# public SSH key found in the Tugboat Repository configuration must be
# copied to the external server in order to use rsync over SSH.
- drush sql-sync @rootstackdf.dev @rootstackdf.tugboat -y
- drush rsync @rootstackdf.dev:%files/ @rootstackdf.tugboat:%files -y
# Make sure our files and translations folders exists and are writable.
- chgrp -R www-data "${DOCROOT}/sites/default/files"
- find "${DOCROOT}/sites/default/files" -type d -exec chmod 2775 {} \;
- find "${DOCROOT}/sites/default/files" -type f -exec chmod 0664 {} \;
- chgrp -R www-data "${DOCROOT}/sites/default/files-private"
- find "${DOCROOT}/sites/default/files-private" -type d -exec chmod 2775 {} \;
- find "${DOCROOT}/sites/default/files-private" -type f -exec chmod 0664 {} \;
# Commands that build the site. This is where you would add things
# like feature reverts or any other drush commands required to
# set up or configure the site. When a preview is built from a
# base preview, the build workflow starts here, skipping the init
# and update steps, because the results of those are inherited
# from the base preview.
build:
- composer install --optimize-autoloader
- drush cache:rebuild
- drush config:import -y
- drush updatedb -y
- drush cache:rebuild
# TODO: This feature is available for Tugboat Plus and Premium plans.
# apache:
# # Screenshot settings that affect all the defined service URLs.
# # These override our defaults, and can also be overridden per-URL
# screenshot:
# enabled: true
#
# # The following options are used when taking a screenshot of
# # the URL for _this_ preview
# timeout: 30
# waitUntil:
# - load
# fullPage: true
# urls:
# # Create a visualdiff of the home page using the default options
# - url: /
# # Create a visualdiff of /blog, but set a similarity threshold of 90%
# - url: /blog
# visualdiff:
# threshold:
# desktop: 90
# mobile: 80
# tablet: 99
Once the Tugboat configuration file is committed to your git repository, you can start building previews.
After, that we are able to see all the available branches/ tags for a preview. In our test repository, we have 3 branches.
For our lab, we selected the master as the base review where we used to have the Claro as the administration and default theme.
And we created a preview of the feature/RDF-01/theme-update branch where we installed with composer and enabled the drupal Gin theme as the administration and default theme.