DEV Community 👩‍💻👨‍💻

Robin Kretzschmar
Robin Kretzschmar

Posted on

Set docker build args from .env file (NextJS)

I recently came across the issue that I had to build a Docker container with a NextJS app inside that was relying on a environment variable to set the domain for Plausible.io.
The tricky thing was that I was building the container once and deploying it to multiple pods with different environment configs.

Technically docker can respect a .env file when it is run with the option --env-file like so:

docker run --rm --env-file .env -p 3000:3000 -d YOUR_CONTAINER_TAG:prod
Enter fullscreen mode Exit fullscreen mode

So here comes the issue...

But since the environment was set during build time inside the container and NextJS has automatic site optimiziation and builds pre-rendered pages for server-side render during build, the environment variables from the Docker build run were baked into the image and it did not care about the .env file for server logic.

A small bash script to the rescue

I am using Envault to manage environment configs and since the image is being build with a Jenkins pipeline, the pipeline pulls the correct .env file from Envault each time.
Inside the Dockerfile, change the vars to be this:

ARG DB_USER
ARG DD_SVC_NAME
ENV DB_USER=$DB_USER
ENV DD_SVC_NAME=$ARG DD_SVC_NAME
Enter fullscreen mode Exit fullscreen mode

This means the build command needs to contain --build-arg paramters for each variable.
To read those from the .env file via bash, we can use this:

$(for i in `cat .env`; do out+="--build-arg $i " ; done; echo $out;out="")
Enter fullscreen mode Exit fullscreen mode

The docker command looks like this:

docker build -f Dockerfile -t MYTAG:prod $(for i in `cat .env`; do out+="--build-arg $i " ; done; echo $out;out="") .
Enter fullscreen mode Exit fullscreen mode

Bonus round: makefile

Since I love Makefiles, there is a small pitfall how to include the bash loop into the command, so here is my Makefile for reference:

SHELL := /bin/bash
...
# this line will set the build args from env file
DECONARGS = $(shell echo "$$(for i in `cat .env`; do out+="--build-arg $$i " ; done; echo $$out;out="")")
GEN_ARGS = $(eval BARGS=$(DECONARGS))

.PHONY: dist-prod
dist-prod:
    @echo "Running docker build for PROD ..."
        $(GEN_ARGS)
    docker build -f Dockerfile -t $(TAG_SHA) $(BARGS) .
...
Enter fullscreen mode Exit fullscreen mode

Top comments (2)

Collapse
 
naubit profile image
Al - Naubit

That was a nice read! Liked, bookmarked and followed, keep the good work!

Collapse
 
darksmile92 profile image
Robin Kretzschmar Author

Thanks! :)

🌚 Life is too short to browse without dark mode