Docker3 min read

docker inspect로 컨테이너의 실제 환경변수와 마운트가 이미지 설정과 다른 이유 진단하기

2026년 10월 16일3 min read작성자 Flature

docker inspect로 컨테이너 생성 시 적용된 런타임 설정(실제 ENV, 마운트)과 이미지에 선언된 기본 설정(ENV, VOLUME)을 각각 확인하는 방법과 명령 예시를 제공합니다. 이미지 설정과 컨테이너 실행 설정을 구분해 빠르게 원인 파악하는 절차를 제시합니다.

docker inspect로 컨테이너의 실제 환경변수와 마운트가 이미지 설정과 다른 이유 진단하기

요약하면, 컨테이너에서 실제 적용된 환경변수와 마운트는 컨테이너 대상의 docker inspect 결과(최종 설정)에서 보고, 이미지에 선언된 기본값은 docker image inspect 결과에서 비교하면 됩니다. 아래 절차와 명령 예시로 각각 무엇을 확인해야 할지 알려드립니다.

언제/왜 이 방법이 필요한가

컨테이너가 기대한 환경변수나 파일/볼륨을 갖지 못할 때 원인은 주로 다음 네 가지입니다.

  • 이미지의 Dockerfile에 선언된 기본 ENV 또는 VOLUME과, 컨테이너 실행 시 전달한 값이 다른 경우
  • docker run 또는 docker-compose에서 전달한 환경변수/볼륨 설정이 의도와 다르게 적용된 경우
  • 엔트리포인트 스크립트가 컨테이너 시작 시 환경변수를 변경하거나 파일을 재배치하는 경우
  • 바인드 마운트가 이미지 내부 파일을 덮어써서 보이지 않게 되는 경우

이 문제들을 분리하려면 "이미지에 정의된 기본값"과 "실제 컨테이너에 적용된 값"을 각각 확인해야 합니다.

어떻게 검사하는가 — 명령과 의미

기본 원칙: 이미지의 선언은 docker image inspect로 확인하고, 컨테이너의 실제 런타임 설정은 docker inspect(또는 docker container inspect)로 확인합니다.

1) 이미지에 선언된 값 확인

docker image inspect my-image:tag --format '{{json .Config.Env}}'
docker image inspect my-image:tag --format '{{json .Config.Volumes}}'

의미:

  • .Config.Env — Dockerfile의 ENV로 이미지에 기록된 기본 환경변수 목록(키=값 형식)
  • .Config.Volumes — Dockerfile에서 선언한 VOLUME 경로 목록(메타데이터, 실제 마운트는 아님)

2) 컨테이너에 실제 적용된 값 확인

docker inspect my-container --format '{{range .Config.Env}}{{println .}}{{end}}'
# 마운트(볼륨/바인드) 확인
docker inspect my-container --format '{{json .Mounts}}'
# 호스트 바인드 문자열도 보기
docker inspect my-container --format '{{json .HostConfig.Binds}}'
# 엔트리포인트·CMD 확인
docker inspect my-container --format '{{json .Config.Entrypoint}}'
docker inspect my-container --format '{{json .Config.Cmd}}'

의미:

  • .Config.Env — 컨테이너가 시작될 때 Docker가 전달한(또는 이미지에서 병합된) 최종 환경변수 목록입니다. 이미지의 ENV와 실행 시 --env/--env-file/compose 설정이 병합/오버라이드된 결과를 보여줍니다.
  • .Mounts — 컨테이너에 실제로 연결된 마운트의 배열(타입, 소스, 대상, 읽기/쓰기 등). 런타임에 적용된 bind/volume 정보를 여기서 확인합니다.
  • .HostConfig.Binds — 전통적인 bind 마운트(-v /host:/container) 문자열 형태(있다면 함께 확인하면 원인 파악에 유용).
  • .Config.Entrypoint/.Config.Cmd — 컨테이너가 어떤 프로세스로 시작되는지, 엔트리포인트 스크립트가 있는지 확인합니다. 엔트리포인트가 환경을 조작하면 inspect로는 그 변경 전/후를 구분할 수 없으니 추가 검사 필요합니다.

