Environment variables are not set in docker container using docker-compose.yml - docker

I have a .env file like below:
# DEV
SALES_DB_HOST=xxx
Then I have a docker-compose.yml file that looks like:
version: "3.1"
services:
web:
image: xxx
build: .
env_file: .env
However, the values for the environment variables when accessed in nodejs like process.env.SALES_DB_HOST it prints undefined.
Output of docker-compose config is:
services:
web:
build:
context: xxxxxxxx
environment:
SALES_DB_HOST: xxx
image: xxxxx
version: '3.1'
So, it looks like docker-compose.yml is formed correctly. But why is process.env not getting this value correctly?
EDIT:
I build the docker image with: docker build -t my_image .

Can you change command on you container configuration in yml file.
You should try to test your environment to understand - where is a problem. In docker or in your code.
Try something like this:
maxantonov : ~/passbolt .$ cat dc.yml
version: '3.4'
services:
db:
image: alpine:latest
container_name: db
hostname: db
env_file:
- env/mysql.env
command: ["printenv"]
maxantonov : ~/passbolt .$ docker-compose -f dc.yml up
Starting db ... done
Attaching to db
db | PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
db | HOSTNAME=db
db | MYSQL_ROOT_PASSWORD=test
db | MYSQL_DATABASE=passbolt
db | MYSQL_USER=passbolt
db | MYSQL_PASSWORD=P4ssb0lt
db | HOME=/root
db exited with code 0

It's not a docker problem.
Look to your code:
process.env.process.env.SALES_DB_HOST
It's typo. process.env.process.env
You shold use
process.env.SALES_DB_HOST

Related

How to use config.yml for docker compose env

As far as I know, to use the env variable in docker-compose we need to create a .env file
PORT=9000
And then use it like this in docker-compose.yml:
services:
go:
ports:
- ${PORT}:${PORT}
But what if I have a config file in .yml file like this:
http:
host: "0.0.0.0"
port: "1020"
jwt_secret: "secret"
How to access it on the docker-compose? This doesn't work:
version: "3.8"
services:
go:
env_file: config.yml
build:
context: .
dockerfile: Dockerfile
command: /fetch-app
ports:
- ${http.port}:${http.port}
environment:
NODE_ENV: development
It is generates error:
invalid interpolation format for services.go.ports.[].
You may need to escape any $ with another $.
${http.port}:${http.port}

Docker Extension fields, environment variables and env file not mapping through

I am trying to use environment variables and extension fields in docker-compose and it doesn't seem to be working.
I am starting the docker-compose with:
docker-compose --env-file ../.env up
The .env has:
DB_HOST=test_db
The docker-compose has:
version: '3.7'
x-common-variables: &common-variables
POSTGRES_HOST: ${DB_HOST}
services:
test_db:
image: postgres:10.5
application:
build:
context: ./app
environment:
<<: *common-variables
When my application starts, it is stuck waiting on the database.
when I go into the application docker instance and run:
printenv | grep POSTGRES_HOST
it returns nothing.
Am I missing something?

Hosting docker swarm from one docker-compose but with nodes var

I'm looking to be able to run swarm from same docker-compose file which uses env variables. Currently I only achieved that all nodes are replicating Leaders env. Is it possible to let each node start from its own local env var?
My docker-compose
version: '3.1'
networks:
base:
services:
test:
container_name: ${Name}
restart: always
image: ubuntu:latest
environment:
- Name=${Name}
command: sh -c "echo $Name && sleep 30"
networks:
- base
use env_file option
https://docs.docker.com/compose/environment-variables/
# .env, file
Name=<your_name>
# <your_name>.env, file
TEST_ENV=stackoverflow
# docker-compose.yaml, file
version: '3.1'
services:
test:
container_name: ${Name}
restart: always
image: ubuntu:latest
env_file:
- ${Name}.env
command: sh -c "set | grep TEST_ENV && sleep 30"
docker logs <your_name>
# TEST_ENV='stackoverflow'
You can set env_files with different names in different containers.
for example
# docker-compose.yaml, file
version: '3.1'
services:
test1:
container_name: test1
restart: always
image: ubuntu:latest
env_file:
- first.env
command: sh -c "set | grep TEST_FIRST_ENV && sleep 30"
test2:
container_name: test2
restart: always
image: ubuntu:latest
env_file:
- second.env
command: sh -c "set | grep TEST_SECOND_ENV && sleep 30"
Environment variables referenced in the docker-compose.yml file are not resolved on the leader even, they are resolved on whatever jump box you are deploying too the swarm from.
If you want to reference the env vars from the host system, from the command, or entrypoint, iirc you can escape the reference to "$$Name", but this will only make the env variable available to the entrypoint or command script which are evaluated on the host, not to values like the container_name.
Given your specific use case, perhaps service creation templates are what you are looking for: They let you inject per service instance values into hostname, mount and env.
version: '3.8'
services:
test:
env:
MY_HOSTNAME: "{{.Node.Hostname}}"
...
See Create Service Using Templates for the full list of supported values.

