Learn Docker With My Newest Course

Dive into Docker takes you from "What is Docker?" to confidently applying Docker to your own projects. It's packed with best practices and examples. Start Learning Docker →

Docker Tip #47: Build Time vs Run Time ENV Variables

blog/cards/docker-tips-and-tricks.jpg

Docker allows you to set both build time and run time ENV variables and even lets you overwrite build time ENV vars at run time.

There may come a time where you’ll want to add an ENV variable to your Docker image, but you’ll want this value to be different depending on where you build your image, but you don’t want to edit your Dockerfile to change it.

You may also want to sometimes overwrite that value at run time (not build time).

Setting up a Docker image with a build argument and ENV variable:
FROM debian:stable-slim

ARG YOURAPP_ENV=production
ENV YOURAPP_ENV="${YOURAPP_ENV}"

YOURAPP_ENV could be RAILS_ENV, NODE_ENV or whatever environment variable you want to set at build time.

The ARG and ENV variable names don’t need to match, but it’s generally a good idea to keep them the same for consistency. In this case, the ENV variable will default to whatever the ARG is set to at build time (or “production” if none is supplied).

A few outcomes when building and running the above Docker image:
# A typical build.
docker build -t yourapp .
docker run --rm yourapp env | grep YOURAPP_ENV
> YOURAPP_ENV=production

# Building it with a custom --build-arg value.
docker build -t yourapp --build-arg YOURAPP_ENV=staging .
docker run --rm yourapp env | grep YOURAPP_ENV
> YOURAPP_ENV=staging

# Overwriting the ENV's value at run time instead of build time.
docker run --rm -e YOURAPP_ENV=development yourapp env | grep YOURAPP_ENV
> YOURAPP_ENV=development

If you’re using Docker Compose instead, it supports both setting build arguments and also setting environment variables at run time, so this all works the same way.

A quick Docker Compose example that sets a build argument:
services:
  yourapp:
    build:
      context: "."
      args:
        YOURAPP_ENV: "helloworld"

Now if you run docker-compose up --build and took a look at the environment variables in the container you would see YOURAPP_ENV=helloworld.

You could even define that arg as a variable with ${YOURAPP_ENV:-helloworld} and if you have it defined in a .env file then Docker Compose will pick it up automatically. If it’s not defined it’ll fall back to the default value of helloworld.

Also, if you set YOURAPP_ENV as an environment variable in the docker-compose.yml file with the environment property (or being loaded in from a file with env_file) it would overwrite the build argument just like it did without Docker Compose. Feel free to try that out on your own!

Free Intro to Docker Email Course

Over 5 days you'll get 1 email per day that includes video and text from the premium Dive Into Docker course. By the end of the 5 days you'll have hands on experience using Docker to serve a website.



Comments