docker load·save·run으로 보는 이미지 로드와 실행

이미지를 파일로 옮길 때는 레이어·히스토리·태그를 완벽하게 보존하는 docker save와 docker load를 사용합니다. 컨테이너의 파일시스템 스냅샷이 필요한 특수한 경우에만 docker export·import를 사용해야 합니다. 레지스트리 없이 로드된 이미지는 Docker 시리즈 1편에서 살펴본 것과 동일한 실행 경로, 즉 docker run을 통해 컨테이너로 전환됩니다. 이 글은 Docker 시리즈의 두 번째로, 이미지 전송에서 실행까지 가장 자주 혼동되는 명령어들의 차이와 올바른 사용법을 공식 CLI 문서를 기준으로 정리합니다.

이 글은 Docker 공식 CLI 문서를 기준으로 한 일반 안내이며, 엔진 버전과 이미지 스토어 설정(classic storage driver vs containerd image store)에 따라 저장 경로·출력은 달라질 수 있습니다.

docker save와 docker load는 무엇을 보존하나?

한 줄 답: docker save는 이미지의 레이어, 히스토리, 태그를 포함한 메타데이터 전체를 tar 아카이브로 저장하며, docker load는 이를 그대로 로컬 이미지 스토어에 복원합니다.

docker save는 하나 이상의 이미지를 단일 tar 아카이브로 패키징합니다. 공식 CLI 문서에 따르면, 이 tar 파일에는 다음 정보가 모두 포함됩니다.

  • 레이어(Layers): Dockerfile의 각 명령어(예: RUN, COPY)에 대응하는 파일시스템 레이어가 그대로 보존됩니다.
  • 히스토리(History): 각 레이어를 생성한 명령어 정보가 메타데이터로 포함되어 docker history로 조회 가능한 상태가 유지됩니다.
  • 태그 및 리포지토리 정보: 저장 시점의 이미지 이름과 태그가 repositories 파일 및 manifest.json에 기록됩니다.

docker loaddocker save로 만든 tar(또는 gzip 압축 tar)를 읽어 로컬 이미지 스토어에 복원합니다. 이미 동일한 레이어가 로컬에 존재하면 중복 저장 없이 해당 레이어를 재사용할 수 있습니다. 로드가 완료되면 docker images에서 원래의 리포지토리 이름과 태그로 이미지를 확인할 수 있습니다.

pull/push와의 관계를 정리하면, 레지스트리에 접근 가능한 환경에서는 docker pull/docker push가 기본입니다. 레지스트리를 사용할 수 없는 파일 전달 경로에서는 docker save→ tar 전달 → docker load 경로가 표준적인 방법입니다.

docker export·import는 load·save와 어떻게 다른가?

한 줄 답: docker export/import는 컨테이너의 파일시스템 스냅샷을 평탄화(flatten)한 단일 레이어 이미지를 만들며, 레이어·히스토리·볼륨 데이터를 보존하지 않습니다.

아래 비교 표는 두 명령어 쌍의 핵심 차이를 정리합니다.

항목docker save / docker loaddocker export / docker import
대상이미지(Image)컨테이너(실행 중 또는 중지된 컨테이너)
레이어 보존✅ 모든 레이어 보존❌ 단일 레이어로 평탄화
히스토리 보존✅ Dockerfile 히스토리 유지❌ 히스토리 소실
태그 보존✅ 리포지토리·태그 정보 포함❌ 기본 태그 없음 (import 시 별도 지정 필요)
볼륨 데이터해당 없음 (이미지 단위)❌ 마운트된 볼륨 내용 미포함 (공식 동작)
빌드 캐시 이점✅ 레이어 캐시 재사용 가능❌ 단일 레이어이므로 캐시 이점 감소
주요 용도이미지 이동·백업·오프라인 전달rootfs 스냅샷·평탄화 이미지 생성

몇 가지 중요한 사항을 추가로 정리합니다.

  • docker export는 컨테이너를 대상으로 합니다. 이미지가 아닌 실행 중이거나 중지된 컨테이너의 파일시스템을 tar로 내보냅니다. 공식 문서에 따르면 마운트된 볼륨 내의 데이터는 내보내기에 포함되지 않습니다.
  • docker import는 단일 레이어 이미지를 생성합니다. export로 만든 tar(또는 임의의 rootfs tar)를 가져오면 Dockerfile 히스토리와 멀티 레이어 구조가 사라집니다. 이후 이 이미지를 베이스로 다시 빌드하더라도 레이어 캐시의 이점이 크게 줄어듭니다.

