When building a Docker image for your PHP application there are some steps you should take to prevent the cache from being invalidated prematurely. Cache misses can slow down the build process drastically.
Consider the following Dockerfile snippet:
The first instruction is to install Composer. Then we change the working directory to
/app which is created if it doesn’t already exist.
COPY instruction will copy your application’s source directory to the file system of the container. These files have likely been changed and the
COPY instruction will invalidate the cache, which means that all subsequent Dockerfile instructions will run on every build.
Having Composer install all its dependencies on every build is not ideal.
Here’s an alternative Dockerfile:
Instead of copying all the source files we only copy
composer.lock. These rarely change and will not invalidate the cache. Neither will the
RUN instruction unless you change the command itself.
With these files in place we can run
composer install before the cache is invalidated by the new application source files; our dependencies will not be downloaded with every Docker build. However, without the source files we cannot run our Composer scripts or build the autoloader just yet, so we use the
Then, only after we have copied all the source files, we dump the autoloader and run the scripts.
The output from
docker build will look something like this:
Now Docker is reusing the cache for all but the last layer where the source code is copied.
Because we’re copying the entire source directory into the image, any file change will invalidate the cache, even the change of a log file. We can easily remove certain files and directories from the build context by adding a
.dockerignore file which lists all the items we want to exclude, e.g. a
Generally speaking, any file that isn’t required by your image should be added to
.dockerignore in order to increase build performance.