Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dockerfile: how to set env variable from file contents

I want to set an environment variable in my Dockerfile.

I've got a .env file that looks like this: FOO=bar.

Inside my Dockerfile, I've got a command that parses the contents of that file and assigns it to FOO.

RUN 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'

The problem I'm running into is that the script above doesn't return what I need it to. In fact, it doesn't return anything.

When I run docker-compose up --build, it fails with this error.

The command '/bin/sh -c 'export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")'' returned a non-zero code: 127

I know that the command /bin/sh -c 'echo "$(cut -d'=' -f2 <<< $(grep FOO .env))"' will generate the correct output, but I can't figure out how to assign that output to an environment variable.

Any suggestions on what I'm doing wrong?

like image 806
Ben Downey Avatar asked Aug 01 '18 21:08

Ben Downey


2 Answers

Environment Variables

If you want to set a number of environment variables into your docker image (to be used within the containers) you can simply use env_file configuration option in your docker-compose.yml file. With that option, all the entries in the .env file will be set as the environment variables in image and hence into containers.

More Info about env_file


Build ARGS

If your requirement is to use some variables only within your Dockerfile then you specify them as below

ARG FOO
ARG FOO1
ARG FOO2

etc...

And you have to specify these arguments under the build key in your docker-compose.yml

build:
  context: .
  args:
    FOO: BAR
    FOO1: BAR1
    FOO2: BAR2

More info about args


Accessing .env values within the docker-compose.yml file

If you are looking into passing some values into your docker-compose file from the .env then you can simply put your .env file same location as the docker-compose.yml file and you can set the configuration values as below;

ports:
  - "${HOST_PORT}:80"

So, as an example you can set the host port for the service by setting it in your .env file

Please check this

like image 187
chamindaindika Avatar answered Sep 16 '22 16:09

chamindaindika


First, the error you're seeing. I suspect there's a "not found" error message not included in the question. If that's the case, then the first issue is that you tried to run an executable that is the full string since you enclosed it in quotes. Rather than trying to run the shell command "export", it is trying to find a binary that is the full string with spaces in it and all. So to work past that error, you'd need to unquote your RUN string:

RUN export FOO=$(echo "$(cut -d'=' -f2 <<< $(grep FOO .env))")

However, that won't solve your underlying problem. The result of a RUN command is that docker saves the changes to the filesystem as a new layer to the image. Only changes to the filesystem are saved. The shell command you are running changes the shell state, but then that shell exits, the run command returns, and the state of that shell, including environment variables, is gone.

To solve this for your application, there are two options I can think of:

Option A: inject build args into your build for all the .env values, and write a script that calls build with the proper --build-arg flag for each variable. Inside the Dockerfile, you'll have two lines for each variable:

ARG FOO1=default value1
ARG FOO2=default value2
ENV FOO1=${FOO1} \
    FOO2=${FOO2}

Option B: inject your .env file and process it with an entrypoint in your container. This entrypoint could run your export command before kicking off the actual application. You'll also need to do this for each RUN command during the build where you need these variables. One shorthand I use for pulling in the file contents to environment variables is:

set -a && . .env && set +a
like image 28
BMitch Avatar answered Sep 16 '22 16:09

BMitch