Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't pass Environment variables from docker-compose.yml to Dockerfile #5600

Closed
MatthewBooth opened this issue Jan 23, 2018 · 17 comments
Closed

Comments

@MatthewBooth
Copy link

This is a huge oversight. I'm not sure when the use-case would be that you want some variables within your project that build cannot access.

I'm running Laravel, which of course uses .env files. docker-composer passes these along nicely and the system runs.

Until I want to build an image and then composer (php) cannot generate autoload files because it can't find the .env file and therefore can't build an image.

TL;DR
My project needs some .env values and the Dockerfile has no way of knowing about them.

@shin-
Copy link

shin- commented Jan 23, 2018

Compose is not a build tool, and has no vocation to become one. That being said, it should be simple enough to pass those variables you need as build args and declare them as ENV variables in your Dockerfile, like so:

docker-compose.yml

version: '2.3'
services:
  foobar:
    build:
      context: .
      args:
        FOO: ${FOO}
        BAR: ${BAR}

Dockerfile

FROM busybox:latest
ARG FOO
ARG BAR
ENV FOO $FOO
ENV BAR $BAR
...

@MatthewBooth
Copy link
Author

Yes, I was using a Dockerfile for the build and had "build" and "context" within the compose file.

I appear to be missing this bit

ENV FOO $FOO
ENV BAR $BAR

I'll give that a shot tomorrow. The docs are not really clear on this and I cannot imagine my case is an edge case.

@shin- shin- closed this as completed Feb 8, 2018
@landsman
Copy link

landsman commented Jan 2, 2019

This is annoying...

@alexei-developer
Copy link

Yes, I was using a Dockerfile for the build and had "build" and "context" within the compose file.

I appear to be missing this bit

ENV FOO $FOO
ENV BAR $BAR

I'll give that a shot tomorrow. The docs are not really clear on this and I cannot imagine my case is an edge case.

Unfortunately, not work without:

ARG FOO
ARG BAR

docker-compose --version
docker-compose version 1.24.0-rc1, build 0f3d4dd
docker --version
Docker version 18.03.1-ce, build 9ee9f40

@Resch-Said
Copy link

Some people like me are stupid and need clear names, so I will just make it a little more clear for myself and others.
docker-compose.yml

args:
         TOMCAT_ADMIN_PASSWORD: ${TOMCAT_PASSWORD}

Dockerfile

ARG TOMCAT_ADMIN_PASSWORD
ENV TOMCAT_ADMIN_PASSWORD $TOMCAT_ADMIN_PASSWORD

So, Compose passes the args to the Dockerfile
the ARG TOMCAT_ADMIN_PASSWORD contains TOMCAT_PASSWORD
and then I'm passing ARG TOMCAT_ADMIN_PASSWORD to ENV TOMCAT_ADMIN_PASSWORD

@rjindael
Copy link

This is not a practical solution whatsoever if you have a big environment file. This makes development tedious and unnecessarily annoying where if you can just read environment variables passed from the compose file. Hard-coding variables is never good, because if you would then want to add more environment variables you have to edit multiple files.

@dhvcc
Copy link

dhvcc commented Nov 16, 2020

I guess the only way not to hardcode variables is to source your .env before running docker-compose like

. .env && docker-compose up --build -d

Keep in mind that . and source are the same command, yet I had problems with source in Makefile, so I stick with .

Also consider using Makefile as it provides cleaner interface and will execute source in the separate shell which will not load variables in your shell.

@mehrdad-shokri
Copy link

as mentioned by @Downvote-Hunter, just pass your args under build directive, then define them in Dockerfile by ARG ARG_NAME from then on you can access it by $ARG_NAME

@rjindael
Copy link

Again, that re-introduces the problem of hard-coding your environment variable names.

One thing I've noticed is that simply adding env_file: "./.env" to your docker-compose files sends the environment variables to the image, and it can also be accessed by the image. They can't be accessed by the Dockerfile directly, but the image can. You can use an entrypoint script to sort of mitigate any lost functionality.

@Edmartt
Copy link

Edmartt commented Aug 12, 2021

hardcoded values works inside docker-compose, but not the same with env vars from .env. I f I exec a shell I can see my env vars exists but my app not working properly

@Booplicate
Copy link

It is a mystery why this process needs to be painful. First rule to learn: DRY, yet we have to write down every env var again?

Compose is not a build tool, and has no vocation to become one

This is why it can build, then?

@dhvcc
Copy link

dhvcc commented Jan 12, 2023

It is a mystery why this process needs to be painful. First rule to learn: DRY, yet we have to write down every env var again?

Compose is not a build tool, and has no vocation to become one

This is why it can build, then?

Having a way to pass build args, but not envs, while having a way of providing envs to the container. Also, a lot of repetition when you're providing through environment:

@Splines
Copy link

Splines commented Feb 21, 2024

. .env && docker-compose up --build -d

@dhvcc Did this work for you? For me, it doesn't. I have a docker.env file that looks like this:

# docker.env
FANCY=5

Then I do:

# A .sh script
set -a # enable allexport (env variable) shell option
. ./docker.env
echo $FANCY                                   # this works fine and prints "5"
docker compose build -d --pull                # the env variable doesn't get passed to docker compose build here
set +a # disable allexport (env variable) shell option

For testing purposes, I've included the following in the dockerfile:

# Dockerfile
RUN echo $FANCY

but it prints nothing (an empty line) when executed. While the workaround with ARGS might work, it's not an option for us to repeat every variable as this is just not scalable to a large docker.env files with 40+ env variables.

@dhvcc
Copy link

dhvcc commented Feb 21, 2024

Hey, @Splines I doubt I'd know what happened at that time, it was quite a while ago. My best suggestion would be to use build args, ARG in Dockerfile and build: ... args: in compose. You can use access some environment variables in compose configs, like it usually auto loads .env files. See screenshot

image

To avoid repeating some of the variables you send you might want to look at yaml anchors

Hope this helps

@ernstki
Copy link

ernstki commented Mar 27, 2024

Keep in mind that . and source are the same command, yet I had problems with source in Makefile, so I stick with .

@dhvcc, great tip thanks!

In Bash, source and . are the same command; in Z shell, they're nearly the same. However, GNU Make uses /bin/sh unless otherwise specified, which does not have a source command.

You can prove this to yourself with:

$ echo $SHELL
/bin/bash

$ make -f <(printf 'test:\n\techo $(SHELL)\n')
echo /bin/sh
/bin/sh

@dhvcc
Copy link

dhvcc commented Mar 28, 2024

Keep in mind that . and source are the same command, yet I had problems with source in Makefile, so I stick with .

@dhvcc, great tip thanks!

In Bash, source and . are the same command; in Z shell, they're nearly the same. However, GNU Make uses /bin/sh unless otherwise specified, which does not have a source command.

You can prove this to yourself with:

$ echo $SHELL
/bin/bash

$ make -f <(printf 'test:\n\techo $(SHELL)\n')
echo /bin/sh
/bin/sh

Yep, that's a more detailed answer. AFAIK make by default uses SH unless you tell it to switch.

Good to have more context, thanks!

@Splines
Copy link

Splines commented Mar 28, 2024

Hey, @Splines I doubt I'd know what happened at that time, it was quite a while ago. My best suggestion would be to use build args, [...]

@dhvcc, thanks for your suggestions! In the end, I filed in a StackOverflow question tailored specifically for my use case ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests