Update 6th-Jun-2024
After deeper dive into the docs and practice. I realize I mixed up .env and file.env. Please refer to -> https://dev.to/tbroyer/comment/2fhdp, that's the right way of understanding this concept.
As shown in the screenshot, I didn't specify .env under any env_file directives. But it choose to use the PORT value defined under .env instead of public.env or private.env.
Versions
- docker: 24.0.0
- docker-compose: 1.29.2
Possible Solution
- Remove '.env'
- Never use variable names that are already defined in .env
My Take
I think more people should be aware of this default behavior and I am interested to know how others deal with this issue.
Code Snippet
Checkout the code snippet below if the screenshot is not clear.
# docker-compose.yml
version: "3.8"
services:
  private:
    container_name: private_server
    build: ./backend
    command: uvicorn main:app --host=0.0.0.0 --port=7000
    ports:
      # - 127.0.0.1:${PUBLIC_PORT}:7000
      - 127.0.0.1:${PORT:-7001}:7000
    environment:
      - WORKSPACE=secret
    env_file:
      - private.env
  public:
    container_name: public_server
    build: ./backend
    command: uvicorn main:app --host=0.0.0.0 --port=7000
    ports:
      # - 127.0.0.1:${PRIVATE_PORT}:7000
      - 127.0.0.1:${PORT:-7000}:7000
    environment:
      - WORKSPACE=client
    env_file:
      - public.env
Environment File
# .env
PORT=9879
# public.env
PORT=7000
# private.env
PORT=7001
docker-compose config
services:
  private:
    build:
      context: /home/server/projects/server/backend
    command: uvicorn main:app --host=0.0.0.0 --port=7000
    container_name: private_server
    environment:
      PORT: '7001'
      WORKSPACE: secret
    ports:
    - 127.0.0.1:9879:7000/tcp
  public:
    build:
      context: /home/server/projects/server/backend
    command: uvicorn main:app --host=0.0.0.0 --port=7000
    container_name: public_server
    environment:
      PORT: '7000'
      WORKSPACE: client
    ports:
    - 127.0.0.1:9879:7000/tcp
version: '3.8'
 


 
    
Top comments (3)
I think you're mixing up variable interpolation in the compose file (that resolves from
.envand environment variables) and the environment variables within the container (that you set within the compose file inenvironment:--that can itself use interpolation-- andenv_file:)So in your exemple, the
PORTin theports:is interpolated from.env(or environment variables), and within your containers each will have aPORTwith the values from theenv_files.Those are separate, the
.envvariables will never leak into the containers unless you explicitly ask for it (using a- PORTinenvironment:, or using the.envas anenv_file, or interpolation in any of those)BTW, is there any reason you're still using Compose v1⁉️
Yes, thanks for pointing out. You are absolutely right and I came back here to confess my confusion.
Compose v1? Hmm, I was not aware of v2. So far I am doing well with v1 but I will move over to v2 since v1 will no longer receive updates.
I am just putting this here for anyone who wants to nerd down on this "feature", docs.docker.com/compose/environmen...