When building container, environment variables are not applied.
docker-compose.yml:
img:
build: img
environment:
VAR: Hello
/img/Dockerfile:
FROM python:2.7
RUN python -c 'import os; print os.environ["VAR"]'
Expected to have "Hello" written, received KeyError: VAR
- missing environment variable.
If you get into container with docker-compose run --rm img bash
(after removing that last failing line) and do python -c 'import os; print os.environ["VAR"]'
you will get expected result.
docker-compose==1.3.3
docker-version
:
Client version: 1.7.1
Client API version: 1.19
Go version (client): go1.4.2
Git commit (client): 786b29d
OS/Arch (client): linux/amd64
Server version: 1.7.1
Server API version: 1.19
Go version (server): go1.4.2
Git commit (server): 786b29d
OS/Arch (server): linux/amd64
This is expected. The environment:
key in the docker-compose.yml
is the same as specifying it to the docker run
command to start the container. build
and dockerfile
are the old keys used for building the image.
This is maybe not obvious from the documentation and could be improved.
Docker doesn't support injecting environment into the build environment (it must be part of the Dockerfile), but I believe there are some open proposals to add support for something like that.
Just a reference for anyone who find this issue, here is docker discussion regarding build-time variables: https://github.com/docker/docker/issues/14634 and corresponding PR: https://github.com/docker/docker/pull/15182
This bit us hard, really needs better docs.
The documentation is really confusing, e.g. talks about env-file, which is used for docker-compose.yml
and is used for docker run
. Given that docker-compose is an orchestration tool for building and running containers, it is easy to assume that environment would apply to build time, using --env <key>=<value>
or something like this.
Bit me as well.
Just to leave a note that environment variables can be set as build args in the compose file. Like others on this thread, I was initially expecting env_file or environment to be used by both build and run.
Verified with compose file v2, docker-compose v1.7, docker-engine v1.11 .
Updated docs in https://github.com/docker/compose/pull/3747
Note that if you need to include env vars from a file, you can do the following. This will require (in the docker-compose build section) args set from these variables, which you can then refer to in your docker file. This means that while you can't directly reuse your env_file, you can do so with a little extra work.
env $(cat vars.env | xargs) docker-compose up --build <whatever>
the answer to this stack overflow question helped https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile
it is possible to map the .env environment variables to ARGS to be used by the Dockerfile during build.
docker-compose.yml
version: "2"
services:
lumen:
build:
context: .
dockerfile: ./Dockerfile
args:
- PORT=${PORT}
volumes:
...
Dockerfile
FROM php:7.0-apache
ARG PORT
ENV PORT "$PORT"
EXPOSE ${PORT}
...
@williamli Can you add a link to the Stack Overflow question?
Sorry guys - I am not sure I understand how to resolve this - and I would like to use a pre-built image.
version: '3'
services:
web1:
image: softwaremaker/web-w
environment:
I used to think that the api image (softwaremaker/api-w) will be able to resolve into the environment variables I had set up above but it doesnt work.
@PatrLind
added stackoverflow link to my original comment.
https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile
The issue is still relevant for env files other than default .env
file.
F.e. Next code will not work:
nginx:
env_file:
- .env
- .env.local
environment:
- SERVER_NAME=${SERVER_NAME}
build:
context: ./nginx
dockerfile: Dockerfile
args:
server_name: ${SERVER_NAME}
while SERVER_NAME is defined in second env file (.env.local
).
I see no options to pass env vars from .env.local to build context ((
@remort
I can confirm this as well, if I have variables being used during build they are only passed to the build process if the the file is called .env
if they are named .env.docker
they don't get picked up. Even when the env_file
is specified to use the .env.docker
file.
My solution for this during my build copying the other named env file and renaming it to .env
COPY .env.docker ${APP_HOME}/.env
WORKDIR $APP_HOME
After this it appeared to pickup the environment variables when the container runs
Operating System: macOS (10.14.6)
Docker Desktop Version: 2.1.0.5 (40693)
Engine Version: 19.03.5
Compose: 1.24.1
Hi guys,
A quick question for all of you, will this be a better way to build an image for dev? It works fine so far. However, is this the recommended practice? All images are based on buster.
```
FROM redis:buster as redis
RUN mkdir /env && env > /env/.env_redis
RUN cat /etc/passwd
RUN ls -lah /home
FROM ruby:slim-buster AS ruby
RUN mkdir /env && env > /env/.env_ruby
FROM node:lts-buster-slim AS node
RUN mkdir /env && env > /env/.env_node
FROM nginx:latest AS nginx
RUN mkdir /env && env > /env/.env_nginx
FROM php:fpm-buster AS php
RUN mkdir /env && env > /env/.env_php
COPY --from=redis / /
COPY --from=ruby / /
COPY --from=node / /
COPY --from=nginx / /
ADD conf/include-site.conf /etc/nginx/conf.d/include-site.conf
ADD conf/supervisord.conf /etc/supervisord.conf
RUN su root
EXPOSE 80 443
WORKDIR "/var/www/html"
ENTRYPOINT ["/bin/bash", "/start.sh"]
Problem is still exists.
env_file key in build section will be more clear than passing env vars through args to container build.
Like this:
#NOT_WORKING
build:
context: ./client
dockerfile: Dockerfile
env_file: ${CURRENT_ENV_FILE}
Because i am using shell scripts to build and up docker compose.
For production i need different env_file than for dev/local.
And there are many docker-compose.env.yml files with many args so it's not convinient as i think
I think there needs to be some elegant way around this. I really like the docker syntax and using arguments instead of environment variables doesn't make sense to me. I would not want want someone to manually change my docker-compose files. Changing values in the .env files appears consistent to me.
Most helpful comment
the answer to this stack overflow question helped https://stackoverflow.com/questions/19537645/get-environment-variable-value-in-dockerfile
it is possible to map the .env environment variables to ARGS to be used by the Dockerfile during build.
docker-compose.yml
Dockerfile