How to share global env vars in Docker? - docker

I have two environments development and production, I use two files with respective vars of each environment: .env.development and .env.production. I'm use, too, docker-compose to load this variables.
.env.development
COMPOSE_PROJECT_NAME=luna
RAILS_ENV=development
DATABASE_URL=postgresql://user:pass#lunapostgres:5432/luna?encoding=utf8&pool=5&timeout=5000
REDIS_CACHE_URL=redis://:pass#redis:6379/0/cache
ACTIVE_JOB_QUEUE_PREFIX=luna:jobs
ACTIVE_JOB_URL=redis://:pass#redis:6379/0
AUTH_BASE_URL=auth.com
SOLAR_BASE_URL=http://test.url
# SOLAR_BASE_URL=http://api/api/v1/
BUNDLE_PATH=/box
BIND_ON=0.0.0.0:3000
SENTRY_DSN=http://xxxxxxx
PAGER=more
ACCESS_TOKEN=xxx
VERIFY_TOKEN=xxx
DIALOGFLOW_CLIENT_ACCESS_TOKEN=xxx
DIALOGFLOW_DEV_ACCESS_TOKEN=xxx
RAILS_MAX_THREADS=1
WEB_CONCURRENCY=1
REQUEST_TIMEOUT=5
DOMAIN=localhost:3000
BASE_URL=localhost:300
SECRET_TOKEN=xxx
LOG_LEVEL=debug
SOLAR_MENTOS_DEBUG=true
.env.production
COMPOSE_PROJECT_NAME=luna
RAILS_ENV=production
RACK_ENV=production
DATABASE_URL=postgresql://user:pass#lunapostgres:5432/luna?encoding=utf8&pool=5&timeout=5000
REDIS_CACHE_URL=redis://:pass#redis:6379/0/cache
ACTIVE_JOB_QUEUE_PREFIX=luna:jobs
ACTIVE_JOB_URL=redis://:pass#redis:6379/0
AUTH_BASE_URL=auth.com
SOLAR_BASE_URL=http://test.url
# SOLAR_BASE_URL=http://api/api/v1/
BUNDLE_PATH=/box
BIND_ON=0.0.0.0:3000
SENTRY_DSN=http://xxxxxxx
ACCESS_TOKEN=yyy
APP_SECRET=yyy
VERIFY_TOKEN=yyy
DIALOGFLOW_CLIENT_ACCESS_TOKEN=yyy
DIALOGFLOW_DEV_ACCESS_TOKEN=yyy
RAILS_SERVE_STATIC_FILES=true
RAILS_LOG_TO_STDOUT=true
WEB_CONCURRENCY=5
REQUEST_TIMEOUT=5
RAILS_MAX_THREADS=5
DOMAIN=production.com
BASE_URL=https://production.com
SECRET_TOKEN=yyy
LOG_LEVEL=info
# ----------------------------------------
DEVISE_SECRET_KEY='yyy'
GOOGLE_ANALYTICS_UA='yyy'
docker-compose.override.yml
version: '2'
services:
app:
env_file:
- '.env.development'
docker-compose.production.yml
version: '2'
services:
app:
env_file:
- '.env.production'
I would like share equivalents environment variables between my containers, and keep different variables in your respective environment.

Use extendable environment files.
version: '2'
services:
app:
env_file:
- 'base.env'
- 'production.env'
From the Docs
When you set the same environment variable in multiple files, here’s
the priority used by Compose to choose which value to use:
Compose file,
Environment file
Dockerfile
Variable is not defined
The docs are not clear on the use of multiple files so I ran a test. The last environment files overrides previously set variables. If you want to override default values, do so in the last file or in the compose file.
base.env
TEST_VARIABLE=base
production.env
TEST_VARIABLE=production
docker-compose.yml
version: '2.1'
services:
test:
image: alpine
env_file:
- 'base.env'
- 'production.env'
Running docker-compose run --rm test env gives us TEST_VARIABLE=production. Thus, the second file overrides the first.

Related

forward exact environment variables from host to container

I am finding my self repeating like this:
services:
noice-service:
environment:
- EUREKA_SERVICE_URL=${EUREKA_SERVICE_URL}
- ZIPKIN_BASE_URL=${ZIPKIN_BASE_URL}
- CONFIG_SERVER_URL=${CONFIG_SERVER_URL}
I have defined these env vars in .env file and some in another scripts and I just want to pass their exact value in container. Is there any way quicker way of achieving this without any custom shell script as entrypoint ?
You can pass the variables directly:
# .env
DOTENV=foo
# docker-compose.yml
version: "3.7"
services:
busybox:
image: busybox
command: ["env"]
environment:
- DOTENV
- ANOTHER
And run ANOTHER=bar docker-compose up.

Docker Compose .env File Not Read

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.

Dockerfile - use environment variable from env file

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.

How to copy file contents to a service during docker-compose up?

I have 2 files:
.env
docker-compose.yml
docker-compose.yml looks like this:
version: '3'
services:
database:
image: mysql:5.7
myapp:
image: me/some-image
depends_on:
- database
env_file: .env
myapp is a web service app that needs a .env file or optionally it can access the environment variables if no .env file is present.
As of now, the myapp is accessing the environment variables because I don't want the .env file to be included in the image build for security reasons. What I did is to pass a env_file: .env to the myapp service in the docker-compose.yml file so it will rely to the environment variables of the service instead of a .env file.
Now, I really want to add a .env file to the myapp service when running docker-compose up. Take note that the myapp web service will throw an error if it didnt find a .env file and the option is to look for a .env file instead of getting from the environment variables of the container.
Is there a way to create a .env file when running docker-compose up and copy the contents of the .env file on the host? Thank you in advance.
You can use bind mount to mount file into the container
change the target location to the one your app requires
version: '3'
services:
database:
image: mysql:5.7
myapp:
image: me/some-image
depends_on:
- database
env_file: .env
volumes:
- type: bind
source: ./.env
target: /envfile/.env
readonly: true
You shouldn't be storing the environment variables in the container.
According to TwelveFactor-
The twelve-factor app stores config in environment variables (often shortened to env vars or env). Env vars are easy to change between deploys without changing any code; unlike config files, there is little chance of them being checked into the code repo accidentally; and unlike custom config files, or other config mechanisms such as Java System Properties, they are a language- and OS-agnostic standard.
You are correctly passing the env file. The env file needs to be in the format of <key>=<value>.
For example -
DB_USERNAME=user
DB_PASSWORD=password
DB_SCHEMA=db
DB_PORT=3306
DB_HOST=db
REDIS_HOST=redis
REDIS_PORT=6379
REDIS_DB=0
In your application, you don't need to care about if the .env file is present, you simply read the environment variable.
Example in python -
import os
db_username = os.environ['DB_USERNAME']
You should not be coupling your environment variable to a file. It should read from the runtime environment.

env_file is ignored in docker-compose and cause "The ... variable is not set" warning

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}"]

Resources