Docker unable to connect to postgres, but same command works fine when running from containers bash

When building the docker file, I have the command:
CMD ["/app/database/updateLocalDocker.sh"]
The shell script should connect to the postgres service using liquibase but fails with the error connection refused...
When i comment out the above CMD and run the same script directory from the container via docker exec -t -i f42c4bbcd95d /bin/bash, it works fine.
The URL i'm trying to connect to is: jdbc:postgresql://localhost:5432/service_x"
I have a feeling that it's related to either the service not being started or a network issue, when trying to execute the CMD during the docker-compose build stage.
Any guidance would be much appreicated.
docker-compose.yml:
version: "3.8"
services:
db:
image: local.db
build:
context: .
ports:
- 15432:5432
environment:
POSTGRES_PASSWORD: password
networks:
- a
networks:
a:
name: a
external: true
To access your database from your localhost you need to use the port 15432 instead of 5432.
services:
db:
image: local.db
build:
context: .
ports:
- 15432:5432 <--- Here
environment:
POSTGRES_PASSWORD: password
networks:
- a
The first port is your host and the second is the port used in your container.
You can also access it with the container name and the port used in it.
Docker port mapping documentation :
https://docs.docker.com/config/containers/container-networking/
Instead of putting the command in the Dockerfile, you can directly put the command in the docker-compose file and remove CMD ["/app/database/updateLocalDocker.sh"].
docker-compose.yml
version: "3.8"
services:
db:
image: local.db
build:
context: .
command: sh -c "<Enter-your-command>"
ports:
- 15432:5432
environment:
POSTGRES_PASSWORD: password
networks:
- a
networks:
a:
name: a
external: true
If you have one command execute
command: <command>
OR
If you have more than one command, it should be separated by &&.
Syntax:
sh -c "<command-1> && <command-2> && <command-3>"

Environment property not injected to volume mapping

I run docker-compose up in a parent directory and -f the docker-compose.yml in child folder. Does anyone know why this won't work? MY_VAR is evaluated to empty string
root-ui-e2e-ci:
environment:
MY_VAR: ./hello
env_file: ./.env
volumes:
- ${MY_VAR}:/app
I end up with this error
.: volume name is too short, names should be at least two alphanumeric
characters
The variable specified in environment & env_file not used for compose-file, it will directly pass to container.
For variable substitution in docker-compose.yaml, you could use next two solutions, and use docker-compose config to quick check the effect:
Solution 1:
Use the variable export in the same shell which run docker-compose:
docker-compose.yaml:
version: '3'
services:
root-ui-e2e-ci:
image: ubuntu
volumes:
- ${MY_VAR}:/app
Try Command:
$export MY_VAR=./hello
$docker-compose config
services:
root-ui-e2e-ci:
image: ubuntu
volumes:
- /home/shubuntu1/99/hello:/app:rw
version: '3.0'
Solution 2:
Use .env:
Set a .env file in the same folder of docker-compose.yaml:
.env:
MY_VAR=./hello
docker-compose.yaml:
version: '3'
services:
root-ui-e2e-ci:
image: ubuntu
volumes:
- ${MY_VAR}:/app
Try Command:
$unset MY_VAR
$docker-compose config
services:
root-ui-e2e-ci:
image: ubuntu
volumes:
- /home/shubuntu1/99/hello:/app:rw
version: '3.0'
depends on you comment that hello is a stringyou need to rewrite you docker-compose like this:
environment:
MY_VAR: hello
volumes:
- ../${MY_VAR}:/app

Resources