WordPress

Wondering how to configure Tugboat for a standard WordPress repository? Every site tends to have slightly different requirements, so you may need to do more customizing, but this should get you started.

First Things First

We’ll provide 2 sets of instructions below for configuring your WordPress site to work with Tugboat:

  • Where WordPress Core is committed at the root of your repo,
  • and where WordPress is installed using Composer into a subdirectory.

When you copy the config file below, make sure you follow the instructions to adjust the config to your setup.

If you haven’t yet, add a .tugboat directory to the root of your repo. This is where Tugboat will look for configuration files and custom scripts.

Configure WordPress For Tugboat

A standard WordPress configuration has a wp-config.php file at its root. Best practice is to not commit this file to your repo as it contains sensitive information. If this file does exist, Tugboat will overwrite it with its own from the default config, so here’s what we recommend:

  1. Add wp-config.tugboat.php to your .tugboat directory.
  2. Add any specific config needed to your .tugboat/wp-config.tugboat.php file.
  3. Set these values specifically:
 1<?php
 2// Define Tugboat's database credentials.
 3define('DB_NAME', 'tugboat');
 4define('DB_USER', 'tugboat');
 5define('DB_PASSWORD', 'tugboat');
 6define('DB_HOST', 'mysql');
 7
 8// Set our Tugboat hostname.
 9define( 'WP_HOME', 'https://' . getenv('TUGBOAT_SERVICE_URL_HOST') );
10
11// Define the location where WordPress Core is installed.
12// In this case, a subdirectory of the webroot called "wp".
13define( 'WP_SITEURL', 'https://' . getenv('TUGBOAT_SERVICE_URL_HOST') . '/wp' );

Note: Make sure your wp-config.php is formatted as close to the sample file as possible. The WordPress CLI gets angry when it’s not and will release the Kraken on your Tugboat builds.

Configure Tugboat for WordPress

The Tugboat configuration is managed by a YAML file at .tugboat/config.yml in the git repository. Copy the code below into that file as a starting point. Then, you’ll need to tweak a few things for your particular installation.

For each service (php, mysql, etc) Tugboat runs three phases to build your preview: init, update, and build.

WordPress Starter Config

There are two starter configs provided here. Copy the appropriate one into .tugboat/config.yml and uncomment the options that fit your setup.

A. Without Composer

  1services:
  2  # Define our webserver service.
  3  php:
  4    # Use PHP 8.1 with Apache to serve the WordPress site.
  5    # This syntax pulls in the latest version of PHP 8.1.
  6    image: tugboatqa/php:8.1-apache
  7
  8    # Set this as the default service. This does a few things:
  9    #   1. Clones the git repository into the service container,
 10    #   2. Exposes port 80 to the Tugboat HTTP proxy,
 11    #   3. Routes requests to the preview URL to this service.
 12    default: true
 13
 14    # Wait until the mysql service is done building.
 15    depends: mysql
 16
 17    # Configure the webserver.
 18    commands:
 19      # The INIT phase is for initializing the server itself.
 20      init:
 21        # Install prerequisite packages.
 22        - apt-get update
 23        - apt-get install -y rsync libzip-dev libmagickwand-dev
 24
 25        # Turn on URL rewriting.
 26        - a2enmod expires headers rewrite
 27
 28        # Install the PHP extensions.
 29        - docker-php-ext-install mysqli exif zip
 30
 31        ## Install the WordPress CLI.
 32        - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
 33        - chmod +x wp-cli.phar
 34        - mv wp-cli.phar /usr/local/bin/wp
 35
 36      # The UPDATE phase is for importing assets and dependencies.
 37      # When you refresh a Tugboat Preview, the process starts here, skipping `init`.
 38      update:
 39        ## @TODO: Define your site's docroot.
 40        #
 41        # OPTION 1: WordPress is at the repo root.
 42        # - ln -snf "${TUGBOAT_ROOT}" "${DOCROOT}"
 43
 44        # OPTION 2: WordPress lives in a subdirectory (in this example, 'docroot').
 45        # - ln -snf "${TUGBOAT_ROOT}/docroot" "${DOCROOT}"
 46
 47        ## @TODO: Include your custom WordPress config.
 48        #  This will depend on your setup.  Here our default WordPress config is looking
 49        #  in the DOCROOT for a file called `wp-config.local.php` so we'll move our
 50        #  Tugboat config files there.
 51        - cp ${TUGBOAT_ROOT}/.tugboat/wp-config.tugboat.php ${DOCROOT}/wp-config.local.php
 52        - cp ${TUGBOAT_ROOT}/.tugboat/.htaccess ${DOCROOT}/.htaccess
 53
 54        ## @TODO: Import WordPress files (uploads).
 55        # Ensure the destination directory exists.
 56        - mkdir -p "${DOCROOT}/wp-content/uploads" || /bin/true
 57
 58        # Add an SSH key to your source server if needed.  The Environment Variable
 59        # here can be added in the Tugboat Repository settings.
 60        # - echo "${MY_PRODUCTION_SSH_KEY}" > ~/.ssh/production_ssh_key
 61        # - chmod 600 ~/.ssh/production_ssh_key
 62
 63        # OPTION 1: Import a tarball from a remote source.
 64        #  Periodically bundling your assets on production-like server and placing
 65        #  them somewhere Tugboat can access them can decrease build times and
 66        #  improve security.
 67        # - curl -O https://example.com/path/to/remote/source/uploads.tar.gz
 68        # - tar -C /tmp -zxf uploads.tar.gz
 69        # - rsync -avz --delete /tmp/uploads/ "${DOCROOT}/wp-content/uploads/"
 70
 71        # OPTION 2: Manually sync files from a remote server.
 72        # Adjust the port value, user credentials, and path values as needed.
 73        # - rsync --archive --verbose --delete \
 74        #    -e "ssh -p 22 -o ConnectTimeout=120" \
 75        #    --exclude={'*.zip','*.gz', '*.tgz'} \
 76        #    example@example.com:/var/www/html/docroot/wp-content/uploads/ \
 77        #    "${DOCROOT}/wp-content/uploads"
 78
 79        # After placing the files, fix file ownership and harden permissions.
 80        - chgrp -R www-data "${DOCROOT}/wp-content/uploads"
 81        - find "${DOCROOT}/wp-content/uploads" -type d -exec chmod 2775 {} \;
 82        - find "${DOCROOT}/wp-content/uploads" -type f -exec chmod 0664 {} \;
 83
 84        # Cleanup.
 85        - apt-get clean
 86        - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 87
 88      # Commands that build the site. When a Preview is built from a
 89      # Base Preview, the build workflow starts here, skipping the `init`
 90      # and `update` steps, because the results of those are inherited
 91      # from the base preview.
 92      build:
 93        # Flush WordPress Cache.
 94        - wp cache flush
 95
 96  # Define the database server.
 97  # This name also acts as the hostname to access the service.
 98  mysql:
 99    # Use the latest available 5.x version of MySQL
