Docker 컨테이너 생명주기: run·start·stop·rm·commit 차이

반응형

Docker를 처음 쓸 때 가장 자주 헷갈리는 부분은 이미지와 컨테이너의 생명주기다. 이미지는 컨테이너를 만드는 읽기 전용 기반이고, 컨테이너는 그 이미지와 실행 설정을 바탕으로 생성된 인스턴스다.

따라서 컨테이너를 멈추는 것, 컨테이너를 지우는 것, 로컬 이미지를 지우는 것은 서로 다른 작업이다.

명령어별로 바뀌는 대상을 먼저 구분한다

명령 대상 핵심 동작
docker image pull 이미지 레지스트리에서 로컬로 내려받는다
docker image push 이미지 태그가 가리키는 이미지를 레지스트리에 올린다
docker container create 컨테이너 이미지를 바탕으로 컨테이너를 만들지만 시작하지 않는다
docker container run 컨테이너 새 컨테이너를 만들고 시작한다
docker container start 컨테이너 이미 존재하는 중지된 컨테이너를 다시 시작한다
docker container stop 컨테이너 실행 중인 컨테이너의 주 프로세스에 종료 기회를 준 뒤 멈춘다
docker container rm 컨테이너 컨테이너를 제거한다
docker image rm 이미지 로컬 이미지 태그나 콘텐츠 참조를 제거한다
docker container commit 컨테이너→이미지 컨테이너의 변경으로 새 이미지를 만든다

축약형인 docker run, docker stop, docker rm, docker rmi도 사용할 수 있다. 다만 처음에는 docker containerdocker image를 붙여 쓰면 어떤 객체를 다루는지 더 잘 보인다.

run은 언제나 새 컨테이너를 만든다

docker container run은 “이미지가 없으면 pull하고, create하고, start한다”는 흐름으로 이해할 수 있다. 중요한 점은 같은 이미지와 같은 명령으로 다시 실행해도 기존 컨테이너를 재사용하지 않고 새 컨테이너를 만든다는 것이다.

docker container run --name web -d nginx:alpine
docker container stop web
docker container start web

첫 번째 명령은 web 컨테이너를 새로 만든 뒤 시작한다. 두 번째 명령으로 멈춘 뒤에는 세 번째처럼 start해야 같은 컨테이너를 다시 쓴다. 다시 run --name web ...을 실행하면 이미 같은 이름의 컨테이너가 있어 충돌한다.

그렇다고 평소에도 createstart를 반드시 나눠야 하는 것은 아니다. 새 컨테이너를 즉시 실행하는 일반적인 경우에는 run이 자연스럽다. 컨테이너 설정만 먼저 만들거나 시작 시점을 별도로 제어해야 할 때 createstart를 나눈다.

stop은 메모리에서 지우는 명령이 아니다

docker container stop은 기본적으로 컨테이너의 주 프로세스에 SIGTERM을 보내고 유예 시간 동안 종료를 기다린다. 그 안에 끝나지 않으면 SIGKILL로 강제 종료한다. 이미지의 STOPSIGNAL이나 실행 옵션에 따라 첫 신호는 달라질 수 있다.

컨테이너가 멈춰도 컨테이너 객체와 writable layer, 설정은 남는다. 그래서 start로 다시 시작하거나 inspect, logs로 상태를 확인할 수 있다. 단, 컨테이너 안에 저장된 데이터가 안전하다는 뜻은 아니다. 애플리케이션이 종료 신호를 처리하지 못했거나 쓰기 중 강제 종료됐다면 데이터 일관성 문제가 생길 수 있다.

운영 서비스라면 PID 1이 종료 신호를 제대로 받고, 진행 중인 요청을 정리한 뒤 제한 시간 안에 끝나는지 별도로 확인해야 한다.

rm과 image rm은 삭제 범위가 다르다

docker container rm은 컨테이너를 제거한다. 기본적으로 중지된 컨테이너에 사용하며, --force는 실행 중인 주 프로세스에 SIGKILL을 보내고 제거하므로 신중해야 한다.

docker container stop web
docker container rm web
docker image rm nginx:alpine

컨테이너를 지워도 기반 이미지가 자동으로 지워지지는 않는다. 반대로 docker image rm은 로컬 이미지의 태그와 콘텐츠 참조를 다룬다. 같은 이미지 ID를 여러 태그가 가리키면 특정 태그만 사라질 수 있고, 실행 중인 컨테이너가 참조하는 이미지는 보통 강제로 제거할 수 없다. 이 명령은 레지스트리에 올라간 원격 이미지를 삭제하는 명령도 아니다.

볼륨은 더 조심해야 한다. docker container rm -vdocker run --rm은 연결된 익명 볼륨을 함께 제거할 수 있지만, 이름이 있는 볼륨은 그대로 남는다. 영속 데이터는 컨테이너 생명주기와 분리해 명시적인 named volume이나 외부 저장소로 관리하는 편이 안전하다.

commit은 스냅숏이지만 재현 가능한 빌드는 아니다

docker container commit은 컨테이너의 파일 변경과 일부 설정을 새 이미지로 만든다. 디버깅 중인 상태를 보존하는 데는 유용할 수 있지만, 마운트된 볼륨의 데이터는 포함하지 않는다. 기본 설정에서는 일관성을 높이기 위해 commit 동안 컨테이너를 잠시 멈춘다.

docker container commit debug-session local/debug-image:20260802

이 명령만으로는 무엇을 설치하고 어떤 파일을 바꿨는지 과정을 설명하기 어렵다. 반복 빌드와 코드 리뷰, 취약점 추적이 필요한 이미지는 Dockerfile과 빌드 파이프라인으로 만드는 것이 낫다. commit은 문제 분석용 스냅숏에 가깝게 한정하는 편이 관리하기 쉽다.

Docker의 이미지와 컨테이너 관계부터 다시 보고 싶다면 Docker 기본 개념을, 컨테이너를 GitOps 흐름에서 다루는 맥락은 GitOps Cookbook의 컨테이너 정리에서 이어서 볼 수 있다.

참고 자료

반응형
KEEP READING
카테고리 전체 보기 →

댓글