Docker의 목적은 애플리케이션과 실행에 필요한 환경을 하나의 배포 단위로 묶는 것이다.
Application -> Runtime -> Dependencies -> Configuration -> Image -> Container -> Process
개발 환경과 서버 환경의 차이로 발생하는 문제를 줄인다.
Source Code -> Dockerfile -> Image -> Registry -> Server -> Container
Docker 전체 구조
Docker의 핵심 관계는 다음과 같다.
Dockerfile -> Image -> Container
이미지는 컨테이너를 생성하기 위한 템플릿이고, 컨테이너는 이미지를 기반으로 실행되는 인스턴스다.
Image -> Container A
Image -> Container B
Image -> Container C
Docker Engine
Docker CLI에서 명령을 실행하면 Docker Engine에 작업을 요청한다.
Docker CLI -> Docker API -> Docker Engine -> Image / Container / Network / Volume
Docker 명령은 크게 다음 흐름으로 이해하면 된다.
docker build -> Image 생성
docker pull -> Image 다운로드
docker run -> Container 생성 및 실행
docker stop -> Container 중지
docker rm -> Container 삭제
Docker Image
Image는 여러 Layer로 구성된다.
Base Image -> System Package -> Runtime -> Dependencies -> Application Code -> Image
Dockerfile을 기반으로 Image를 만든다.
Dockerfile -> docker build -> Image
Dockerfile의 일반적인 구성 흐름은 다음과 같다.
FROM -> WORKDIR -> COPY -> RUN -> COPY -> CMD
예를 들어 Node.js 애플리케이션은 다음처럼 구성할 수 있다.
Node Image -> Working Directory -> package.json -> npm install -> Source Code -> Application Start
Docker Layer와 Build Cache
Dockerfile의 각 단계는 Layer를 형성한다.
FROM -> Layer
RUN -> Layer
COPY -> Layer
RUN -> Layer
변경이 적은 작업을 앞에 배치하면 Cache를 활용하기 좋다.
package.json -> npm install -> Cache
Source Code -> COPY -> 변경 발생
따라서 일반적인 Node.js Dockerfile은:
package.json -> Dependency Install -> Source Code Copy -> Application Start
순서로 구성하는 경우가 많다.
Container
Container는 Image를 기반으로 실행되는 격리된 프로세스 환경이다.
Image -> docker run -> Container -> Process
Container는 VM과 구조가 다르다.
Host OS -> Docker Engine -> Container -> Application
VM은 일반적으로:
Host OS -> Hypervisor -> Guest OS -> Application
Container는 Guest OS를 별도로 실행하는 방식이 아니라 호스트의 커널 기능을 활용해 프로세스와 리소스를 격리한다.
Container와 VM
VM -> Guest OS -> Application
Container -> Host Kernel -> Application Process
따라서 Container는 작은 VM이라고 보는 것보다 격리된 애플리케이션 실행 환경으로 이해하는 것이 정확하다.
Docker Registry
Image를 다른 환경으로 전달하려면 Registry를 사용할 수 있다.
Dockerfile -> docker build -> Image -> docker push -> Registry
서버에서는:
Registry -> docker pull -> Image -> docker run -> Container
전체 배포 흐름은:
Source Code -> Dockerfile -> Image -> Registry -> Server -> Container
Docker Volume
Container 내부에 중요한 데이터를 저장하면 Container 삭제 시 데이터가 사라질 수 있다.
따라서 영속 데이터는 Volume으로 분리한다.
Container -> Application -> Data -> Volume
MySQL을 예로 들면:
MySQL Container -> Database Files -> Volume
Container와 데이터의 관계는 다음처럼 잡으면 된다.
Container -> 실행 환경
Volume -> 영속 데이터
Container를 삭제하고 다시 만들어도 Volume을 연결하면 데이터를 유지할 수 있다.
Container A -> Volume
Container A 삭제 -> Volume 유지
Container B -> 동일 Volume -> 기존 데이터 사용
Docker Network
여러 Container가 통신하려면 Docker Network를 사용할 수 있다.
Application Container -> Docker Network -> Database Container
여러 서비스가 같은 Network에 연결되면 서비스 이름을 통해 통신할 수 있다.
Application -> db -> Database
전체 구조는:
Application Container -> Docker Network -> Database Container
Docker Compose
Container 하나만 실행할 때는 docker run으로 충분하다.
여러 Container를 함께 실행하려면 Compose를 사용할 수 있다.
compose.yaml -> Application Container + Database Container + Redis Container -> Docker Network
Compose를 이용한 실행 흐름은:
compose.yaml -> docker compose up -> Containers 생성 -> Network 연결 -> Services 실행
종료할 때는:
docker compose down -> Containers 종료 및 제거
Compose 전체 구조
compose.yaml -> Application -> Database -> Redis -> Network -> Volume
실제 애플리케이션 구조는:
Client -> Application Container -> Database Container
Client -> Application Container -> Redis Container
Port Mapping
Container 내부 Port와 Host Port는 서로 다를 수 있다.
Host : 9000 -> Container : 8080
Docker에서는:
docker run -p 9000:8080
형태로 연결한다.
전체 흐름은:
Client -> Host : 9000 -> Container : 8080 -> Application
Environment
Image 자체는 최대한 동일하게 유지하고 실행 환경에 따라 달라지는 값은 외부에서 주입할 수 있다.
Image -> Container -> Environment Variables -> Application Configuration
예를 들어:
Container -> DB_HOST -> Database
Container -> DB_PORT -> Database
Container -> API_KEY -> External Service
환경에 따라 다른 설정을 주입할 수 있다.
Same Image -> Development Environment
Same Image -> Staging Environment
Same Image -> Production Environment
Docker Build
Image를 만드는 과정은:
Source Code -> Dockerfile -> docker build -> Image
Dockerfile 내부에서는:
Base Image -> Dependencies -> Application -> Image Layer
Docker Run
Container를 실행하는 과정은:
Image -> docker run -> Container -> Process
Port와 Environment를 포함하면:
Image -> docker run -> Port Mapping + Environment + Volume -> Container -> Application
Docker 배포
Docker를 실제 서버에 배포하는 기본 흐름은:
Git -> Dockerfile -> docker build -> Image -> Registry -> Server -> docker pull -> Container
CI/CD까지 연결하면:
Git Push -> CI -> Test -> Docker Build -> Image -> Registry -> Deployment -> Container
Docker와 Kubernetes
Docker와 Kubernetes는 역할이 다르다.
Docker -> Image Build -> Container Packaging -> Container Execution
Kubernetes -> Container Scheduling -> Scaling -> Service Discovery -> Health Check -> Rolling Update
전체적인 관계는:
Application -> Docker Image -> Container -> Kubernetes -> Multiple Servers
Kubernetes에서는 Docker Engine 자체가 필수인 것은 아니다.
Kubernetes -> CRI -> Container Runtime
대표적인 Container Runtime으로 containerd, CRI-O 등이 사용될 수 있다.
Docker와 애플리케이션 구조
실제 서버 애플리케이션에서는 하나의 Container만 존재하지 않을 수 있다.
Client -> Application Container -> Database Container
Client -> Application Container -> Redis Container
Compose를 사용하면:
compose.yaml -> Application -> Database -> Redis -> Network -> Volume
Docker 전체 배포 흐름
가장 중요한 전체 흐름은 이것이다.
Source Code -> Dockerfile -> docker build -> Image -> Registry -> Server -> docker pull -> Container -> Application
데이터까지 포함하면:
Source Code -> Dockerfile -> Image -> Registry -> Container -> Application -> Volume
네트워크까지 포함하면:
Client -> Host Port -> Application Container -> Docker Network -> Database Container -> Volume
Docker의 핵심 관계
Dockerfile -> Image -> Container
Image -> Registry -> Server
Container -> Network -> Container
Container -> Volume
Container -> Environment -> Application
Compose -> Multiple Containers -> Network -> Volume
Docker 핵심 명령 흐름
docker build -> Image 생성
docker pull -> Registry에서 Image 다운로드
docker run -> Image에서 Container 실행
docker ps -> Container 확인
docker logs -> Container 로그 확인
docker exec -> Container 내부 명령 실행
docker stop -> Container 중지
docker rm -> Container 삭제
docker rmi -> Image 삭제
Compose는:
docker compose up -> 전체 서비스 실행
docker compose down -> 전체 서비스 종료
docker compose ps -> 서비스 상태 확인
docker compose logs -> 서비스 로그 확인
최종 핵심 흐름
Docker의 전체 개념을 하나로 압축하면 다음이다.
Application -> Dockerfile -> Image -> Registry -> Server -> Container -> Process
컨테이너 주변의 실행 환경까지 포함하면:
Image -> Container -> Environment + Network + Volume -> Application
여러 서비스를 묶으면:
Compose -> Application Container + Database Container + Redis Container -> Network + Volume
CI/CD까지 연결하면:
Git Push -> CI -> Test -> Docker Build -> Image -> Registry -> Deployment -> Container
결국 Docker에서 가장 중요한 흐름은 하나다.
Dockerfile -> Image -> Container
그리고 그 주변에:
Image -> Registry
Container -> Network
Container -> Volume
Container -> Environment
Compose -> Multiple Containers
가 붙는다.
Docker는 애플리케이션과 실행 환경을 Image로 패키징하고, 그 Image를 Container로 실행하는 구조다.
이것만 중심에 놓으면 Dockerfile, Registry, Volume, Network, Compose, CI/CD가 전부 어디에 위치하는지 자연스럽게 연결된다.