실무 규칙(Rule of Thumb): “이미지 이동 = save/load”, “rootfs 스냅샷·평탄화 = export/import”. 두 명령어 쌍의 혼용은 재현성과 빌드 캐시를 깨뜨리므로 권장하지 않습니다.

load한 이미지를 docker run으로 실행하면 무엇이 생기나?

한 줄 답: docker load로 복원된 이미지는 docker pull로 내려받은 이미지와 동일하게 취급되며, docker run은 읽기 전용 이미지 레이어 위에 컨테이너 전용 쓰기 레이어를 더해 컨테이너를 생성하고 시작합니다.

docker load가 완료되면 해당 이미지는 로컬 이미지 스토어에 등록됩니다. 이후 docker run을 호출하면 다음 과정이 진행됩니다.

  1. 이미지 확인: Docker는 로컬 이미지 스토어에서 지정한 이미지 이름과 태그를 조회합니다. docker load로 복원된 이미지는 이 단계에서 정상적으로 발견됩니다.
  2. 컨테이너 생성: containerd와 runc가 읽기 전용 이미지 레이어를 기반으로 컨테이너를 위한 쓰기 레이어를 얹은 파일시스템 뷰를 구성합니다. 이 레이어 구조(overlay2의 lowerdir·upperdir 등)의 상세한 내용은 시리즈 3편에서 다룹니다.
  3. 프로세스 기동: runc가 namespaces·cgroups를 적용하고 지정된 명령어를 실행합니다. 이 격리와 자원 제한 구조는 1편에서 자세히 다룬 내용과 동일합니다.

즉, docker load는 “이미지 준비” 단계이고, docker run은 “namespaces·cgroups로 프로세스를 기동”하는 단계입니다. 이미지가 어떤 경로(pull, load, build)로 준비되었는지는 docker run의 실행 경로에 영향을 주지 않습니다.

태그·멀티 이미지 tar·stdin/stdout 파이프는 어떻게 쓰나?

한 줄 답: docker save/docker load는 stdin/stdout 파이프, -o/-i 플래그, gzip 압축을 모두 지원하며, 하나의 tar 파일에 여러 이미지를 묶을 수 있습니다.

stdout 파이프와 gzip 압축

docker save는 기본적으로 tar 스트림을 stdout에 출력합니다. 이를 gzip으로 압축하여 저장하는 방법은 다음과 같습니다.

# stdout을 파이프로 gzip 압축 후 파일 저장
docker save myimage:latest | gzip > myimage.tar.gz

# gzip 압축 파일을 직접 load (docker load는 gzip을 자동 감지)
docker load < myimage.tar.gz

공식 문서에 따르면 docker load는 gzip 압축 여부를 자동으로 감지합니다. 별도의 압축 해제 없이 .tar.gz 파일을 직접 docker load에 전달할 수 있습니다.

-o / -i 플래그

stdin/stdout 리다이렉션 대신 명시적 파일 경로를 지정하려면 플래그를 사용합니다.

# -o 플래그: 출력 파일 지정 (save)
docker save -o myimage.tar myimage:latest

# -i 플래그: 입력 파일 지정 (load)
docker load -i myimage.tar

멀티 이미지 tar

docker save는 하나의 tar 파일에 여러 이미지를 묶어 저장할 수 있습니다. 이미지 이름과 태그를 공백으로 구분하여 나열합니다.

# 여러 이미지를 하나의 tar에 저장
docker save -o multi.tar ubuntu:22.04 alpine:latest nginx:stable

# 동일하게 load로 복원 (모든 이미지가 한 번에 복원됨)
docker load -i multi.tar

멀티 이미지 tar에서 docker load를 실행하면 포함된 모든 이미지가 한 번에 로컬 이미지 스토어에 등록됩니다.

태그 지정 없이 저장된 경우

