How to Simplify Setup of Complex Drupal Sites with Docker and Expresso PHP
The ever increasing complexity and functionality of Drupal sites does not need to translate into increasingly steeper development costs.
In the past, Drupal sites were relatively homogeneous with the occasional multi-domain or multi-site implementation. Today, as sites become more complex, with features such as headless integration with non-Drupal software, the overhead of reproducing an environment locally can become very costly. Docker was created to bridge the gap between a homogeneous Drupal implementation and a complex integration with non-Drupal software.
Rather than running a full virtual machine locally, Docker emulates a given environment but still uses your operating system for better efficiency. This is done via "containers" for things like MySQL and PHP, enabling you to do things such as set a given PHP version for each site rather than system-wide. As a result, the process of increasing a site’s complexity has less of an impact on onboarding time.
To build on the benefits of Docker, Expresso PHP was created. Expresso PHP is an open-source Docker setup geared toward PHP development, including Drupal. An additional benefit: by only utilizing official Docker images, there is no need to maintain custom images.
To further illustrate the benefits of Docker and Expresso PHP, let’s walk through setting up a local Drupal environment in Drupal 8 using macOS Mojave.
Software Versions Used
- macOS Mojave 10.14.4
- Drupal 8.6.14
- Docker 18.09.3
- Docker Compose 1.24.0-rc1
- Expresso PHP v1.1.0
Setting up Drupal using Expresso PHP
The first step is cloning the Expresso PHP Git repo and doing some initial setup. This installation assumes you are installing Docker sites in a "Docker" directory within your local environment's home directly. In the directions for this example, the site in question is called "my-site."
cd ~/docker git clone https://github.com/expresso-php/expresso-php.git my-site cd my-site git checkout nginx-php
After cloning the repo, specify the desired PHP version here:
The first line will look something like this:
Next, clone the Drupal site's Git repo or otherwise add the site. This example assumes the repo will be cloned within a directory called "my-site", so its location would be
Replace the existing "web" directory with a symlink to the document root:
rm -rf ~/docker/my-site/web cd ~/docker/my-site ln -s my-site/docroot web
This example assumes the document root is "docroot" but it could be "www" or something else.
Copy the settings.php file from default.settings.php
cd ~/docker/my-site/my-site/docroot cp sites/default/default.settings.php sites/default/settings.php cd sites/default
Edit settings.php and replace
$databases = array();
with the following
$databases['default']['default'] = [ 'database' => 'expresso-php', 'username' => 'expresso-php', 'password' => 'expresso-php', 'host' => 'db', 'port' => '3306', 'driver' => 'mysql', 'prefix' => '', 'collation' => 'utf8mb4_general_ci', ];
Edit settings.php and replace
$settings['hash_salt'] = '';
$settings['hash_salt'] = 'expresso-php';
A local domain can be used to update the host’s file. You will need to use sudo to edit /etc/hosts and add the following:
Optionally, create a directory for a copy of the site's database and place a *.sql of the database into this directory:
cd ~/docker/my-site mkdir ref_db cd ref_db
This is only needed if a Makefile or build script will be used, which is recommended; otherwise, DB import could be done via drush.
Note - The designated location for the reference database may be different for a given Makefile or build script.
Add the Drupal files directory here and modify permissions if needed:
Build the Docker containers:
cd ~/docker/my-site docker-compose up -d
Note - This is only needed during initial set, on a daily basis, "docker-compose start" and "docker-compose stop" will be sufficient.
The next step is importing the Drupal database. Ideally this would be done via a Makefile or build script.
Alternatively, the DB import can be done via Drush:
cd ~/docker/my-site/docroot docker-compose exec -T php_nginx drush sql-cli < ../ref_db/ecoDB.sql
Once the DB is imported, check the port needed to access the site:
It will use the port associated with my-site_nginx_1; for example 32768.
Access the local website to confirm it works. For example, if the IP is 32768 then the site's URL would be:
Commonly Used Commands
To use Drush:
docker-compose exec php_nginx drush cr
To SSH in to the nginx container:
docker-compose exec php_nginx /bin/bash
To start services:
To restart services:
docker-compose restart docker-compose ps
"docker-compose ps" is included here since restarting services resets the port used to access the site.
To uninstall the site:
cd ~/docker/my-site/my-site/docroot docker-compose down -v cd ~/docker rm -fr ~/docker/my-site
That's all there is to it. When a build script or Makefile is used, a new environment can be set up from the script in a matter of minutes. The main, limiting factor is time needed to copy in the Drupal files/ directory and import the database.
Expresso PHP and Docker are excellent tools that enable you to maintain a straightforward setup process, even as complexity increases -- serving as another clear indicator of the inherent agility of Drupal.
Looking for further insights on leveraging Drupal to achieve specific outcomes? Contact us today.