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.
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).
Recently, I was creating a new Dockerfile for a PHP web app that I’m building, one that I’m planning to deploy to Fly.io.
In that Dockerfile, I have the following stage:
FROM base as final
ARG DATA_DIR=/opt/data
# The PHP app lives here
WORKDIR ${APACHE_DOCUMENT_ROOT}
# Copy over the application code
COPY . .
# Copy over the Composer vendor directory from the dependencies stage
COPY --from=dependencies ${APACHE_DOCUMENT_ROOT}/vendor ${APACHE_DOCUMENT_ROOT}/
# Change the document root and enable mod_rewrite
RUN sed -ri -e 's!/var/www/html!${APACHE_DOCUMENT_ROOT}/public!g' /etc/apache2/sites-available/*.conf \
&& sed -ri -e 's!/var/www/!${APACHE_DOCUMENT_ROOT}/public!g' /etc/apache2/apache2.conf /etc/apache2/conf-available/*.conf \
&& a2enmod rewrite
# Build the data directory structure and ensure that they can be written in
RUN mkdir -p ${APACHE_DOCUMENT_ROOT}/logs ${APACHE_DOCUMENT_ROOT}/cache \
&& chown -Rv ${APACHE_RUN_USER}:${APACHE_RUN_GROUP} ${APACHE_DOCUMENT_ROOT} \
&& chmod -Rv ug+w ${APACHE_DOCUMENT_ROOT}
Frustratingly, while attempting to build an image from the Dockerfile, I was getting errors relating to APACHE_DOCUMENT_ROOT
, such as the following:
=> ERROR [dependencies 6/8] RUN chown -Rv www-data:www-data ${APACHE_DOCUMENT_ROOT}
------ > [dependencies 6/8] RUN chown -Rv www-data:www-data ${APACHE_DOCUMENT_ROOT}:
0.152 chown: missing operand after 'www-data:www-data'
0.152 Try 'chown --help' for more information.
------
As you can see, the build argument was not defined, so the command using it was failing. I was, initially, confused as I’d defined the build argument at the top of the Dockerfile, before the first stage, as follows:
ARG APACHE_DOCUMENT_ROOT=/var/www
I was of the understanding that if you define a build argument before the first stage, that it, effectively, had global scope, so was accessible to all stages within the Dockerfile.
Given that, I thought that the variable would be set at this point. Sadly, I was wrong. But, I always love learning and filling in the gaps in my knowledge; so this was a fun opportunity to do so.
After reviewing the Dockerfile documentation, I found the following near the end of the Scope section:
An ARG instruction goes out of scope at the end of the build stage where it was defined. To use an argument in multiple stages, each stage must include the ARG instruction.
Based on that, I defined APACHE_DOCUMENT_ROOT
in the relevant stages and removed it from the top of the Dockerfile.
On running docker build
again, the image built successfully.
It feels a bit wrong to define a build argument multiple times. but, I can see some benefits in doing so too.
If you’re wondering why your build arguments are not being set when building images using your Dockerfiles, more than likely, this is why.
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.
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.
Laracon AU 2024 is over, so I thought I’d share a bit of what it was like for me, especially as I’ve not been to Laracon before.
Please consider buying me a coffee. It really helps me to keep producing new tutorials.
Join the discussion
comments powered by Disqus