이미지 ID만으로 저장하거나 태그 정보가 없는 경우, docker save <IMAGE_ID>로 저장한 tar를 load하면 리포지토리와 태그가 <none>:<none>으로 나타날 수 있습니다. 이 경우는 다음 섹션의 점검 방법을 참고하시기 바랍니다.

이미지가 “없다”고 나올 때 load·tag·run 순서를 어떻게 점검하나?

한 줄 답: docker load 후 이미지가 <none>:<none>으로 표시되는 경우, docker images로 이미지 ID를 확인하고 docker tag로 이름을 부여한 뒤 docker run을 실행합니다.

증상

docker loaddocker run myimage:latest를 실행했을 때 Unable to find image 'myimage:latest' locally 오류가 발생하거나, docker images 목록에 이미지가 <none>:<none>으로 보이는 경우가 있습니다.

원인

  • docker import 혼용: docker save 대신 docker export로 만든 tar를 docker import로 가져왔을 때, 기본적으로 태그 없이 단일 레이어 이미지가 생성됩니다.
  • 태그 없이 save: docker save <IMAGE_ID>와 같이 이미지 이름 없이 ID만으로 저장하면, load 후 리포지토리·태그 정보가 <none>:<none>으로 나타납니다.

점검 및 해결 순서

다음 순서로 점검하고 수정합니다.

  1. docker images로 이미지 ID 확인

    docker images

    <none>:<none> 행에서 IMAGE ID 열의 값(예: a1b2c3d4e5f6)을 메모합니다.

  2. docker tag로 이름 부여

    docker tag a1b2c3d4e5f6 myimage:latest

    이미지 ID를 원하는 리포지토리 이름과 태그로 연결합니다.

  3. docker run으로 실행

    docker run myimage:latest

    태그 부여 후 정상적으로 실행됩니다.

재발 방지

처음부터 태그를 명시하여 저장하면 이 문제가 발생하지 않습니다.

# 권장: 이미지 이름과 태그를 명시하여 save
docker save -o myimage.tar myimage:latest

docker import로 가져올 경우에도 명령어 끝에 repository:tag를 붙이면 태그를 바로 지정할 수 있습니다.

docker import payload.tar myimage:latest

FAQ

한 줄 답: 자주 묻는 질문을 정리합니다. docker save/load는 이미지 이동에, docker export/import는 컨테이너 파일시스템 스냅샷에 사용합니다.

질문답변
docker import 시 리포지토리와 태그를 지정할 수 있나요?네, 가능합니다. docker import payload.tar repository:tag 형식으로 명령어 마지막에 이름을 지정합니다. 지정하지 않으면 <none>:<none>으로 생성됩니다.
docker export 시 볼륨 데이터도 포함되나요?포함되지 않습니다. 공식 문서에 따르면 마운트된 볼륨 내의 데이터는 docker export에 포함되지 않습니다. 볼륨 데이터를 별도로 백업해야 합니다.
docker load -idocker load < file은 동일한가요?결과는 동일합니다. -i 플래그는 입력 파일 경로를 명시적으로 지정하는 방식이고, < 리다이렉션은 셸에서 stdin을 파일로 연결하는 방식입니다. 두 방법 모두 gzip 압축 파일을 자동 감지합니다.
이미지 저장 시 -o 없이 stdout 리다이렉션만 사용해도 되나요?네, 동일합니다. docker save myimage:latest > myimage.tardocker save -o myimage.tar myimage:latest는 같은 결과를 냅니다. gzip 압축이 필요하다면 파이프를 사용하는 방법이 더 간결합니다.
멀티 이미지 tar에서 특정 이미지만 load할 수 있나요?공식 CLI 기준으로 docker load는 tar 전체를 한 번에 로드합니다. 특정 이미지만 선택적으로 가져오려면 tar를 수동으로 분리하거나 처음부터 개별 tar로 저장하는 방법을 권장합니다.

출처

한 줄 답: 본문 사실은 2026-09-14 기준으로 확인한 Docker 공식 CLI 문서를 바탕으로 작성되었습니다.

이 글은 Docker 공식 CLI 문서를 기준으로 한 일반 안내이며, 엔진 버전과 이미지 스토어 설정(classic storage driver vs containerd image store)에 따라 저장 경로·출력은 달라질 수 있습니다.