Let's say that you've written the following Dockerfile to containerise one of your PHP applications.
# syntax=docker/dockerfile:1
ARG FPM_VERSION=alpine3.17
ARG PHP_VERSION=8.2.3
FROM php:${PHP_VERSION}-fpm-${FPM_VERSION} as base
RUN apk --update-cache \
add \
autoconf \
gcc \
icu-dev \
libzip-dev \
linux-headers \
make \
musl-dev \
sqlite \
&& pecl install xdebug \
&& docker-php-ext-install intl zip \
&& docker-php-ext-enable xdebug intl zip \
&& rm -rf /var/lib/apt/lists/* /var/cache/apk/*
COPY --from=composer:2.2.7 /usr/bin/composer /usr/bin/
WORKDIR /var/www/html
# Set up the log file directory with appropriate permissions
RUN mkdir -p data/log \
&& chmod -R 777 data/log \
&& chown -R www-data.www-data data/log \
&& touch data/log/webhook.log \
&& chown -R www-data.www-data data/log/webhook.log \
&& chmod -R 777 data/log/webhook.log
There’s not a lot to it. It is based on the Alpine Linux, php-fpm version of the official Docker Hub PHP image. The Dockerfile:
- Installs a number of dependencies, mainly to support running Composer
- Copies Composer from version 2.2.7 of the official Docker Hub Composer image
- Sets up the application’s directory structure, including assigning ownership of it to the www-data user and group
You have tests that validate your code, which you run before code is deployed. But, how do you validate a Dockerfile?
Well, available with Dockerfile 1.8 and Buildx version 0.15.0, the docker build command supports the --check option.
It checks a Dockerfile against a number of criteria, providing the required validation.
Assuming that we were in the same directory as the Dockerfile above, we’d run the command below to validate it.
docker build --check .
It would produce output pretty similar to the following.
[+] Building 3.6s (6/6) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 918B 0.0s
=> resolve image config for docker-image://docker.io/docker/dockerfile:1 1.8s
=> CACHED docker-image://docker.io/docker/dockerfile:1@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd5 0.0s
=> => resolve docker.io/docker/dockerfile:1@sha256:fe40cf4e92cd0c467be2cfc30657a680ae2398318afd50b0c8058578 0.0s
=> [internal] load metadata for docker.io/library/composer:2.2.7 1.6s
=> [internal] load metadata for docker.io/library/php:8.2.3-fpm-alpine3.17 1.6s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
WARNING: FromAsCasing - https://docs.docker.com/go/dockerfile/rule/from-as-casing/
'as' and 'FROM' keywords' casing do not match
Dockerfile:5
--------------------
3 | ARG PHP_VERSION=8.2.3
4 |
5 | >>> FROM php:${PHP_VERSION}-fpm-${FPM_VERSION} as base
6 |
7 | RUN docker-php-ext-install opcache
--------------------
Toward the bottom of the output, you can see a warning.
This indicates that the keywords in the FROM instruction use a mixture of upper and lower case.
There are a number of other build checks that are performed, such as if there are duplicate stage names, undefined variables, and attempts to copy files ignored by .dockerignore.
Now, let’s assume that you updated the Dockerfile, correcting the mixed casing of the FROM instruction and ran the command again.
You would then see output similar to the following, showing that no warnings were found.
[+] Building 0.9s (4/4) FINISHED docker:desktop-linux
=> [internal] load build definition from Dockerfile 0.0s
=> => transferring dockerfile: 340B 0.0s
=> [internal] load metadata for docker.io/library/composer:2.3.5 0.9s
=> [internal] load metadata for docker.io/library/php:8.3.9-fpm-alpine3.20 0.9s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
Check complete, no warnings found.
That’s how to validate Dockerfile
While it won’t guarantee that your build will work (though there is another command to do that) docker build --check is a good way to validate your Dockerfiles, a check that is almost trivial to integrate into your CI/CD build pipelines.