Docker Compose에서 다른 이름의 환경 변수 파일 지정하는 방법

Docker Compose에서 다른 이름의 환경 변수 파일 지정하는 방법

·

3 min read

Intro.

Docker Compose는 여러 컨테이너를 정의하고 실행할 수 있는 도구로, 사내 프로젝트에서 로컬 통합 테스트 환경을 구축하기 위해 이를 사용하던 중 발생한 문제와 그 해결 방법에 대해 다루고자 한다.


Problem.

docker compose up -d --build

보통 위와 같은 명령어로 docker-compose.yml 이라고 명명된 파일을 실행시킬 것이다. 이 때, 환경 변수 파일을 로드하기 위해서 이 파일의 내용을 아래와 같이 env_file 을 필드로 사용해 지정할 수 있을 것이다.

services: 
    something:
        env_file:
            .env.validator

이렇게 하면 서비스로 지정된 컨테이너가 정상적으로 실행될 수 있을까? 실행해 보니 답은 '아니오' 였다.

에러 상황은 아니지만 Docker Compose는 아래와 같이 내게 경고 상황이란 것을 알 수 있는 로그를 출력해 주었다.

WARN[0000] The "NETWORK_ID" variable is not set. Defaulting to a blank string. 
WARN[0000] The "ADDRESS_VALIDATOR_1" variable is not set. Defaulting to a blank string. 
WARN[0000] The "NETWORK_ID" variable is not set. Defaulting to a blank string. 
WARN[0000] The "ADDRESS_VALIDATOR_2" variable is not set. Defaulting to a blank string. 
WARN[0000] The "NETWORK_ID" variable is not set. Defaulting to a blank string. 
WARN[0000] The "ADDRESS_VALIDATOR_3" variable is not set. Defaulting to a blank string. 
WARN[0000] The "NETWORK_ID" variable is not set. Defaulting to a blank string. 
WARN[0000] The "ADDRESS_VALIDATOR_0" variable is not set. Defaulting to a blank string.

하지만 이는 단순한 경고 메시지라고 할 수 없었다. 환경 변수들이 세팅되지 않으면 컨테이너가 정상적으로 실행될 리 없기 때문이다.


Solution.

이 문제를 해결하기 위해 몇 가지 시도를 해보았다.

첫 번째로 시도한 것은 .env.validator 파일 내에 환경 변수를 단순히 docker-compose.yml에 직접 넣는 것이었다. (딱히 무식한 방법이라고 생각하진 않고, 필요에 의한 좋은 방법이라고 생각한다.)

services:
    something:
        environment:
            NETWORKD_ID=1337
            ADDRESS_VALIDATOR_1=ab84848973jjdifid2352
            (생략..)

위와 같이 설정하고 명령을 실행했으나 실패했다. 여전히 같은 경고 메시지가 출력되었다. 여기서 알게 된 것은 이 문제가 단순히 환경 변수 파일을 읽지 못해서 발생한 경고가 아니라는 것이다.


그래서 공식 문서를 살펴 보니 약간의 힌트를 얻을 수 있었다.

🤔 environment.envenv_file에 정의된 변수들을 덮어 쓴다.

이 말은 Docker Compose가 우선 순위에 따라 환경 변수를 처리한다는 의미로 해석될 수 있다.

Docker Compose는 설정 파일 내에서는 기본적으로 environment 필드에 높은 우선 순위를 부여하고, 그 다음은 env_file, .env 파일 순으로 낮아진다.


Docker Compose의 환경 변수가 우선 순위에 따라 처리된다는 것은 .env 같은 환경 변수 파일이 우선 순위가 높은 것에 의해 변경되지 않게 하면 문제를 해결할 수 있단 것을 의미한다.

따라서 아래와 같이 일단 .env 파일을 정의해 사용하기로 했다.

NETWORK_ID=1337
ADDRESS_VALIDATOR_0=0xabcd
ADDRESS_VALIDATOR_1=0xabcd
ADDRESS_VALIDATOR_2=0xabcd
ADDRESS_VALIDATOR_3=0xabcd
GAS_PRICE=0

🤔 환경을 분리해야 하는 상황이 아니라면 간단하게 .env만 사용해도 될 것 같다.

이러면 .env.validator를 사용할 때와 어떤 차이가 있을까? .env는 Docker Compose가 자동으로 로드하도록 하며, .env.validator 와 같이 지정된 파일보다 우선 순위가 높기 때문에 이를 덮어 씌운다는 것이다.

따라서 docker-compose.yml과 같은 디렉토리 위치에 .env를 생성해 사용하면 Docker Compose가 이를 인식해 환경 변수를 컨테이너로 주입해 준다는 것이다.


End.

services:
    something:
        env_file:             # 이 필드와
            - .env.validator  # 이 값을 여기서 제거해 .env 파일이 로드되도록 하자

이제 위 docker-compose.yml 파일에서 환경 변수를 제대로 읽어오게 하려면 env_file 필드와 값을 제거하면 된다. 그러면 동일한 디렉토리 위치에 있는 .env 파일이 로드되어 컨테이너가 비로소 정상적으로 실행된다.

정리해 보자면, 아래와 같다

  • Docker Compose는 환경 변수를 우선 순위에 따라 처리한다.

  • .env 환경 변수 파일을 사용하고 있다면, 가장 높은 우선 순위에 해당하는 방법이 덮어 버리지 않게 주의한다.


References.