
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.
Today's Drupal sites often rely upon external services in order to serve their visitors. When hosting such a site in Docker, we need to take special consideration in order to allow the site to access these essential components.
In this tutorial, we'll:
- Outline the steps necessary for troubleshooting connectivity issues
- Discuss steps to protect API keys and other sensitive pieces of information
- Touch upon your options if you require external libraries or utilities
One of the key advantages of Docker is that it makes it much easier to share your containers with your team members. For most of this series, we've been relying on containers hosted on Docker Hub. When we need to create a custom container for our team, we want to leverage that same sharing infrastructure.
In this tutorial, we'll:
- Describe the various methods of sharing containers.
- Outline the advantages of using Docker Hub.
- Briefly describe why and when you should use a private container image registry.
For many container images on Docker Hub, the preferred approach is to create an automatic build. An automatic build integrates Hub with a public Git repository, providing you an effective, open, and best-practice approach to sharing your containers with your team, and with the world.
In this tutorial, we'll:
- List the advantages of creating an automatic build compared to other approaches on Docker Hub.
- Describe the process of creating an automatic build.
- Outline how to organize your git repository for your images.
- Learn how to configure and trigger the build on Hub.
Often it's useful for a container image to provide several variants of itself under the same name on Docker Hub. Docker uses tags to identify these variants. You can configure your own tags as part of your automatic build on Docker Hub.
In this tutorial, we'll:
- Outline the uses for tags
- Discuss the best practices for tag names
- Learn how to add tags to your automatic build on Docker Hub
Docker Hub provides a free, easy to use way of distributing your container images. However, there are situations where sharing your container images is either not ideal, bad practice, or against legal requirements. In those cases, you will want to use a private registry instead.
In this tutorial, we'll:
- Describe what a private registry is.
- Learn how to run Docker's own
registry
image. - Learn how to push and pull images from the self-hosted registry.
- Outline the production concerns for the
registry
image. - List other options for self-hosting your own images.
Docker provides numerous advantages for us as Drupal developers. It simplifies the management of infrastructure for our projects while allowing customization to suit each project's needs. Running Docker in production also brings a number of advantages, but it also creates new concerns.
In this tutorial, we'll:
- Outline the advantages Docker brings to the production environment.
- Highlight the concerns when planning a production deployment of Docker.
- Describe container orchestration and list several container orchestration platforms to choose from.
When you are implementing an HTTP API for a decoupled project, one of the critical, but often overlooked, aspects is the API documentation. Documenting your API will allow front-end developers (and you six months from now) to learn how to use that particular API.
In Drupal, there are several modules that can read your site configuration and generate documentation for you automatically.
In this tutorial we're going to:
- Learn about the importance of good documentation.
- Decide whether or not to use an existing specification for our API such as JSON:API or GraphQL.
- Review options for automatically generating documentation.
By the end of this tutorial you'll be able to decide whether or not using an existing documentation specification is a good fit for your project, and choose an option based on those available for use with Drupal.
JSON:API includes a way to request a list of entities of a given resource from the server. Collections are the best way to find content based on filters, and to build listings into the consumers. Moreover, collections can be combined with all the options you can apply to a single resource, like sparse fieldsets and includes.
In this tutorial we'll:
- Learn about what collections are in JSON:API
- Learn how to request, sort, and paginate lists of content
By the end of this tutorial you should know how to retrieve a list of resources from the JSON:API server, and how to optionally sort and paginate the items in the list.
Often, web services require the user to create content. Votes on content, ratings, comments, and user-submitted stories are good examples of this. The JSON:API module supports the creation of entities by sending data in POST requests.
In this tutorial we will:
- Add an appropriate set of HTTP headers to a request that generates a new entity
- Construct a JSON object for the entity we want to create
- Issue a POST request that creates a new article node in Drupal
By the end of this tutorial you should be able to create a POST request that creates a new entity of any type via the JSON:API.
Sometimes unexpected things happen and Drupal needs to generate an error. The JSON:API specification describes how the server should return those errors. Understanding what to expect allows consumers to plan for errors and react gracefully.
In this tutorial we will:
- Discuss how HTTP errors are used in conjunction with JSON:API
- Learn about how JSON:API embeds information about the error encountered into the response object
By the end of this tutorial, you should have a basic understanding of the types of errors you can expect to receive when making JSON:API requests and what you can do to handle them.
Collections are a very powerful feature because they allow us to access multiple items at the same time. However, in many situations we do not want to access all the entities of a given type, but only the ones that meet some specific criteria. In order to reduce the set of entities in the collection to the ones we care about, we use filters.
In this tutorial we will:
- Look at the
filter
query string parameter and how it can be used with JSON:API collections - Learn how to use filters in combination with the JSON:API module for Drupal to reduce the list of entities in a collection
By the end of this tutorial you should be able to request a list of entities in the form of a JSON:API collection and filter that list to include only the entities that match a specific set of requirements.
Embedding resources at the consumer's demand is one of the crucial features of a modern API. We mentioned in Modern Web Services with JSON:API and GraphQL that multiple round trips to the server is harmful for performance. This issue can be overcome by making a request that embeds any required related resources into the response for the resource we're retrieving.
In this tutorial, we'll learn how to use JSON:API's include
parameter to embed resources in a response.
By the end of this tutorial, you should be able to make a single request that retrieves multiple embeded resources in order to improve the performance of your application when interacting with a JSON:API server.