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).
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:
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.
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.
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).
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.
Recently, I deployed a Go-powered app backed by an SQLite database on Fly.io for the first time. Here’s the process that I went through, along with some of the issues that I encountered along the way.
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.
Please consider buying me a coffee. It really helps me to keep producing new tutorials.
Join the discussion
comments powered by Disqus