I get asked this question often, so I figured I would document how I setup my Craft installations that are powered by Docker. There are three main components to my setup; a Dockerfile, Makefile, and docker-compose.yml.
The Dockerfile is the main "workhorse" for my flow, it should represent the entirely of the application and should be near identical to production as possible. Some people opt for a `Dockerfile.dev` and `Dockerfile.production` but I personally find this as a cumbersome workflow; especially when your team grows someone will forget to update one and push a deployment.
I always keep my Dockerfile in "production" mode. This means I don't install xdebug or other local development tools, for those requirements I tend to place those commands in the Makefile (e.g. `make xdebug` which will execute the installation steps inside the local docker container). This flow also allows the CI/CD tools to install xdebug in the staging or test process when needed.
This Dockerfile uses the PHP Apache image as a base, since we modified a few items (specifically the path to the document root) we need to add our own Apache configuration. You can see this in the COPY step in the Dockerfile above.
A lot of load balanced applications will also need to set the `X-Proto-Forwarded` header to properly pass HTTPS
This file is used for local development, instead of running a long list of docker commands, the docker-compose file allows you to "bootstrap" your applications dependencies such as PostgreSQL and Redis.
There are a few key items of note in the docker-compose file.
Instead of writing a lot of local scripts and storing in the code repository, I tend to use a Makefile. This allows me, or anyone on the team, to add repeatable commands to use among the team. There are some specifics to tagging the images and pushing to the Docker Container Registry, but the one command specific to Craft is local, using the Craft CLI to quickly install your local development environment with one command
This is not a complete example, as it is missing a few build steps like testing.
One really interesting thing to note is the Makefile syntax which is a little difficult to find `SOMETHING ?= this`. This will check for the environment variable SOMETHING and if it is not found, it will default to something. This allows your CI/CD tools to be really flexible and define variables for each build step.
A while ago, Google updated their PageSpeed Insights to start using Lighthouse for analyzing accessibility, performance, SEO, and progressive web apps. The way we used to calculate our score was to ship the application to a staging server and run PageSpeed Insights. That process was time consuming and most developers just gave up on it.
Most people don't know that you can run these checks locally and also get a list of items that need to be corrected. This means you can maximize your score locally without shipping to a publicly available server!
Another excellent talk from GraphQL summit