Drupal 11

Wondering how to configure Tugboat for a typical Drupal 11 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 11 project (typically with drupal/recommended-project).

Configure Drupal

A common practice for managing Drupal’s settings.php is to leave sensitive information, such as database credentials, out of it and commit it to git. Then, the sensitive information is loaded from a settings.local.php file that exists only on the Drupal installation location.

This pattern works very well with Tugboat. It lets you keep a Tugboat-specific set of configurations in your repository, where you can copy it into place with a configuration file command.

Add or uncomment the following at the end of settings.php

1if (file_exists($app_root . '/' . $site_path . '/settings.local.php')) {
2  include $app_root . '/' . $site_path . '/settings.local.php';
3}

Add a file to the git repository at .tugboat/settings.local.php with the following content:

 1<?php
 2/**
 3 * @file
 4 * Tugboat preview environment settings.
 5 *
 6 * To activate these settings for sites in Tugboat preview environments,
 7 * ensure that this file is placed in .tugboat/settings.local.php
 8 * in the root of your git repository.
 9 */
10
11/**
12 * Database connection information for Tugboat preview environments.
13 */
14$databases['default']['default'] = array (
15  'database' => 'tugboat',
16  'username' => 'tugboat',
17  'password' => 'tugboat',
18  'prefix' => '',
19  'host' => 'database',
20  'port' => '3306',
21  'driver' => 'mysql',
22  'isolation_level' => "READ COMMITTED",
23);
24
25/**
26 * Salt for one-time login links, cancel links, form tokens, etc.
27 *
28 * Use the TUGBOAT_REPO_ID to generate a hash salt for Tugboat sites.
29 */
30$settings['hash_salt'] = hash('sha256', getenv('TUGBOAT_REPO_ID'));
31
32
33
34/**
35 * Skip file system permissions hardening.
36 *
37 * The system module will periodically check the permissions of your site's
38 * site directory to ensure that it is not writable by the website user. For
39 * sites that are managed with a version control system, this can cause problems
40 * when files in that directory such as settings.php are updated, because the
41 * user pulling in the changes won't have permissions to modify files in the
42 * directory.
43 */
44$settings['skip_permissions_hardening'] = TRUE;
45
46/**
47 * Trusted host configuration for Tugboat preview environments.
48 *
49 * Drupal requires you to specify which hostnames are allowed to access your
50 * site. Since Tugboat preview URLs use the tugboatqa.com domain, we add this
51 * pattern to allow Drupal to accept requests from any Tugboat preview URL.
52 *
53 * @see https://www.drupal.org/docs/installing-drupal/trusted-host-settings
54 */
55$settings['trusted_host_patterns'] = [
56  '\.tugboatqa\.com$',
57];
58
59/**
60 * Set the memory limit for the CLI (drush).
61 */
62if (PHP_SAPI === 'cli') {
63  ini_set('memory_limit', '-1');
64}

Configure Tugboat

