Docker
도커는 “애플리케이션을 컨테이너라는 단위로 싸서, 어디서든 똑같이 실행하게 해주는 플랫폼”
이다.
-
애플리케이션 개발, 배포 및 실행을 위한 개방형 플랫폼이다.
-
컨테이너라고 불리는 격리된 환경에서 애플리케이션을 패키징하고 실행할 수 있게 해준다.
-
도커는 컨테이너의 생성 → 실행 → 중지 → 삭제 같은 수명 주기를 관리하는 도구와 플랫폼을 제공한다.
-
컨테이너 안에는 애플리케이션과 그 애플리케이션이 동작하는 데 필요한 라이브러리, 설정 등을 같이 묶어둔다.
구조

구조를 크게 나누면 이렇게 세 덩어리로 볼 수 있다.
- Docker Client
- Docker Daemon (Docker Host)
- Registry (ex. Docker Hub)
1) Docker Client
- 우리가 터미널에서 치는 docker run, docker build 같은 명령들이 클라이언트이다.
- 클라이언트는 실제 일을 하는 게 아니라, Docker 데몬에게 API 요청을 보내는 역할만 한다.
- 클라이언트는 로컬에도 있을 수 있고, 원격 서버의 도커 데몬에 붙어서 명령을 보낼 수도 있다.
2) Docker Daemon (dockerd)
-
도커의 “엔진”에 해당한다.
-
dockerd 프로세스가 Docker API 요청을 수신하고,
- 이미지(Image)
- 컨테이너(Container)
- 네트워크(Network)
- 볼륨(Volume)
같은 도커 객체들을 실제로 관리한다.
-
컨테이너를 빌드, 실행, 중지, 삭제, 네트워크 연결 등 모든 실질적인 작업은 데몬이 한다.
3) Registry
-
도커 이미지를 저장해두는 이미지 저장소이다.
-
대표적인 예: Docker Hub
(일반적인 흐름은 개발자가 로컬에서 이미지를 빌드하고
Registry에 docker push로 올리고, 다른 서버(또는 클러스터)에서 docker pull 해서 가져다 쓰는 방식이다.)
정의 및 핵심 기술
도커/컨테이너의 장점은 보통 이런 키워드들로 정리한다.
-
일관성(Consistency)
- 애플리케이션 + 라이브러리 + 런타임 환경을 이미지로 같이 묶어서 어디서 실행하든 동일한 환경을 보장한다.
-
격리(Isolation)
- 각 컨테이너는 독립된 프로세스 공간, 파일 시스템, 네트워크 환경을 가진다.
- 한 컨테이너가 망가져도 다른 컨테이너에 직접 영향이 적고,
서로 다른 버전의 라이브러리도 충돌 없이 동시에 쓸 수 있다.
-
이식성(Portability)
- 도커 엔진만 설치되어 있으면,
- 노트북 (macOS, Windows WSL, Linux)
- 서버, 클라우드 (AWS, GCP, Azure …)
어디든지 같은 이미지를 그대로 가져다 실행할 수 있다.
-
효율성(Efficiency)
- VM은 OS를 통째로 올리지만, 컨테이너는 호스트 커널을 공유한다.
- 그래서 부팅도 빠르고, 메모리/디스크 사용량도 상대적으로 적다.
-
확장성(Scalability)
- 동일 이미지를 기반으로 컨테이너 여러 개를 찍어내서 쉽게 스케일 아웃할 수 있다.
- 쿠버네티스, Docker Swarm 같은 오케스트레이션 도구와 함께 쓰면 자동 확장도 가능하다.
-
버전 관리(Versioning)
- 이미지에 태그(tag)를 붙여서 버전별로 관리할 수 있다.
ex) myapp:1.0, myapp:1.1, myapp:latest
특정 버전으로 빠르게 롤백하는 것도 가능하다.
주요 구성요소
-
Dockerfile :
- 베이스 이미지, 필요한 패키지 설치, 소스 복사, 포트, 실행 명령 등을 여기에 적는다.
- docker build 명령으로 Dockerfile을 읽어서 실제 이미지가 만들어진다.
-
Docker Compose :
- 여러 개의 컨테이너를 하나의 서비스 묶음처럼 띄우고 싶을 때 사용하는 도구이다.
- ex) 웹 애플리케이션 + DB + 캐시를 하나의 docker-compose.yaml로 정의해두고
docker compose up 한 번에 전체 스택을 띄우는 방식이다.
-
Docker Swarm :
- 도커에서 제공하는 컨테이너 오케스트레이션 기능이다.
- 여러 노드를 묶어서 하나의 클러스터처럼 관리하고, 서비스 스케일링, 롤링 업데이트 등을 제공한다.
-
Docker network :
- 컨테이너끼리 어떻게 통신할지 정의하는 네트워크 기능이다.
- 기본적으로 bridge, host, none 등이 있고,
직접 커스텀 브리지 네트워크를 만들어 동일 네트워크의 컨테이너끼리 통신하게 할 수 있다.
-
Docker volume :
- 컨테이너는 원래 휘발성이라 삭제하면 데이터도 같이 날아간다.
- Volume을 쓰면 컨테이너 생명주기와 분리된 영속 저장 공간을 만들 수 있다.
기본적인 워크플로우
- 이미지 빌드(Build):
- Dockerfile 을 기준으로 애플리케이션 이미지를 만든다.
- docker build -t myapp:1.0 .
- 이미지 배송(Ship):
- 만든 이미지를 Registry(Docker Hub 등)에 푸시해서 다른 곳에서도 쓰게 한다.
- docker push myrepo/myapp:1.0
- 실행 (run):
- 서버(또는 다른 환경)에서 이미지를 받아 컨테이너를 실행한다.
- docker run -d --name myapp -p 80:80 myrepo/myapp:1.0
한 줄로 요약하면:
이미지 빌드 → 레지스트리에 푸시 → 어디서든 docker run 으로 실행
이미지 이해
-
container vs virtual machine:
- vm:
- 하이퍼바이저 위에 게스트 OS 전체를 올려서 그 위에서 앱을 실행한다.
- OS 부팅/업데이트까지 포함되므로 무겁고 느리다.
- 컨테이너
- 호스트 OS의 커널을 공유하면서, 프로세스를 격리해서 실행한다.
- OS를 통째로 띄우지 않아서 가볍고 빠르다.
- “프로세스를 컨테이너라는 박스 안에 넣어서 격리시킨 느낌”에 가깝다.
-
레이어 : 도커 이미지는 여러 개의 레이어(layer)로 구성된다.
-
기반 이미지 : Dockerfile 의 FROM에 사용하는 이미지이다.
ex) ubuntu:22.04, alpine:3.18, node:20, python:3.11 등
-
부모 이미지 :내 이미지가 “위에 덧씌워진 대상 이미지” 정도로 보면 된다.
ex) 대부분의 경우, FROM 으로 지정한 이미지가 곧 부모 이미지이다.
-
이미지 태그 : 태그는 이미지 버전을 구분하기 위한 라벨이다.
-
이미지 ID :
- 실제로는 각각의 이미지가 해시 값(sha256) 으로 구분된다.
- 태그는 사람 보기 편한 이름이고, 진짜 정체성은 이미지 ID이다.
- docker images 명령으로 ID를 확인할 수 있다.
기본 명령어
- docker run : 컨테이너 실행 명령어
- docker build : 컨테이너 빌드 명령어
- docker prune -a : 전체 이미지 정리 명령어
- docker stop <컨테이너 이름> : 컨테이너 중지 명령어
- docker rm <컨테이너 이름> : 컨테이너 삭제 명령어
- docker images : 이미지 목록 보기
- docker exec -it <컨테이너 이름> <경로> : 컨테이너 안에 들어가기
저작권 문제를 방지하기 위해 실제 수업에서 사용한 이미지와 직접적인 내용은 포함하지 않았으며, 일부 내용을 보완하거나 수정하여 ChatGPT를 활용해 직접 작성하였습니다.
본 포스트의 내용은 수업에서 다룬 주요 목차를 정리한 수준입니다.