Development Environment

Docker Compose V2에서 .env를 못 찾는다면?

남희정 2025. 3. 2. 14:03

작년, 실무에서 docker를 접하고 docker-copmose.yml 파일을 처음 사용해 보았다. 당시엔 당연하듯 docker-compose up 명령어를 통해 컨테이너를 생성했다. 하지만 어느 날엔가부터 docker compose명령어가 바뀌었다는 경고 메시지를 보게 되었다.

확인해 보니 Docker 업데이트가 아닌 Docker compose 버전이 V1 ⇒ V2로 업데이트된 사항이었다. 뭐 그리 큰 이슈가 없을 거라 생각하고 새로운 프로젝트도 그렇게 잘 진행하였다. 문제는 추후에 일어나게 되는데…

 

작년에 마무리한 프로젝트를 고도화해보는 과정에서 docker 이미지 버전도 업데이트하는 과정이 있었다. 그런데 도통 서버가 열리지 않는 것이다. 이상하다 생각하고 디버깅해보니 .env파일을 아예 인식하지 못하는 것이었다. .env에 설정한 포트 번호를 들고 오지 못하고 있었음! 분명 같이 빌드되었고 동일한 디렉토리에 위치해 있는데도 말이다.

 

결론적으로 말하면 .env 파일의 경로를 명시해주지 않아서 그랬던 것이다. 근데 이전엔 왜 잘되었는가?

나는 그게 궁금했다.


Docker compose V1 ⇒ V2

docker-compose 명령어를 사용하던 V1에서는 .env 파일을 빌드시 포함하거나 기본적으로 프로젝트 디렉토리에서 자동으로 읽는 방식이 허용되었다. (암묵적 허용)

Docker compose 1.28 미만에서는 .env 파일을 현재 작업 디렉토리 또는 명령어 실행 디렉토리에서 자동으로 읽는다. docker compose 명령어를 사용하게 된 V2에서는 보안 및 일관성 강화를 위해 .env 파일을 명시적으로 설정하도록 변경되었다.

 

버전 .env 자동 로드 기본 로드 경로 명시적 설정 필요 여부
V1
`docker-compose up`
자동 로드 됨 현재 작업 디렉토리(PWD) 필요 없음
V2
`docker compose up`
불완전함 프로젝트 디렉토리
(docker-compose.yml이 있는 곳)
필요함!

 

Docker compose 1.28 이상부터는 .env 파일의 기본 경로가 프로젝트 디렉토리로 제한되었으며, 명시적으로 —env-file 옵션을 사용해야 환경 변수를 주입할 수 있다.

또한, Docker 자체적으로 빌드시 .env 파일을 포함하지 않도록 설계되어 있다. 컨테이너 내부에서 .env 파일을 복사하더라도 실행 시 환경 변수로 인식되지 않는다.

 

그런데 이상하지 않은가?

V1이 2023년 8월에 완전히 종료되었다, 나는 그때까지 어떻게 계속 사용할 수 있었을까?

✔️ Docker Desktop 이전 버전이 V1과 V2를 사용자가 선택적으로 사용할 수 있게 했었다. (권장되진 않았던 것)
✔️ 처음부터 docker-compose 명령어를 사용하게 되어 V1 호출
✔️ Docker Desktop 강제 업데이트로 환경이 바뀌어서 V2로 전환되어버림

 

V2에서 .env 파일을 명시하는 방법

환경 변수는 여러 가지 방법으로 설정할 수 있는데, 적용되는 우선순위가 다르다!

1️⃣ -e 명령어로 직접 전달된 환경 변수

docker compose up -e DATABASE_URL=mysql://new_user:new_password@new_db:3306/new_database

2️⃣ docker-compose.yml의 environment:

env_file: 보다 우선 적용된다.

즉, env_file: 에서 불러온 값이 있어도 덮어씌워지지 않는다.

services:
  web:
    environment:
      DATABASE_URL: "mysql://compose:override@db:3306/compose_db"

2️⃣ docker-compose.yml의 env_file:

.env 파일에서 불러온 값이 적용되지만, 위 environment:에서 같은 변수를 설정하면 덮어씌워지지 않는다.

services:
  web:
    image: my-webapp
    env_file:
      - .env
    environment:
      DATABASE_URL: "compose_value"

2️⃣ —env-file 옵션으로 지정한 환경 변수

env_file:보다 우선 적용되며, 여러 개 지정하면 마지막 파일이 앞의 값을 덮어씀.

docker compose --env-file .env.dev up

3️⃣ Shell에서 환경 변수 export VAR=value 사용

현재 쉘 환경에서 설정된 환경 변수!

export DATABASE_URL=mysql://user:password@db:3306/mydatabase
docker compose up

4️⃣ 프로젝트 디렉토리에 .env 파일 두기

docker-compose.yml이 있는 최상위 폴더에 있는 .env 파일은 명시하지 않아도 도커가 인식할 수 있다.

--env-file이나 env_file:에서 설정한 값이 있다면 덮어씌워진다.

/my-project
 ├── docker-compose.yml
 ├── .env
 ├── .env.production
 ├── Dockerfile
 ├── src/
 │   ├── app.py
 │   ├── config.py
 ├── db/
 │   ├── init.sql
 ├── logs/

5️⃣ 작업 디렉토리의 .env 파일

.env 파일이 현재 작업 디렉토리(PWD)에 있더라도, 프로젝트 디렉토리(docker-compose.yml이 위치한 곳) 내부에 없으면 자동으로 로드되지 않는다.

즉, docker compose up을 실행하는 디렉토리와 docker-compose.yml이 있는 디렉토리가 다르면 명시적으로 —env-file 옵션을 사용해야 한다.

🌟 현재 터미널 세션에서만 적용되며, 위 설정들이 있으면 덮어씌워진다.

 

Docker compose V1에서 V2로 전환되면서 .env 파일 처리 방식이 변경된 것은 보안과 일관성을 강화하기 위해서였다. 이젠 환경 변수를 명시적으로 관리해야 한다.

.env 파일은 항상 docker-compose.yml과 같은 디렉토리에 두거나 —env-file 옵션으로 명시하자!


공식 문서에서 릴리즈 노트를 항상 확인하고 새로운 버전에 적응하는 습관을 들이는 게 중요할 것 같다. 바뀐 원인에 대해서 알아보니 더욱 기억에 잘 남을 것 같다.

 

비슷한 문제를 겪으신 분들께 혹은 궁금한 분들께 글이 도움이 되기를 바란다!!!!!

 

Compose V2

Migrate to Compose V2

[Docker-Compose]Docker-Compose env parsing error로 인한 삽질기록

Set, use, and manage variables in a Compose file with interpolation

Docker에러 - .env파일 환경변수를 인식 못하는 문제

Docker Compose release notes

Docker Desktop 4.23: Updates to Docker Init, New Configuration Integrity Check, Quick Search Improvements, Performance Enhancements, and More

[Docker] docker container run - 환경 변수(.env)가 설정되지 않았습니다.

도커 컨테이너 환경변수 주입