Last updated May 16, 2019

Just as you would for Drupal, you should always test your search configuration prior to deploying it to production. In this tutorial, we examine the various ways to set up Apache Solr locally on your system.

In this tutorial, we'll:

  • List which popular local development environments provide Solr
  • Describe how to find a Solr Docker container
  • How to set up a local, Docker-based local dev environment with Solr

Goal

Set up a local web development environment with Solr using Docker.

Prerequisites

General Docker knowledge, including how to "Dockerize" an existing project. If you need a refresher in any of these areas of knowledge, please visit:

Local development environments for Drupal

When developing a Drupal site, it is best practice to create a copy of your site and run it locally. This requires you to have a web server, PHP, and a database such as MySQL installed on your laptop or workstation. While each of these components could be installed separately, this can be a considerable amount of work on macOS and Windows.

Fortunately, many pre-packaged web development environments have appeared to simplify this task. Generally, these pre-packaged environments fall into one of two categories:

  • Natively installed
  • Virtualized

Natively installed web development environments simply package up a collection of pre-configured applications to support development. Often a UI is provided to create additional local site instances with different versions, services, logins, and so on. MAMP and Acquia Dev Desktop fall into this category.

The drawback is that natively installed web development environments do not run the same configuration, software, or even operating system as the production server. This can result in odd bugs and edge cases that cannot be easily reproduced. Virtualized web development environments allow Linux server applications to run on macOS or Windows without modification. This allows the same software and configurations to be used both locally and on the production server.

Local development environments that support Solr

Natively installed web development environments like MAMP and Acquia Dev Desktop do not support Solr out of the box. Instead, you need to install Solr as you would a standalone server application. This can make these environments less desirable for doing search development.

Fortunately, many virtualized web development environments offer Solr as an optional extra:

Choose a Solr container

Many developers choose to use their own set of Docker containers to run their site locally. Often, these are custom or customized containers with a specific set of versions, features, and configurations parallel to the production environment. Some organizations have also chosen to open source their containers for everyone to use such as Docker4Drupal and Flight Deck.

When choosing a Solr container for Drupal development, it must meet the following criteria:

  • It provides a Solr version compatible with the Search API Module.
  • It has a means of loading custom schemas, or can automatically create search configurations (cores) compatible with Search API.

Create custom containers for this series

This series of tutorials provides a custom set of Docker containers to provide Apache/PHP, MySQL, and Solr. The Solr container is specifically configured to be compatible with Search API, and to allow the creation of Search API-compatible cores. We'll set those up now.

Create the project directory structure

For many Drupal developers, it is common practice to have the root of the project directory at the same level as the site docroot. Unfortunately, this practice creates a number of problems. Instead, it's best to move the site's docroot to a subdirectory:

/path/to/my_project
+-- .git/
+-- docroot/
    +-- core/
    +-- index.php

The above example uses docroot for the site directory name. It can easily be public_html, webroot, htdocs, src, or whatever makes the most sense for you. This series will use docroot going forward.

When working with Docker containers, it is often useful to create a directory within the project to serve as a bind mount. (See also Use Bind Volumes.) The contents of a bind-mounted directory are synchronized between your host system and a target directory inside the container. Once such use is to provide a place for the database container to access database dumps. This way, we can load the dump into the database as if we had uploaded it to a remote MySQL server.

To prevent Git from tracking the files in this directory, we add a .gitignore with common database dump file extensions to the db-backups directory:

/path/to/my_project
+-- .git/
+-- db-backups/
|   +-- .gitignore
+-- docroot/
    +-- core/
    +-- index.php

Finally, we also add a config/ directory to the root of our project. Inside that directory, we add a sync/ directory so that we can export our site config outside the containers:

/path/to/my_project
+-- .git/
+-- db-backups/
|   +-- .gitignore
+-- config/
|   +-- sync/
|       +-- .gitkeep
+-- docroot/
    +-- core/
    +-- index.php

To assure that Git tracks the directory (which is initially empty of files), we add a .gitkeep file. This is an empty file with an arbitrary name, but useful, as Git only tracks files and file paths, not directories.

Create docker-compose.yml

Next, create the Docker Compose file: docker-compose.yml. This file should be created in the root of your project directory:

