지식
Docker
Docker Compose environment: 환경 변수 완전 정복
compose.yaml에서 environment, env_file, 변수 치환 패턴, 우선순위 체계, .env 파일 관리 보안 원칙을 실전 예제로 정리합니다.
지난 글에서 Compose 네트워크 격리를 살펴봤다. 이번에는 컨테이너에 환경 변수를 전달하는 방법과 우선순위 체계를 정리한다.
환경 변수 선언 방법
environment 키
services:
api:
environment:
# 맵 형식
NODE_ENV: production
PORT: "3000"
# 리스트 형식 (동일 효과)
- NODE_ENV=production
- PORT=3000
# 값 없이 선언 → 호스트 셸 변수 전달
- DEBUG
값 없이 변수 이름만 선언하면 호스트 셸의 동일 이름 변수가 컨테이너에 전달된다. DEBUG 변수가 셸에 설정되어 있으면 그 값이 컨테이너로 전달되고, 없으면 변수 자체가 설정되지 않는다.
env_file 키
services:
api:
env_file:
- .env # 공통 변수
- .env.local # 로컬 오버라이드 (git 제외)
- .env.${NODE_ENV} # 환경별 파일
.env 파일 형식:
NODE_ENV=production
DB_HOST=db
DB_PASSWORD=supersecret
REDIS_URL=redis://cache:6379
#으로 시작하는 줄은 주석이다. export 접두사가 있어도 인식한다.
우선순위 체계
높은 우선순위가 낮은 값을 덮어쓴다.
- 셸 환경 변수 (가장 높음)
--env-file옵션으로 지정한 파일- 프로젝트 루트
.env파일 (자동 로드) compose.yaml의environment키- Dockerfile
ENV명령어 (가장 낮음)
# 셸 변수로 .env 값을 덮어씀
DB_PASSWORD=override docker compose up -d
# 다른 env 파일 사용
docker compose --env-file .env.staging up -d
변수 치환 패턴
services:
api:
image: myapp:${TAG:-latest} # TAG 없으면 latest
image: myapp:${TAG:?TAG required} # TAG 없으면 오류 발생
| 패턴 | 동작 |
|---|---|
${VAR} | VAR 값, 없으면 빈 문자열 |
${VAR:-default} | VAR 없거나 비어있으면 default |
${VAR:?error} | VAR 없으면 error 메시지와 함께 종료 |
${VAR:+value} | VAR 있을 때만 value 사용 |
선언 패턴
환경별 분리 패턴
# 환경별 .env 파일 구조
.env # 공통 (git 제외)
.env.example # 예시 (git 포함)
.env.development # 개발 환경
.env.staging # 스테이징 환경
# 개발 환경 실행
docker compose --env-file .env.development up -d
# 스테이징 환경 실행
docker compose --env-file .env.staging up -d
docker compose config로 값 확인
변수가 올바르게 치환되었는지 확인하는 명령이다.
# 변수 치환 후 최종 compose.yaml 출력
docker compose config
# 특정 서비스의 환경 변수 확인
docker compose run --rm api env | sort
secrets 키: 민감 데이터 분리
패스워드·API 키는 environment가 아닌 secrets로 관리한다.
services:
db:
image: postgres:16
secrets:
- db_password
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
db_password:
file: ./secrets/db_password.txt # 파일에서 로드
secrets는 컨테이너 파일시스템의 /run/secrets/ 아래에 마운트된다. 환경 변수로 직접 노출하지 않아 docker inspect나 로그에 값이 노출되지 않는다.
보안 체크리스트
# .gitignore 확인
echo ".env" >> .gitignore
echo ".env.local" >> .gitignore
echo "secrets/" >> .gitignore
# .env.example 커밋 (값 없이 키만)
# .env.example 내용:
# DB_PASSWORD=
# API_KEY=
# JWT_SECRET=
.env에는 실제 값을 넣되 git에 커밋하지 않는다..env.example은 키 이름만 적어 팀원이 어떤 변수가 필요한지 알 수 있게 커밋한다.compose.yaml에 패스워드를 하드코딩하지 않는다.- CI/CD에서는 환경 변수를 시크릿 관리자(AWS Secrets Manager, GitHub Secrets 등)에서 주입한다.
정리
environment는 인라인 선언,env_file은 파일에서 로드한다. 함께 쓸 수 있다.- 우선순위: 셸 변수 >
--env-file>.env>compose.yaml environment> Dockerfile ENV. ${VAR:-default}변수 치환으로 기본값을 설정하고,${VAR:?error}로 필수 변수를 강제한다.- 민감 데이터는
secrets키로 분리해 파일시스템 마운트 방식으로 전달한다. .env는 반드시.gitignore에 추가하고,.env.example만 커밋한다.
지난 글: Docker Compose networks
읽어주셔서 감사합니다. 😊