구체적 예제 — 이미지 기본값과 컨테이너 런타임 설정 비교

상황: 이미지에 ENV APP_ENV=prod와 VOLUME /data를 선언했는데, 컨테이너에서 APP_ENV가 dev로 보이고 /data가 이미지 내용과 다른 경우.

# 1) 이미지에 선언된 기본값 확인
docker image inspect my-image:latest --format 'IMAGE ENV: {{json .Config.Env}}'
docker image inspect my-image:latest --format 'IMAGE VOLUMES: {{json .Config.Volumes}}'

# 출력 예(설명):
# IMAGE ENV: ["APP_ENV=prod" "OTHER=foo"]
# IMAGE VOLUMES: {"/data":{}}

# 2) 컨테이너에 실제 적용된 값 확인
docker inspect my-container --format 'CONTAINER ENV:\n{{range .Config.Env}}{{println .}}{{end}}'
docker inspect my-container --format 'MOUNTS: {{json .Mounts}}'
docker inspect my-container --format 'BINDS: {{json .HostConfig.Binds}}'

# 출력 예(설명):
# CONTAINER ENV:
# APP_ENV=dev
# OTHER=foo
# MOUNTS: [{"Type":"volume","Name":"my-data-vol","Source":"/var/lib/docker/volumes/my-data-vol/_data","Destination":"/data",...}]
# BINDS: null

해석:

  • 이미지에는 APP_ENV=prod로 정의되어 있지만, 컨테이너에는 APP_ENV=dev가 있어 런타임에 오버라이드된 상태입니다(보통 docker run -e 또는 compose의 environment로 설정됨).
  • 이미지의 VOLUME 선언은 메타데이터일 뿐입니다. 컨테이너의 Mounts에 Type:volume과 Source에 볼륨 이름이 보이면 런타임에 볼륨이 연결된 것입니다. 만약 Mounts가 비어있다면 선언된 VOLUME만 있고 실제 볼륨이 연결되지 않은 상태입니다.

한계와 자주 하는 실수

  • docker inspect는 컨테이너 시작 시 Docker가 전달한 설정(메타데이터)을 보여줍니다. 컨테이너 내부에서 런타임 중에 프로세스가 환경변수를 변경한 내용(예: 엔트리포인트 스크립트가 export로 수정한 값 등)은 inspect에 반영되지 않습니다. 그런 경우에는 docker exec 컨테이너 env 또는 docker exec 컨테이너 cat /proc/1/environ로 프로세스 환경을 직접 확인하세요.
  • 이미지의 VOLUME은 단지 선언된 경로입니다. VOLUME 선언 때문에 컨테이너에서 보이는 파일이 없어지거나 바뀌는 것은 해당 경로에 런타임 마운트가 적용되었기 때문인지 확인해야 합니다(바인드나 named volume이 덮어씀).
  • docker-compose를 쓸 때는 docker-compose config 명령으로 합쳐진 서비스 구성을 먼저 확인하면, compose 레벨에서 어떤 값이 주입되는지 파악하기 쉽습니다. 하지만 최종 확인은 컨테이너 inspect가 정확합니다.
  • 출력의 JSON을 사람이 읽기 어렵다면 docker inspect ... --format 와 jq를 조합하여 필드만 뽑아 읽기 좋게 만들면 도움이 됩니다. (--format 템플릿은 Go template 문법을 사용하므로 문법에 유의)

실무적 요약: 문제를 보면 먼저 '이미지(default)'와 '컨테이너(runtime)'를 각각 inspect로 확인하세요. 이미지에서 기대한 기본값이 있는지 확인한 뒤, 컨테이너 inspect로 실제 적용된 .Config.Env와 .Mounts(.HostConfig.Binds도 함께) 값을 비교하면 대부분의 차이 원인을 바로 찾을 수 있습니다.