Quick Flow
services:
web:
image: "webapp:${TAG:-latest}"
ports:
- "${WEB_PORT:-8080}:80"
environment:
- DEBUG=${DEBUG:-false}cat .env
# TAG=v1.5
# WEB_PORT=3000
docker compose config
docker compose --env-file ./config/.env.dev config${VAR}는 Compose 파일을 렌더링할 때의 값이고, environment와 env_file은 컨테이너 프로세스가 받는 값입니다. 필수 배포값은 ${VAR:?message}로 막고, 실제 치환 결과는 docker compose config로 확인합니다.
변수 해석과 치환
interpolation은 Compose 파일을 실행 전 렌더링하는 단계다
Compose의 ${VAR} 치환은 컨테이너 내부 환경 변수를 직접 설정하는 기능이 아니라 Compose 파일 값을 실행 전에 바꾸는 기능입니다. 예를 들어 image: "webapp:${TAG}"에서 ${TAG}는 Compose가 YAML을 해석하는 시점에 실제 문자열로 바뀝니다. 치환 결과가 잘못되면 컨테이너가 뜨기 전에 이미지 이름, 포트, 볼륨 경로부터 잘못 만들어질 수 있습니다.
services:
db:
image: "postgres:${POSTGRES_VERSION:-16}"변수가 없고 기본값도 없으면 Compose는 경고를 내고 빈 문자열로 대체할 수 있습니다. postgres:처럼 유효하지 않은 이미지 참조가 만들어지는 문제가 여기서 발생합니다. 배포에 필요한 값은 ${VAR:?error message} 형태로 필수값을 강제하는 편이 안전합니다.
.env와 env_file은 역할이 다르다
프로젝트 루트의 .env 또는 --env-file로 전달한 파일은 Compose 파일의 interpolation에 쓰입니다. 반면 service의 env_file:은 컨테이너 안으로 환경 변수를 주입하는 설정입니다. 이름이 비슷하지만 적용 시점과 목적이 다릅니다.
services:
app:
image: "my-app:${IMAGE_TAG}"
env_file:
- app.env
environment:
- APP_ENV=${APP_ENV:-development}여기서 IMAGE_TAG와 APP_ENV는 Compose 파일 치환에 쓰이고, app.env는 컨테이너 프로세스가 실행될 때의 환경 변수로 들어갑니다. app.env에 값을 적었다고 해서 반드시 Compose 파일의 ${IMAGE_TAG} 치환에 쓰이는 것은 아닙니다.
누락과 노출 방지
Compose interpolation과 컨테이너 환경 변수 주입을 같은 것으로 보면 설정이 누락됩니다. .env는 기본적으로 Compose 파일 치환에 쓰이고,
컨테이너 내부 값은 environment나 env_file에서 별도로 확인해야 합니다.
참고 링크
2 sources