DEV Community

Jonah Yeoh
Jonah Yeoh

Posted on • Edited on

docker-compose will always load .env

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.

Screenshot of the issue I am presenting in one glance

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
Enter fullscreen mode Exit fullscreen mode

Environment File

# .env
PORT=9879
Enter fullscreen mode Exit fullscreen mode
# public.env
PORT=7000
Enter fullscreen mode Exit fullscreen mode
# private.env
PORT=7001
Enter fullscreen mode Exit fullscreen mode

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'
Enter fullscreen mode Exit fullscreen mode

Top comments (3)

Collapse
 
tbroyer profile image
Thomas Broyer

I think you're mixing up variable interpolation in the compose file (that resolves from .env and environment variables) and the environment variables within the container (that you set within the compose file in environment: --that can itself use interpolation-- and env_file:)

So in your exemple, the PORT in the ports: is interpolated from .env (or environment variables), and within your containers each will have a PORT with the values from the env_files.

Those are separate, the .env variables will never leak into the containers unless you explicitly ask for it (using a - PORT in environment:, or using the .env as an env_file, or interpolation in any of those)

BTW, is there any reason you're still using Compose v1⁉️

Collapse
 
byte4bike profile image
Jonah Yeoh

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.

Collapse
 
thegrumpyopsdude profile image
JB

I am just putting this here for anyone who wants to nerd down on this "feature", docs.docker.com/compose/environmen...