
Bind Volumes are essential to the Drupal developer when using Docker. They allow you to synchronize a directory on your laptop or workstation with a directory in the container. Changes can be replicated in either direction -- from the container to the host OS, or from the host OS to the container. You can add a bind volume to a Compose file with just a single line of code.
In this tutorial, we'll:
- Describe how to use the
volumes
key in your Compose file - Best practices for describing mount points
- Introduce different synchronization strategies for volumes and which to use
Docker's goal is to treat containers as reusable, off-the-shelf pieces of infrastructure. Often, however, we need to tailor a container to our specific needs. We may need to enable debugging facilities, enable key configuration options, create databases, and set logins. Many development-oriented containers rely on environment variables to configure containers at runtime.
In this tutorial, we'll:
- Set environment variables using a static value in the Compose file
- Use an environment file to pass multiple variables at once
Network communication is essential when developing for a multi-tier web application like Drupal. Docker automatically isolates each container it runs, only allowing explicit ports to be exposed to the host OS. Docker Compose takes this one step further.
In this tutorial, we'll:
- Explain how Docker isolates containers
- Expose a container's ports to the host OS
- Re-map ports from the container to the host OS
A common task when developing a Drupal site is loading the database into your local development environment. When working with non-Docker local development environments, command line tools or a graphical application are used to load the database dump. These methods also work for Docker with a bit of container configuration. With Docker, you can include all the tooling in containers, reducing the need for utilities on the host OS.
In this tutorial, we'll:
- Outline the challenges for loading a database into a container
- Identify the methods by which a database can be loaded into a container
One of Docker's goals is to make it as simple to deploy and update infrastructure as it is to pull a product off of a shelf. At the center of this goal is Docker Hub, a massive, public, and free-to-use library of Docker images for you to use. As a free service, additional care is required to select images that will provide you with updated, secure, and well-maintained infrastructure.
In this tutorial, we'll:
- Show how Hub is an integral part of using Docker
- Describe registries and private registries
- Identify official images vs. contributed images
- Outline best practices for selecting an image on Hub
When we issue docker run
, Docker will attempt to download any images it doesn't have cached locally. Locally cached images take up disk space and are not automatically managed. Furthermore, once downloaded, Docker never updates them for you. You can list, update, or delete locally cached images using the docker
command.
In this tutorial, we'll:
- Show how to list all images currently stored on your host OS
- Identify the disk space occupied by cached images
- Learn to explicitly download and update a locally cached image
- Learn to delete images on your system
Often we need a particular version or variation of software in order to support our project. Our site might require Apache Solr 4.x, whereas the same project could be perfectly fine with the latest version of MySQL. Since image names need to be unique on Docker Hub, it'd be inconvenient to require a separate image name for each version of a particular piece of software. Docker solves this problem by using tags.
In this tutorial, we'll:
- Define tags
- Describe how tags are used
- Explain the
latest
tag - Show how to find a container's tags on Docker Hub
- Use a tag with
docker
commands, and in the Compose file
Creating a container set to support Drupal development requires some specialized knowledge. Now that we understand containers, images, how to use Docker Compose (docker-compose
), and how to select images on Docker Hub, we're ready to build a container set to support Drupal development.
In this tutorial, we'll:
- Select images of software that we'll need to run Drupal
- Create a new Compose file
- Configure bind volumes and environment variables to support the site
- Test the configuration
See Dockerize an Existing Project if you already have Drupal installed.
One of the primary goals of Docker is to make it as easy to try out and deploy technical infrastructure as it is to pull an item off of a store shelf. But how are these containers built in the first place? A Docker image is built from a Dockerfile, a kind of container source code. The Dockerfile describes how to build and configure a single container.
In this tutorial, we'll:
- Introduce Dockerfiles and see how Docker uses them to build container images
- Outline the general structure of a Dockerfile
- Describe how to build a new image from a Dockerfile
Creating a custom image only requires a Dockerfile with a FROM directive, but since this only renames the image, how do we actually change it? When building a custom image, we often need to add files. Whether they are config files, scripts, compressed archives, or even application binaries, Docker makes it easy to add a file to an image with just one directive.
In this tutorial, we'll:
- Describe how to position files relative to your Dockerfile
- Use the
COPY
directive to add local files - Download remote files using the
ADD
directive
The COPY
and ADD
directives make it easy to add configuration files or download archives to a container image. While we could install applications into a container using only those directives, it would be difficult and complex. Making matters worse, Docker provides no INSTALL
directive. Instead, Docker provides a more general mechanism.
In this tutorial, we'll:
- Introduce the
RUN
directive and how to run commands during adocker build
- Use package managers to install applications
- Describe best practices for installing software in images
Installation is only one part of setting up a custom Docker image. With few exceptions, we'll want to configure the application to better suit our use case. Docker does not provide a standardized way for applications to be configured. Instead, we rely on the same techniques as we would when configuring the application on a bare-metal server.
In this tutorial, we'll:
- Extract default configuration files from a Docker image
- Give strategies for adding configuration files to the image
- Outline the complexities of using configuration commands in a Dockerfile
The goal of Docker containers is to let you select pieces of technical infrastructure as if you were pulling items off of a shelf. Toward that end, each container image can be configured with a default application to invoke when started with a docker run
or as part of a container set with docker-compose up
.
In this tutorial, we'll:
- Describe the difference between the build-time and runtime environment of a container
- Use the
CMD
directive to specify a default command to execute - Introduce the
ENTRYPOINT
directive and set a default shell in which to run yourCMD
The ENTRYPOINT
directive allows us to specify a default shell to use in our custom image, but it can do more than that. Often, we will want to dynamically configure a container on startup by passing it environment variables or using Docker Secrets. By replacing the ENTRYPOINT
with a custom script, we can perform this dynamic configuration prior to executing the default application.
In this tutorial, we'll:
- Introduce custom entrypoint scripts
- Describe several strategies for performing dynamic configuration in a container
Often you'll find an image on Docker Hub that almost fits your requirements. For Drupal developers, often the off-the-shelf containers for PHP just aren't enough. Drupal often requires additional PHP extensions such as mbstring
or gd
. We may also want to use a slightly different configuration, or bake-in a utility like Drush or Drupal Console. Fortunately, Docker makes modifying existing containers easy in a Dockerfile.
In this tutorial, we'll:
- List the reasons why you might modify an existing image
- Describe the general process by which an existing image is modified
When writing containers for a local development environment, security is often a lesser concern. This is fine as long as we never intend to put the containers we create in a production environment.
When we do want to make production-ready containers, however, our priorities change. While Docker tries to be secure by default, it can't protect us from badly configured or vulnerable applications. For that, we need to design our images to be more secure.
In this tutorial, we'll:
- Outline the best practices for writing secure container images
- Introduce the
USER
directive - Set file ownership using
COPY
andADD
- Use the
RUN
directive to set file permissions
Getting Drupal to run in Docker requires a lot of moving parts. After installing Docker and Docker Compose, we need to select a collection of containers from Docker Hub and create a new docker-compose.yml file. Once we have environment variables and volumes configured, this only gives us the capability of running a Drupal site in Docker.
What if we already have a Drupal site we want to develop using Docker? In this tutorial, we'll show how to modify an existing project to minimize the setup time necessary for switching to a Docker-based environment.
In this tutorial, we'll:
- Describe the best practices for project organization.
- Use an environment file to configure containers.
- Add a Docker-specific settings.php file.
Dockerizing a project helps to simplify setting up new developer workstations, and on-boarding new team members. All the pieces of infrastructure necessary to get started are all in the Compose file. Yet, it's not as easy as it could be.
We still need to create a settings.local.php file with all the necessary database connection information and any setting overrides. In this tutorial, we'll move those out of the local settings file and into a Docker specific settings file that ships with all that information pre-configured out of the box.
In this tutorial, we'll:
- Explain the motivation behind having a Docker-specific settings file.
- Describe how to modify settings.php to detect when it's in a Docker environment.
- Create a Docker-specific settings file with everything preconfigured.
One of the problems with Dockerizing an existing project is that configuration information tends to proliferate everywhere. Not only do we have settings in docker-compose.yml, but also in our Docker-specific settings file settings.docker.php. If we change a setting in one place we need to copy and paste it everywhere else. This can make things difficult if we suddenly have the need to change a setting.
Fortunately, there's a way to centralize Docker configuration for our project by using an environment file.
In this tutorial, we'll:
- Review what an environment file is and its format.
- List the advantages of moving Docker configuration to an environment file.
- Describe the .env file, and how it provides us further advantages.
Throughout this series we've been focused on working with a single set of containers and a single site. For most Drupal developers, however, we're expected to work with multiple client sites, sometimes several different ones in the same day.
When we add Docker into the mix, it can seem overwhelmingly complicated when you're used to working with other tools. Fortunately, there are several simple practices that not only work well with Docker, but also support your workflow.
In this tutorial, we'll:
- Outline the best practices when building a local development environment in Docker.
- Compare the differences in workflow when using Docker compared to other local development environments.
- Discuss various strategies to reduce resource use on team workstations.