Validate Dockerfiles With One Command

Validate Dockerfiles With One Command

Docker is an excellent way of deploying software. But, how do you know if your build configurations (your Dockerfiles) are valid without building them? In this short tutorial, I’ll show you how.


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.

Do you need to get your head around Docker Compose quickly?

What about needing to dockerize existing applications to make them easier to deploy, reducing the time required for develwpers to get started on projects, or learning how to debug an existing Docker Compose-based app? Then this free book is for you!

You might also be interested in these tutorials too...

Dockerfile build arguments go out of scope
Fri, Jun 14, 2024

Dockerfile build arguments go out of scope

When you’re writing Dockerfiles using build arguments (which you should) it’s important to keep their scope in mind. Otherwise, you’ll get very frustrated (more than likely).

Setup Step Debugging in PHP with Xdebug 3 and Docker Compose
Wed, Mar 10, 2021

Setup Step Debugging in PHP with Xdebug 3 and Docker Compose

In versions of Xdebug before version 3 setting up step debugging for code inside Docker containers has often been challenging to say the least. However, in version 3 it’s become almost trivial. In this short tutorial, I’ll step you through what you need to do, regardless of the (supported) text editor or IDE you’re using.

Override an Image's Command with Docker Compose
Thu, Oct 26, 2023

Override an Image's Command with Docker Compose

Sometimes, you need to override an image’s command when launching a container with Docker Compose. If you need to do that, in this tutorial I’m going to show you how — without the need to update an image’s Dockerfile or shell scripts.


Want more tutorials like this?

If so, enter your email address in the field below and click subscribe.

You can unsubscribe at any time by clicking the link in the footer of the emails you'll receive. Here's my privacy policy, if you'd like to know more. I use Mailchimp to send emails. You can learn more about their privacy practices here.

Join the discussion

comments powered by Disqus