Profile picture

[Docker-Compose] 서비스 컨테이너에 주입되는 환경 변수 다루기

JaehyoJJAng2022년 03월 20일

개요

도커 컴포즈(Docker Compose)에서 각 서비스 컨테이너들의 외부 환경변수를 주입하는 방법들을 기록해보려고 한다.


환경변수 삽입 방법

도커 컴포즈에서 환경변수를 주입하는 방법은 크게 네 가지로 구분된다.

  • 1. Compose 파일에 입력하기
  • 2. 쉘 환경변수 등록하기
  • 3. 환경변수 파일 생성하기
  • 4. Dockerfile에 환경변수(ENV) 등록하기

1. Compose 파일에 입력

도커 컴포즈에서 환경변수를 주입하는 직관적인 방법은 바로 Compose 파일에 환경변수 값을 직접 입력하는 것이다.


간단한 예시로 mysql:latest 이미지를 컨테이너 구동시킨다고 해보자.

해당 이미지를 구동시킬 때에 MYSQL_ROOT_PASSWORD 라는 변수가 필수로 입력되어야 하는데,

이럴 때 배포용 compose.yaml 파일에서 아래와 같이

변수명: 값 또는 - 변수명=값 형태로 넣어줄 수 있다.


아래 Compose 파일은 최신 mysql 이미지에 MYSQL_ROOT_PASSWORD 값을 root로 지정하는 파일이다.

services:
  db:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=root

2. 쉘 환경변수 등록

쉘 환경변수에서 변수를 선언한 뒤 이를 Compose 파일에 반영하는 방법이다.

테스트를 위해 현재 활성화된 터미널에서 임시로 변수를 하나 생성해보자.

MYSQL_ROOT_PASSWORD=root

명령을 실행한 뒤에 Compose 파일은 다음과 같이 작성한다.

services:
  db:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}

MYSQL_ROOT_PASSWORD 속성의 값이 ${MYSQL_ROOT_PASSWORD}로 변경되었다.


YAML 파일 외부로부터 환경변수를 주입할 때, 그 값이 주입될 부분은 ${변수명} 또는 $변수명의 형태로 명시해야된다.


3. 환경변수 파일 생성

배포용 Compose 파일에 환경변수를 일일이 적거나, 매번 쉘에서 변수를 선언한 뒤 주입하는 방법은 꽤 비효율적이다.

필요한 환경변수 항목들만 추려내어 별도의 파일(.env)로 구성해둔다면 환경변수 관리를 보다 효율적으로 할 수 있을 것이다.


이번 챕터에서는 시나리오에 따라 아래의 세 가지 방법으로 나누어보려고 한다.

  • 1. 하나의 환경변수 파일(.env) 생성하기
  • 2. 여러 개의 환경변수 파일 생성하기
  • 3. 각 서비스마다 다른 환경변수 파일 주입하기

3-1. 하나의 환경변수 파일 생성하기

도커 컴포즈에서 환경변수들을 별도의 파일로 구성할 때 사용할 수 있는 방법은

Compose 파일이 위치한 경로에 .env 파일을 따로 생성하는 것이다.

.env 파일은 평문 텍스트 포맷으로, 아래의 문법을 따라 작성해야 한다.

  • 각 줄마다 변수명=값의 형태로 입력함.
  • 주석 처리는 # 문자를 사용
  • 비어있는 줄은 무시됨
  • 따옴표 처리('', "")는 불필요함. 입력된 따옴표는 위치에 따라 변수명이나 의 일부분으로 간주됨

이렇게 작성된 .env 파일은 별다른 설정 없이도 Compose 파일에 바로 반영된다.

아래 컴포즈 파일 예시를 살펴보자.

services:
  db:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}

위에서 ${MYSQL_ROOT_PASSWORD}로 명시된 값을 .env 파일에 아래와 같이 작성해주자.

MYSQL_ROOT_PASSWORD=root

이 상태에서 Compose 파일을 convert 해보면 다음과 같이 출력된다.

...
environment:
  MYSQL_ROOT_PASSWORD: root

.env 파일을 이용하는 방식이 간편하기는 하지만,

도커 컴포즈에서 docker-compose up 명령을 수행할 때에만 활용이 가능한 것에 유의하자.


3-2. 여러 개의 환경변수 파일 생성하기

경우에 따라 여러 개의 환경변수 파일로 나누는 일이 필요할 수 있다.

예를 들어 개발환경과 운영환경에 따라 주입해야 할 환경변수 값들이 각기 다른 경우라면 말이다.

이런 경우에는 각각의 환경에 맞는 별도의 env_file을 구성한 뒤,

배포할 때 --env-file <파일경로> 플래그로 불러올 파일을 직접 지정할 수 있다.


아래와 같이 .env.dev.env.prod 파일을 각각 생성해보자.

$ echo "MYSQL_ROOT_PASSWORD=dev" > .env.dev
$ echo "MYSQL_ROOT_PASSWORD=prod" > .env.prod

이 상태에서 docker compose의 --env-file 플래그를 이용하면 해당 파일에 환경변수가 주입된다.

$ docker compose --env-file .env.dev config

image


3-3. 각 서비스마다 다른 환경변수 파일 주입하기

때로는 각 서비스 컨테이너들에 필요한 환경변수 파일을 별도로 관리해야 하는 경우가 생긴다.

이런 경우에는 Compose 파일에 명시된 각 서비스에서 env_file 항목에 환경변수 파일 경로를 명시해 환경변수를 주입해줄 수 있다.


만약 이 항목을 따로 명시하지 않는다면, 기본적으로는 env_file: .env이 적용된 상태라고 보면 된다.

services:
  db:
    image: mysql:latest
    environment:
      - MYSQL_ROOT_PASSWORD=${MYSQL_ROOT_PASSWORD}
    env_file:
      - .env.dev
      - .env.prod

이 방법을 사용할 때는 유의해야 할 사항이 있다.

위와 같이 여러 개의 환경변수 파일을 주입한 경우,

두 파일에 동일한 변수명으로 서로 다른 값이 들어있다면 삽입된 순서를 기준으로 나중에 삽입된 파일의 변수값이 적용된다.


4. Dockerifile에 환경변수 등록하기

환경변수를 YAML이나 별도의 외부 파일로 생성하는 것이 꺼려진다면

Dockerfile에 ARG 또는 ENV 키워드를 사용하여 환경변수를 직접 삽입한 뒤 나만의 이미지로 빌드하여 사용하면 된다.

FROM mysql:latest
ENV MYSQL_ROOT_PASSWORD root

Loading script...