project
└───app
│ │ ...
│ │ Dockerfile
│ │
└───prod.env
└───docker-compose.yml
My docker-compose looks like this:
services:
app:
build:
context: .\app
args:
ARG1: val1
ARG2: val2
env_file:
- prod.env
But I've tried this too:
services:
app:
build:
context: .\app
args:
ARG1: ${ARG1}
ARG2: ${ARG2}
env_file:
- prod.env
My prod.env file looks like this:
ARG1 = 'val1'
ARG2 = 'val2'
But I've tried this too:
ARG1=val1
ARG2=val2
I would like for either the values of args or the values from the prod.env file to be passed to the dockerfile.
This is what I've tried to get this:
ARG ARG1
ARG ARG2
RUN echo ${ARG1}
RUN echo ${ARG2}
ENV ARG1 ${ARG1}
ENV ARG2 ${ARG2}
RUN echo ${ARG1}
RUN echo ${ARG2}
ENV ARG1 "new val2"
ENV ARG2 "new val2"
RUN echo ${ARG1}
RUN echo ${ARG2}
It always end with blank values.
Any help would be greatly appreciated. I feel like no answers from other posts have worked when I tried them.
To build I use docker-compose --env-file prod.env build
Thanks
Update
Sergio Santiago asked if I could run docker-compose config
and show the results.
Here are the final files I used for this test.
docker-compose:
services:
app:
build:
context: .\app
args:
ARG1: val1
ARG2: val2
env_file:
- prod.env
prod.env:
ARG3 = 'val3'
ARG4 = 'val4'
And here is the output of docker-compose --env-file prod.env config
networks:
demo-net: {}
services:
app:
build:
args:
ARG1: val1
ARG2: val2
context: C:\project\app
environment:
ENV: prod.env
ARG3: val3
ARG4: val4
I would like to add that clearly from here getting the variable from the .env file to the docker-compose file is not the issue. I also have a flask app running on the container and through os.environ it is able to use the variables in the .env file. I just can't figure out how to give the same access to the Dockerfile.
Update 2 More specific information in relation to ErikMD's answer
prod.env
DOMAIN = 'actualdomain.com'
ENV = 'prod.env'
ENV_NUM = 1
ARG1 = 'value1'
dev.env
DOMAIN = 'localhost'
ENV = 'dev.env'
ENV_NUM = 0
ARG1 = 'value1'
Notice that the value for ARG1 is the same but the other values are different.
docker-compose.yml
version: "3.7"
services:
home:
image: home-${ENV_NUM}
build:
context: .\home
args:
ARG1: "${ARG1}"
networks:
- demo-net
env_file:
- ${ENV}
labels:
- traefik.enable=true
- traefik.http.routers.home.rule=Host(`${DOMAIN}`)
- traefik.http.routers.home.entrypoints=web
volumes:
- g:\:c:\sharedrive
...
...
reverse-proxy:
restart: always
image: traefik:v2.6.1-windowsservercore-1809
command:
- --api.insecure=true
- --providers.docker=true
- --entrypoints.web.address=:80
- --providers.docker.endpoint=npipe:////./pipe/docker_engine
ports:
- 80:80
- 443:443
- 8080:8080
networks:
- demo-net
volumes:
- source: \\.\pipe\docker_engine\
target: \\.\pipe\docker_engine\
type: npipe
networks:
demo-net:
The dots represent other apps that would be formatted the same as home.
dockerfile
FROM python:3.10.3
ARG ARG1="default"
ENV ARG1="${ARG1}"
WORKDIR /app
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
RUN echo "This is argument 1 -> ${ARG1}"
output of docker-compose --env-file prod.env config
networks:
demo-net: {}
services:
home:
build:
args:
ARG1: value1
context: C:\MIS-Web-App\home
environment:
DOMAIN: actualdomain.com
ENV: prod.env
ENV_NUM: '1'
ARG1: value1
image: home-1
labels:
traefik.enable: "true"
traefik.http.routers.home.entrypoints: web
traefik.http.routers.home.rule: Host(`mis.canaras.net`)
networks:
demo-net: null
volumes:
- g:\:c:\sharedrive:rw
...
...
Then I run either docker-compose --env-file prod.env build
or docker-compose --env-file dev.env build
output of build
Step 9/23 : RUN echo "This is argument 1 -> ${ARG1}"
---> Running in 5142850de365
This
is
argument
1
->
Removing intermediate container 5142850de365
Now I call pass the env_file in the command as well as in the actual file because there are variables in there that my docker-compose file needs and variables that my flask app needs. And there is definitely overlap.
Getting the values from the prod.env or dev.env files to docker-compose is not the issue. Neither is getting it to my flask app. The issue is getting those values to the dockerfile.
My solution was annoying which is why it took me so long to figure it out. My dockerfile was using powershell on a windows server, so I had to do this for every argument:
ARG ARG1
RUN echo $env:ARG1
This seems pretty niche especially since using windows containers on a windows server is not my first choice, so check out @ErikMD 's answer if your having issues with env files and whatnot.