The Tugboat configuration is managed by a YAML file at .tugboat/config.yml in the git repository. Here’s a basic Drupal 11 configuration you can use as a starting point, with comments to explain what’s going on:

  1# Tugboat configuration for Drupal 11
  2# https://docs.tugboatqa.com/starter-configs/tutorials/drupal-11/
  3
  4services:
  5  # Define the webserver service.
  6  webserver:
  7    # Drupal 11 requires PHP 8.3 as the minimum version.
  8    image: tugboatqa/php:8.3-apache
  9
 10    # Set this as the default service. This does a few things
 11    #   1. Clones the git repository into the service container
 12    #   2. Exposes port 80 to the Tugboat HTTP proxy
 13    #   3. Routes requests to the preview URL to this service
 14    default: true
 15
 16    # Wait until the database service is done building.
 17    depends: database
 18
 19    # A set of commands to run while building this service
 20    commands:
 21      # The INIT command configures the webserver.
 22      init:
 23        # Install opcache and mod-rewrite.
 24        - docker-php-ext-install opcache
 25        - a2enmod headers rewrite
 26
 27        # Link the document root to the expected path. This example links /web
 28        # to the docroot (standard for composer-based Drupal projects).
 29        - ln -snf "${TUGBOAT_ROOT}/web" "${DOCROOT}"
 30
 31      # Commands that import files, databases, or other assets. When an
 32      # existing preview is refreshed, the build workflow starts here,
 33      # skipping the init step, because the results of that step will
 34      # already be present.
 35      update:
 36        # Install/update packages managed by composer.
 37        - composer install --optimize-autoloader
 38
 39        # Set the tugboat-specific Drupal settings.
 40        - cp "${TUGBOAT_ROOT}/.tugboat/settings.local.php" "${DOCROOT}/sites/default/settings.local.php"
 41
 42        # Map your custom modules and themes into the Drupal structure.
 43        # Uncomment and adapt these if your repository has custom code outside
 44        # the standard Drupal directory structure:
 45        # - ln -snf "${TUGBOAT_ROOT}/custom/themes" "${DOCROOT}/themes/custom"
 46        # - ln -snf "${TUGBOAT_ROOT}/custom/modules" "${DOCROOT}/modules/custom"
 47
 48        # Create any required directories that don't exist.
 49        # Uncomment if using private files outside the webroot:
 50        # - mkdir -p "${TUGBOAT_ROOT}/files-private"
 51        # - chgrp -R www-data "${TUGBOAT_ROOT}/files-private"
 52        # - find "${TUGBOAT_ROOT}/files-private" -type d -exec chmod 2775 {} \;
 53        # - find "${TUGBOAT_ROOT}/files-private" -type f -exec chmod 0664 {} \;
 54
 55        # Make sure our files and translations folders exist and are writable.
 56        - mkdir -p "${DOCROOT}/sites/default/files/translations"
 57        - chgrp -R www-data "${DOCROOT}/sites/default/files"
 58        - find "${DOCROOT}/sites/default/files" -type d -exec chmod 2775 {} \;
 59        - find "${DOCROOT}/sites/default/files" -type f -exec chmod 0664 {} \;
 60
 61        # Optional: Copy Drupal's public files directory from an external server.
 62        # The public SSH key found in the Tugboat Repository configuration must be
 63        # copied to the external server in order to use rsync over SSH. More common
 64        # is to use Stage File Proxy, which you can enable in the `build` steps below.
 65        # - rsync -av --delete user@example.com:/path/to/files/ "${DOCROOT}/sites/default/files/"
 66
 67      # Commands that build the site. This is where you would add things
 68      # like configuration imports or any other drush commands required to
 69      # set up or configure the site. When a preview is built from a
 70      # base preview, the build workflow starts here, skipping the init
 71      # and update steps, because the results of those are inherited
 72      # from the base preview.
 73      build:
 74        # Install/update packages managed by composer, including any that might
 75        # have been updated by module updates or patches in this branch.
 76        - composer install --optimize-autoloader
 77
 78        # Run any pending database updates and import configuration.
 79        - vendor/bin/drush deploy --yes
 80
 81        # If you are downloading your files from a remote server, you won't need
 82        # to enable Stage File Proxy. Otherwise, enable it to fetch files on-demand.
 83        # - vendor/bin/drush pm:enable --yes stage_file_proxy
 84        # - vendor/bin/drush config:set --yes stage_file_proxy.settings origin "http://www.example.com"
 85        # - vendor/bin/drush config:set --yes stage_file_proxy.settings origin_dir "sites/default/files"
 86
 87  # Define the database service.
 88  database:
 89    # Drupal 11 requires MariaDB 10.6+ or MySQL 8.0+
 90    # Use at least MariaDB 11.4 to avoid TLS/SSL error
 91    # See https://docs.tugboatqa.com/troubleshooting/mysql-ssl-disabled/index.html
 92
 93    image: tugboatqa/mariadb:11.8
 94
 95    # A set of commands to run while building this service
 96    commands:
 97      # Configure the server for the site to run on.
 98      init:
 99        # Increase the allowed packet size to 512MB.
100        - mariadb -e "SET GLOBAL max_allowed_packet=536870912;"
101        # Ensure this packet size persists even if MySQL restarts.
102        - echo "max_allowed_packet=536870912" >> /etc/mysql/conf.d/tugboat.cnf
103
104      # Commands that import files, databases, or other assets. When an
105      # existing preview is refreshed, the build workflow starts here,
106      # skipping the init step, because the results of that step will
107      # already be present.
108      update:
109        # TODO: Copy a database dump from an external server. The public
110        # SSH key found in the Tugboat Repository configuration must be
111        # copied to the external server in order to use scp.
112        - scp user@example.com:database.sql.gz /tmp/database.sql.gz
113        - zcat /tmp/database.sql.gz | mariadb tugboat
114        - rm /tmp/database.sql.gz

Want to know more about something mentioned in the comments of this config file? Check out these topics:

Start Building Previews!

Once the Tugboat configuration file is committed to your git repository, you can start building previews!