100    image: tugboatqa/mysql:5-debian
101
102    # A set of commands to run while building this service
103    commands:
104      # Initialize and configure the database Server.
105      init: []
106
107      # Commands that import files, databases, or other assets. When an
108      # existing preview is refreshed, the build workflow starts here,
109      # skipping the init step, because the results of that step will
110      # already be present.
111      update:
112        ## @TODO: Import a database.
113        #
114        # OPTION 1: Fetch a dump file from a remote source.
115        #  Periodically running a database dump from a production-like environment
116        #  to a place where Tugboat can access it can drastically reduce build times
117        #  and the strain on the source server.  The public SSH key found in the
118        #  Tugboat Repository configuration must be added to the external server
119        #  in order to use scp.
120        # - scp user@example.com:database.sql.gz /tmp/database.sql.gz
121        # - zcat /tmp/database.sql.gz | mysql tugboat
122        # - rm /tmp/database.sql.gz
123        # OPTION 2: Sync the database directly from another environment with wp-cli.
124        #  This is not the recommended option as you'll need to install wp-cli on this service
125        #  in addition to the webserver, and it performs a database dump on each build, which
126        #  can be time-consuming and expensive for big databases.
127        # - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
128        # - chmod +x wp-cli.phar
129        # - mv wp-cli.phar /usr/local/bin/wp
130        #  NOTE: This can be simplified by defining an alias for the source server in
131        #  your `wp-cli.yml` file.
132        # - wp --allow-root --ssh=example@www.example.com:22/var/www/html/docroot/wp  db export - > prod.sql
133        # - wp --allow-root db import prod.sql
134        # - rm prod.sql
135
136      build: []