/path/to/my_project
+-- .git/
+-- db-backups/
|   +-- .gitignore
+-- config/
|   +-- sync/
|       +-- .gitkeep
+-- docker-compose.yml
+-- docroot/
    +-- core/
    +-- index.php

Furthermore, assure that your project directory (my_project in the above example) is unique throughout your system. It will be used to name the containers once started.

Once the file is created, populate it with the example containers:

version: '3'
services:
  web:
    image: osiolabs/drupaldevwithdocker-php:7.2
    volumes:
      - ./src:/var/www/html:cached
      - ./config:/var/www/config:cached
    ports:
      - "80:80"
  db:
    image: osiolabs/drupaldevwithdocker-mysql
    volumes:
      - ./db-backups:/var/mysql/backups:delegated
    environment:
      MYSQL_ROOT_PASSWORD: root
      MYSQL_DATABASE: drupaldb
      MYSQL_USER: drupal
      MYSQL_PASSWORD: verybadpassword
    ports:
      - "3306:3306"
  pma:
    image: phpmyadmin/phpmyadmin
    environment:
      PMA_HOST: db
      PMA_USER: root
      PMA_PASSWORD: root
      PHP_UPLOAD_MAX_FILESIZE: 1G
      PHP_MAX_INPUT_VARS: 1G
    ports:
     - "8001:80"

The above Compose file describes several containers:

  • web provides an Apache web server with PHP.
  • db provides a MySQL database.
  • pma provides a PhpMyAdmin container to interact with the database.

Note how many of the containers also have an environment section which specifies key configurations such as the database name and credentials.

Add the Solr container

The above container set does not yet provide a Solr container for our use. To do that, add the following, being sure that solr is at the same indent level as web and db.

solr:
  image: osiolabs/drupalsearchapi-solr:6.6
  ports:
    - "8983:8983"

The above describes a Solr container providing Solr 6.6 that was created for this course. Furthermore, we expose the default Solr administration port of 8983 for access.

Add an alias to localhost

You might wonder, now that the Solr port has been exposed, how would we access it? After all, there's no domain name or IP address specified in the Compose file. Remember, Docker doesn't so much run a virtual machine as it runs sandboxed Linux applications. Any container running on your system can be accessed from the loopback domain, localhost.

The loopback domain, however, causes some problems with Drupal. localhost is considered a special case in a networking sense. Drupal prefers to be accessed from a non-loopback domain. But we don't want to buy a domain just to point it at our laptop! Instead, we can configure a loopback alias by modifying our system's hosts file:

On macOS and Linux, the process is similar:

  1. Open a new terminal application.
  2. Use sudo to edit the hosts file as the superuser: sudo nano /etc/hosts
  3. Edit the file, adding the following: 127.0.0.1 docker.test
  4. Save and close the editor.

The use of the nano text editor isn't a requirement. Feel free to use whatever text editor you prefer.

On Windows, the process is a little more complicated:

  1. Use the Start menu to search for Notepad.
  2. Right-click the Notepad application and select Run as administrator.
  3. Open the Hosts file: C:\Windows\System32\Drivers\etc\hosts
  4. Edit the file, adding the following: 127.0.0.1 docker.test
  5. Save and close the file.

Once saved, we can now access our containers using docker.test instead of localhost.

Use Compose to "up" the container set

Once the Compose file has been saved, open a new terminal prompt. Navigate to your project directory:

cd /path/to/my_project

Next, we'll download the containers explicitly:

docker-compose pull

Finally, we'll start all the containers in the set:

docker-compose up -d

Validate Solr is up

After "upping" the container set and waiting several seconds, Solr will be ready to use. Using a web browser, navigate to the following address:

http://docker.test:8983

You should see a Solr administration screen.

Install Drupal as normal

Next, navigate to the Drupal site itself:

http://docker.test

You will be taken the the Drupal installation screen. Follow the on-screen instructions. For the database host name, use the database container's service name, db. Use the values of MYSQL_DATABASE, MYSQL_USER, and MYSQL_PASSWORD from your docker-compose.yml when configuring the database credentials.

Recap

There are many options for running Solr locally on your system. While you can install it natively, most often you will rely on your web development environment's preferred Solr installation method. For this series, we will be using a custom container set pre-configured to work with Drupal and Search API.

Further your understanding

  • What if you need Solr for multiple Docker-based projects?

Additional resources