도커 컴포즈(Docker Compose)를 사용할 때 각 서비스 컨테이너에 필요한 환경변수들을 어떻게 하면 효율적으로 다룰 수 있을까? 이번 글에서는 도커 컴포즈(Docker Compose)에서 환경변수를 다루는 방법들을 알아보고, 각 방법이 실제 배포 상황에서 어떤 우선순위를 갖는지, 그리고 주의해야 할 점은 무엇인지를 살펴보자.

환경변수 삽입 및 관리 방법

Docker Compose에서 환경변수를 다루는 방법은 크게 네 가지로 구분된다. 여기서는 Docker Hub에서 제공되는 MySQL 공식 이미지를 예시로 하여 살펴보기로 하자.

  1. Compose 파일에 직접 입력하기
  2. 쉘 환경변수로 등록하기
  3. 환경변수 파일로 구성하기
  4. Dockerfile에 환경변수를 직접 삽입하기

1. Compose 파일에 직접 입력하기

Docker Compose에서 환경변수를 주입하는 가장 직관적인 방법은 Compose 파일에 직접 입력하는 것이다. MySQL 이미지로 컨테이너를 구동시킬 때엔 MySQL의 관리자(root) 계정 비밀번호를 설정할 MYSQL_ROOT_PASSWORD 변수값이 반드시 필요한데, 이럴 땐 배포용 Compose 파일에서 services.<서비스명>.environment 부분에 해당 내용을 변수명: 값 또는 - 변수명=값 형태로 넣어주면 된다.

아래 예시는 MySQL 8 이미지에 MYSQL_ROOT_PASSWORD 환경변수값을 password로 지정하여 둔 Compose 파일 내용이다.

version: '3.9'
services:
  mysql:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: password

2. 쉘 환경변수로 등록하기

쉘 환경에서 변수를 선언한 뒤 이를 Compose 파일에 반영되도록 하는 방법도 있다. 예를 들어 아래와 같은 명령을 커맨드라인으로 입력해 둔 상황을 가정해보자.

$ export MYSQL_ROOT_PASSWORD=password

이때 Compose 파일은 아래와 같이 작성한다. services.mysql.environment 부분의 MYSQL_ROOT_PASSWORD 항목값이 ${MYSQL_ROOT_PASSWORD}으로 대체된 것에 주목하자. YAML 파일 외부로부터 환경변수를 주입받을 때, 그 값이 주입될 부분은 ${변수명} 또는 $변수명의 형태로 명시하도록 한다. 여기서는 외부 환경변수값이라는 점을 보다 잘 드러내기 위해 ${변수명} 문법을 따랐다.

version: '3.9'
services:
  mysql:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}

이 상태에서 배포용 Compose 파일을 convert 시켜보면, 아래와 같이 쉘에서 등록한 변수값이 변수명에 대응하여 삽입된 것을 볼 수 있다.

$ docker compose convert
# ...
# environment:
#   MYSQL_ROOT_PASSWORD: password

3. 환경변수 파일로 구성하기

배포용 Compose 파일에 환경변수를 하나하나 다 적어넣거나, 매번 쉘에서 변수로 직접 선언시키는 방법은 다소 비효율적이다. 필요한 환경변수 항목들만 골라내어 별도의 파일로 구성해 둔다면 환경변수 관리를 보다 효율적으로 할 수 있을 것이다. 여기서는 실제 활용 시나리오에 따라 아래의 세 가지 방법으로 나누어 소개한다.

  1. 하나의 .env 파일로 구성하기
  2. 여러 개의 파일로 구성하기
  3. 각 서비스마다 다른 환경변수 파일 반영하기

3-1. 하나의 .env 파일로 구성하기

Docker Compose에서 환경변수 정보들을 떼어 별도의 파일로 구성할 때 가장 간편한 방법은 Compose 파일이 위치한 동일 경로에 .env 파일을 따로 구성하는 것이다. 이 .env 파일은 평문 텍스트 포맷으로, 아래의 문법을 따라 작성해야 한다.

이렇게 작성된 .env 파일은 별다른 설정 없이도 Compose 파일에 바로 반영된다. 아래 Compose 파일을 예시로 살펴보자.

version: '3.9'
services:
  mysql:
    image: mysql:8
    restart: unless-stopped
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}