I have a docker compose setup where I want to use environment variables from env file in my dockerfile. I want to use these variables during the build time since I use this version number in concatenating the string in order to form a download URL.
Here I wrote part of the files I'm using just to keep the focus on the point of my question.
.env
MY_APP_VER=v1.2.3
docker-compose.yml
version: "2"
services:
my-app:
build: .
container_name: my_app
environment:
- my_app_version=$MY_APP_VER
Dockerfile
FROM scratch
ENV my_app_ver=$my_app_version
RUN echo $my_app_ver
I have checked various sources but without any success. I'm not sure if this is even possible or am I using the wrong syntax (should I use quotes or no e.g. "$my_app_ver" or curly brackets ${my_app_ver}).
For version 3.8 you can do it in the following way
version: '3.8'
services:
my-app:
build: .
ports:
- ${CONTAINER_PORT}:${PORT} # for example
env_file: .env
container_name: my-app-${NODE_ENV} # for example
environment:
MYSQL_DATABASE: ${DB_NAME} # for example
my_app_version: ${MY_APP_VER} # for your case
Find more information in documentation
Also, you can find more information about the usage of env variables in Dockerfile and docker-compose here
There is an option called env-file in docker-compose, that you can leverage: https://docs.docker.com/compose/environment-variables/#the-env_file-configuration-option
version: "3"
services:
my-app:
build: .
container_name: my_app
env_file:
- .env.dev
Be aware, that the .env file is loaded by default, if it is present in the current context. So you only have to use env_file, if it is named differently or is in a different folder.
Related
I have a .env file I'm trying to use in a Docker Compose file to pass to the container to be used in the entrypoint script defined in the Dockerfile.
I have the following effective Dockerfile (spread out over two files, one override). The .env.dev file is in the same directory as the docker compose files. The environment variable value is not getting passed to the container. When I add "=${RUN_MIGRATIONS_ON_START}", the variable value is blank. If I leave that off, then the variables aren't even set in the container.
Docker compose files:
Main docker compose file:
version: '3.4'
services:
web:
build
context: .
Override docker compose file:
version: '3.4'
services:
web:
environment:
- RUN_MIGRATIONS_ON_START=${RUN_MIGRATIONS_ON_START}
- WS_SCHEME=${WS_SCHEME}
env_file:
- .env.dev
Solution
docker-compose.override.yml
version: '3.4'
services:
web:
env_file:
- .env.dev
.env.dev
RUN_MIGRATIONS_ON_START=FOO
WS_SCHEME=BAR
Why
environment:
- X=${Y} # Y is a variable from the local shell environment, not from .env
Described in detail in documentation
Your configuration options can contain environment variables. Compose
uses the variable values from the shell environment in which
docker-compose is run.
TL/DR: Can I use .env file variables in docker-compose's environment directives?
I have a Dockerfile which uses the ARG variable to copy files based on an environment variable.
In my docker-compose I want to run two versions of this container with different configuration.
Is there a way where I can set different filepaths in a single .env file and have it build twice, like the example below?
Or is there a smarter way to accomplish this?
/
/.env
/docker-compose.yml
/app
/app/Dockerfile
/version1/data
/version2/data
/.env
VERSION_1_PATH=./version1/data
VERSION_2_PATH=./version2/data
/app/Dockerfile
FROM node:latest
ARG APP_PATH # pull this environment variable
COPY $APP_PATH /var/app/ # use it to copy source to the same generic destination
/docker-compose.yml
version: "3"
services:
version1:
build: ./app
container_name: version1
env_file:
- '.env'
environment:
APP_PATH: ${VERSION_1_PATH}
version2:
build: ./app
container_name: version2
env_file:
- '.env'
environment:
APP_PATH: ${VERSION_2_PATH}
You can add args in compose file when to define build, something like follows:
version: '3'
services:
version1:
build:
context: ./app
args:
- APP_PATH=${VERSION_1_PATH}
version2:
build:
context: ./app
args:
- APP_PATH=${VERSION_2_PATH}
And no need to define .env in env_file if just want it be used in build as .env could default be used in docker-compose.yml. And, environment also not for build, it's for running container.
One example, FYI.
I have docker-compose.yml like below:
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
And I have two files : dev.env and stage.env where SERVICE_VERSION and PROFILE are described.
Is there any way to specify concrete file when running docker-compose up
By default docker-compose takes .env file from current dir.
Is there a way to override it or another workaround ?
As mentioned in the answer in the comments there is no way to do that as it is directly coded into the source code to use .env.
However, there a couple ways to get similar behaviour.
The first way works natively with docker-compose, which would be to use docker-compose override files.
So in your case you could have your base docker-compose.yml file like this:
version: '2'
services:
micro-service:
image: some/micro-service:1.0.0
ports:
- "8085:8085"
Then you can define a docker-compose-dev.yml file:
version: '2'
services:
micro-service:
image: some/micro-service:dev
env_file:
- ../all-variables/dev/micro_service.env
Then you can run the following command
$ docker-compose up -f docker-compose.yml -f docker-compose-dev.yml up
If you do this the values in docker-compose-dev.yml will override those in docker-compose.yml. So instead of using image some/micro-service:1.0.0 it will use the image defined in docker-compose-dev.yml.
The second way would be to use docker-app. Which is a new experimental utility from the Docker team.
Basically you will create a dockerapp file that would look like this:
version: 0.0.1
name: app
---
version: '2'
services:
micro-service:
image: some/micro-service:${SERVICE_VERSION}
env_file:
- ../all-variables/${PROFILE}/micro_service.env
ports:
- "8085:8085"
---
SERVICE_VERSION: latest
PROFILE: default
Then if you convert your .env files to .yml render the compose file with the correct variables using docker-app.
docker-app render -f dev.yml | docker-compose -f - up
Hopefully this is helpful, I am going through a similar issue when working with multiple environments with docker-compose.
I'm working on a group project involving Docker that has a .env file, which looks like this:
DATABASE_URL=xxx
DJANGO_SETTINGS_MODULE=xxx
SECRET_KEY=xxx
Couldn't this just be declared inside the Dockerfile? If so, what is the advantage of making a .env file?
Not sure if I'm going in the right direction with this, but this Docker Docs page says (emphasis my own):
Your configuration options can contain environment variables. Compose
uses the variable values from the shell environment in which
docker-compose is run. For example, suppose the shell contains
POSTGRES_VERSION=9.3 and you supply this configuration:
db:
`image: "postgres:${POSTGRES_VERSION}"`
When you run docker-compose up with this configuration, Compose looks for the POSTGRES_VERSION environment variable in the shell and substitutes its value in. For this example, Compose resolves the image to postgres:9.3 before running the configuration.
If an environment variable is not set, Compose substitutes with an empty string. In the example above, if POSTGRES_VERSION is not set, the value for the image option is postgres:.
You can set default values for environment variables using a .env file, which Compose automatically looks for. Values set in the shell environment override those set in the .env file.
If we're using a .env file, then wouldn't I see some ${...} syntax in our docker-compose.yml file? I don't see anything like that, though.
Here's our docker-compose.yml file:
version: '3'
services:
server:
build:
context: ./server
dockerfile: Dockerfile
env_file: .env.dev
command: python3 manage.py runserver 0.0.0.0:8000
volumes:
- ./server:/app
ports:
- "8500:8000"
depends_on:
- db
stdin_open: true
tty: true
db:
image: postgres
client:
build:
context: ./client
dockerfile: Dockerfile
command: bash -c "npm install; npm run start"
volumes:
- ./client:/app
- /app/node_modules
ports:
- "3000:3000"
depends_on:
- server
Idea there is probably to have a place to keep secrets separated from docker-compose.yml, which you then can keep in VCS and/or share.
I simply want to use a environment variable loaded from file in my docker-compose file. But after running the container, I only got
WARNING: The TESTVAR variable is not set. Defaulting to a blank string.
Only found this topic, but I'm using a later version of docker like there (docker-compose: 1.14.0, docker: 17.05.0-ce). And I changed the encoding to ISO 8859-1, since I found a github issue where strange behavior with encodings was detected. Both doesn't work.
My docker-compose file
version: '2'
services:
mysql:
container_name: test_${TESTVAR}
build: mysql
mem_limit: 1G
env_file:
- credentials.env
credentials.env contains only TESTVAR=test123. To start, I run docker-compose up mysql and I also tried to specify the environment variables directly in the compose file like this:
environment:
- TESTVAR=1234
Not working, too.
If you want to use variables in the docker-compose.yml you can do it with .env file, docker docs
$ cat .env
TAG=v1.5
TESTVAR=123
$ cat docker-compose.yml
version: '3'
services:
web:
image: "webapp:${TAG}"
environment: ["TESTVAR=${TESTVAR}"]