DEV Community

Cover image for Fix an issue on my Dockerfile: ARG Scope in Multi-Stage Docker Build
Manuel Artero Anguita 🟨
Manuel Artero Anguita 🟨

Posted on

4 1 1 1

Fix an issue on my Dockerfile: ARG Scope in Multi-Stage Docker Build

OK, so this one had me stuck until I hit the Eureka moment,
the "Oooooohhhh, gotcha!" moment.

Context

Specifically this was for a web-app, we use a node:alpine as builder, install the dependencies and build the app; then use an nginx image and copy the static build to /usr/share/nginx/html.

I bet you have done similar.

For reference, the Dockerfile 🐳:

FROM node:20-alpine AS builder

ARG VERSION
WORKDIR /app

COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/bin /app/bin
COPY --from=builder /app/build /usr/share/nginx/html
COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf

RUN echo "{\"version\": \"$VERSION\"}" > /usr/share/nginx/html/_v.json

CMD ["/app/bin/serve-prod"]
Enter fullscreen mode Exit fullscreen mode

Now, check this layer:

RUN echo "{\"version\": \"$VERSION\"}" > /usr/share/nginx/html/_v.json
Enter fullscreen mode Exit fullscreen mode

this is an specific use case, our infra rely on our services to expose this _v.json which is returning something like

{ "version": "2.11.0-ea34fd5" }
Enter fullscreen mode Exit fullscreen mode

this wasn't working,

The problem

Building the image like:

npm run build:image
# docker build --build-arg VERSION=$VERSION-$SHA -f ./Dockerfile -t our-project:$VERSION-$SHA ."
#...
#=> naming to docker.io/library/our-project:2.11.0-ea34fd5
Enter fullscreen mode Exit fullscreen mode

...and running the container:

docker run -it --rm our-project:2.11.0-ea34fd5 /bin/sh
/ # cat /usr/share/nginx/html/_v.json
# {"version": ""}
Enter fullscreen mode Exit fullscreen mode

😭😭 Where is my $VERSION 😭😭


Explanation

Each FROM instruction defines a new stage.

Any ARG variable set in each stage is only accessible within that stage. Visually:

ARG are defined in their own stage

So, when I tried using an ARG for a version string defined in the build stage, it wasn’t available in the nginx stage.


Two possible fixes

In this case, since the VERSION argument is only used in the nginx step, this just works:

FROM node:20-alpine AS builder

-ARG VERSION
WORKDIR /app

COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
+ARG VERSION
+
COPY --from=builder /app/bin /app/bin
COPY --from=builder /app/build /usr/share/nginx/html
COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf

RUN echo "{\"version\": \"$VERSION\"}" > /usr/share/nginx/html/_v.json

CMD ["/app/bin/serve-prod"]
Enter fullscreen mode Exit fullscreen mode

An alternative: using ENV would promote the VERSION argument to env var:

FROM node:20-alpine AS builder

ARG VERSION
ENV VERSION=$VERSION
WORKDIR /app

COPY package.json package.json
COPY package-lock.json package-lock.json
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/bin /app/bin
COPY --from=builder /app/build /usr/share/nginx/html
COPY --from=builder /app/nginx.conf /etc/nginx/conf.d/default.conf

RUN echo "{\"version\": \"$VERSION\"}" > /usr/share/nginx/html/_v.json

CMD ["/app/bin/serve-prod"]
Enter fullscreen mode Exit fullscreen mode

This time i went for moving the ARG declaration but both solutions work.

--
Thanks for reading.

Sentry blog image

Identify what makes your TTFB high so you can fix it

In the past few years in the web dev world, we’ve seen a significant push towards rendering our websites on the server. Doing so is better for SEO and performs better on low-powered devices, but one thing we had to sacrifice is TTFB.

Read more

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay