What is the use of enviroument variable if the .env already existed

I am watching the example from [digitalocean] to introduce docker compose.(Containerizing a Node.js Application for Development With Docker Compose | DigitalOcean)
.env:

MONGO_USERNAME=sammy
MONGO_PASSWORD=your_password
MONGO_PORT=27017
MONGO_DB=sharkinfo

The script use the .env variable

...
const {
  MONGO_USERNAME,
  MONGO_PASSWORD,
  MONGO_HOSTNAME,
  MONGO_PORT,
  MONGO_DB
} = process.env;

const url = `mongodb://${MONGO_USERNAME}:${MONGO_PASSWORD}@${MONGO_HOSTNAME}:${MONGO_PORT}/${MONGO_DB}?authSource=admin`;

mongoose.connect(url, {useNewUrlParser: true});

If we can already use the env or use proccess.env.VARIABLE_NAME(or any other programming language own getting .env variable method) in the script, why do we still need to add environment variable inside docker-compose file, like this:

version: '3'

services:
  nodejs:
    build:
      context: .
      dockerfile: Dockerfile
    image: nodejs
    container_name: nodejs
    restart: unless-stopped
    env_file: .env
    environment:
      - MONGO_USERNAME=$MONGO_USERNAME
      - MONGO_PASSWORD=$MONGO_PASSWORD
      - MONGO_HOSTNAME=db
      - MONGO_PORT=$MONGO_PORT
      - MONGO_DB=$MONGO_DB 
    ports:
      - "80:8080"
    volumes:
      - .:/home/node/app
      - node_modules:/home/node/app/node_modules
    networks:
      - app-network
    command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js

What is the purpose of adding these environment variable?

Hi,

Its not needed, things defined in the yaml, environment block, will override the variable in .env

So if I’m happy with using environment variable directly reading the ā€˜.env’, I no need to add another environment section inside docker compose file? Is there any benefit of people using the environment section rather than reading the ā€˜.env’? I knew there are levels of environment variable, environment variables inside docket compose will replace the ā€˜.env’.

Personally i only use the environment block in docker-compose, in that way i have all configuration in 1 file :slight_smile:

The .env files are useful when you want to place your docker-compose.yml in git, but don’t want your secrets in there.

Other static env settings you can place inside docker-compose.yml, keeping it all in one place.

Nothing is really required, just an option for specific usecases. If your application can read a .env file, that’s fine, but that means, only your application will know about the variables and you need to read the file every time when you execute a command in the container using docker exec for example.

Also worth noting that variables in a .env file can be used to choose a docker network dynamically or set a port number which has nothing to do with the application in the container. It is also possible that the application expects a URL as an endpoint, but you want to create separate variables like EP_PROTOCOL, EP_HOSTNAME, EP_PATH and so on and you just concatenate it and optionally generate a new .env file for the application.

You could also have an appliation which was written without the support of reading a file for the variables but you still want to run it in a container.

So Docker and Docker Compose just makes things possible, but eventually it is up to you how you use the features.