Dockerfile build arguments go out of scope

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).


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.

So, remember that Dockerfile build arguments go out of scope

If you’re wondering why your build arguments are not being set when building images using your Dockerfiles, more than likely, this is why.

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...

Validate Dockerfiles With One Command
Tue, Aug 27, 2024

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.

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.


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