B. With Composer

  1services:
  2  # Define our webserver service.
  3  php:
  4    # Use PHP 8.1 with Apache to serve the WordPress site.
  5    # This syntax pulls in the latest version of PHP 8.1.
  6    image: tugboatqa/php:8.1-apache
  7
  8    # Set this as the default service. This does a few things:
  9    #   1. Clones the git repository into the service container,
 10    #   2. Exposes port 80 to the Tugboat HTTP proxy,
 11    #   3. Routes requests to the preview URL to this service.
 12    default: true
 13
 14    # Wait until the mysql service is done building.
 15    depends: mysql
 16
 17    # Configure the webserver.
 18    commands:
 19      # The INIT phase is for initializing the server itself.
 20      init:
 21        # Install prerequisite packages.
 22        - apt-get update
 23        - apt-get install -y rsync libzip-dev libmagickwand-dev
 24
 25        # Turn on URL rewriting.
 26        - a2enmod expires headers rewrite
 27
 28        # Install the PHP extensions.
 29        - docker-php-ext-install mysqli exif zip
 30
 31      # The UPDATE phase is for importing assets and dependencies.
 32      # When you refresh a Tugboat Preview, the process starts here, skipping `init`.
 33      update:
 34        #  If you rarely modify your composer.json file, this line can be moved
 35        #  to the `init` phase to speed up refreshes and rebuilds that use base
 36        #  previews.
 37        - composer install --optimize-autoloader
 38
 39        ## Install the WordPress CLI utility.
 40        #  Set up the wp-cli instance installed with composer to be used globally.
 41        - ln -snf "${TUGBOAT_ROOT}/vendor/bin/wp" /usr/local/bin
 42
 43        ## @TODO: Define your site's docroot.
 44        #
 45        # OPTION 1: WordPress is at the repo root.
 46        # - ln -snf "${TUGBOAT_ROOT}" "${DOCROOT}"
 47
 48        # OPTION 2: WordPress lives in a subdirectory (in this example, 'docroot').
 49        # - ln -snf "${TUGBOAT_ROOT}/docroot" "${DOCROOT}"
 50
 51        ## @TODO: Include your custom WordPress config.
 52        #  This will depend on your setup.  Here our default WordPress config is looking
 53        #  in the DOCROOT for a file called `wp-config.local.php` so we'll move our
 54        #  Tugboat config files there.
 55        - cp ${TUGBOAT_ROOT}/.tugboat/wp-config.tugboat.php ${DOCROOT}/wp-config.local.php
 56        - cp ${TUGBOAT_ROOT}/.tugboat/.htaccess ${DOCROOT}/.htaccess
 57
 58        ## @TODO: Import WordPress files (uploads).
 59        # Ensure the destination directory exists.
 60        - mkdir -p "${DOCROOT}/wp-content/uploads" || /bin/true
 61
 62        # Add an SSH key to your source server if needed.  The Environment Variable
 63        # here can be added in the Tugboat Repository settings.
 64        # - echo "${MY_PRODUCTION_SSH_KEY}" > ~/.ssh/production_ssh_key
 65        # - chmod 600 ~/.ssh/production_ssh_key
 66
 67        # OPTION 1: Import a tarball from a remote source.
 68        #  Periodically bundling your assets on production-like server and placing
 69        #  them somewhere Tugboat can access them can decrease build times and
 70        #  improve security.
 71        # - curl -O https://example.com/path/to/remote/source/uploads.tar.gz
 72        # - tar -C /tmp -zxf uploads.tar.gz
 73        # - rsync -avz --delete /tmp/uploads/ "${DOCROOT}/wp-content/uploads/"
 74
 75        # OPTION 2: Manually sync files from a remote server.
 76        # Adjust the port value, user credentials, and path values as needed.
 77        # - rsync --archive --verbose --delete \
 78        #    -e "ssh -p 22 -o ConnectTimeout=120" \
 79        #    --exclude={'*.zip','*.gz', '*.tgz'} \
 80        #    example@example.com:/var/www/html/docroot/wp-content/uploads/ \
 81        #    "${DOCROOT}/wp-content/uploads"
 82
 83        # After placing the files, fix file ownership and harden permissions.
 84        - chgrp -R www-data "${DOCROOT}/wp-content/uploads"
 85        - find "${DOCROOT}/wp-content/uploads" -type d -exec chmod 2775 {} \;
 86        - find "${DOCROOT}/wp-content/uploads" -type f -exec chmod 0664 {} \;
 87
 88        # Cleanup.
 89        - apt-get clean
 90        - rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
 91
 92      # Commands that build the site. When a Preview is built from a
 93      # Base Preview, the build workflow starts here, skipping the `init`
 94      # and `update` steps, because the results of those are inherited
 95      # from the base preview.
 96      build:
 97        # Flush WordPress Cache.
 98        - wp cache flush
 99
100  # Define the database server.
101  # This name also acts as the hostname to access the service.
102  mysql:
103    # Use the latest available 5.x version of MySQL
104    image: tugboatqa/mysql:5-debian
105
106    # A set of commands to run while building this service
107    commands:
108      # Initialize and configure the database Server.
109      init: []
110
111      # Commands that import files, databases, or other assets. When an
112      # existing preview is refreshed, the build workflow starts here,
113      # skipping the init step, because the results of that step will
114      # already be present.
115      update:
116        ## @TODO: Import a database.
117        #
118        # OPTION 1: Fetch a dump file from a remote source.
119        #  Periodically running a database dump from a production-like environment
120        #  to a place where Tugboat can access it can drastically reduce build times
121        #  and the strain on the source server.  The public SSH key found in the
122        #  Tugboat Repository configuration must be added to the external server
123        #  in order to use scp.
124        # - scp user@example.com:database.sql.gz /tmp/database.sql.gz
125        # - zcat /tmp/database.sql.gz | mysql tugboat
126        # - rm /tmp/database.sql.gz
127        # OPTION 2: Sync the database directly from another environment with wp-cli.
128        #  This is not the recommended option as you'll need to install wp-cli on this service
129        #  in addition to the webserver, and it performs a database dump on each build, which
130        #  can be time-consuming and expensive for big databases.
131        # - curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
132        # - chmod +x wp-cli.phar
133        # - mv wp-cli.phar /usr/local/bin/wp
134        #  NOTE: This can be simplified by defining an alias for the source server in
135        #  your `wp-cli.yml` file.
136        # - wp --allow-root --ssh=example@www.example.com:22/var/www/html/docroot/wp  db export - > prod.sql
137        # - wp --allow-root db import prod.sql
138        # - rm prod.sql
139
140      build: []

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!