왜 Docker가 필요한가
소프트웨어 개발에서 오래된 문제가 있습니다. 개발자의 로컬 환경에서는 잘 동작하던 애플리케이션이 다른 환경(테스트 서버, 동료의 PC, 프로덕션 서버)에서는 동작하지 않는 현상입니다. 이른바 “works on my machine” 문제입니다.
이 문제의 근본 원인은 환경 간의 불일치에 있습니다.
- 팀원마다 설치된 런타임(Node.js, Python, Java 등)의 버전이 다릅니다.
- 운영체제가 다르면 라이브러리 의존성이 달라집니다.
- 개발 환경과 프로덕션 환경의 설정이 달라집니다.
- CI/CD 파이프라인의 환경도 또 다릅니다.
Docker는 애플리케이션과 그것이 실행되는 인프라를 분리함으로써 이 문제를 해결합니다. 공식 문서의 표현을 빌리면, Docker는 “코드를 작성하는 시점과 프로덕션에서 실행되는 시점 사이의 지연을 획기적으로 줄입니다.”
Docker의 탄생 배경
Docker는 Solomon Hykes, Kamel Founadi, Sebastien Pahl이 창업한 dotCloud라는 PaaS(Platform as a Service) 회사에서 출발했습니다. 2008년 파리에서 시작되었으며, 2010년 Y Combinator 입주를 계기로 미국으로 이전하여 법인을 설립했습니다.
dotCloud를 운영하면서 내부적으로 Linux 컨테이너 기술을 활용하고 있었는데, 개발자들이 그 기반 기술에 관심을 보이기 시작했습니다. 결국 2013년 3월 PyCon에서 Solomon Hykes가 Docker를 처음 공개 시연하였고, 이것이 컨테이너 혁명의 시작점이 되었습니다. 같은 해 10월, 회사명도 dotCloud에서 Docker Inc. 로 변경되었습니다.
Docker 등장 이전에도 Linux 컨테이너(LXC) 기술 자체는 존재했으나, 일반 개발자가 접근하기 어려운 복잡한 기술이었습니다. 초기 Docker는 LXC를 기본 실행 환경으로 사용했으나, 이후 버전(v0.9)에서 Go 언어로 자체 개발한 libcontainer로 교체하며 LXC 의존성을 제거했습니다. Docker는 이 컨테이너 기술을 표준화하고 추상화하여 누구나 쉽게 사용할 수 있도록 하였습니다.
이후 Docker가 업계 표준이 되자, 2015년 6월에는 컨테이너 생태계의 표준화를 위해 OCI(Open Container Initiative) 가 설립되었으며, Docker는 컨테이너 이미지 명세와 런타임 코드인 runc 를 OCI에 기증했습니다. 이어서 2017년에는 컨테이너 런타임인 containerd를 CNCF(Cloud Native Computing Foundation)에 기증하여 오픈 생태계 발전에 기여했습니다.
Docker의 발전 과정과 오늘날
표준화와 생태계 확장 (2013~2017)
2013년 공개 직후 Docker는 폭발적인 관심을 받으며 컨테이너 기술의 사실상 표준(de facto standard)이 되었습니다. 이 시기 Docker는 기술적으로도 빠르게 진화했습니다. 초기에는 LXC에 의존했으나 v0.9에서 자체 개발한 libcontainer로 교체하였고, 이어서 Docker Compose, Docker Swarm(오케스트레이션), Docker Machine 등 주변 생태계 도구를 연이어 출시했습니다.
2015년에는 컨테이너 표준화를 위한 OCI(Open Container Initiative를 주도적으로 설립하고 runc를 기증했으며, 2017년에는 컨테이너 런타임인 containerd를 CNCF에 기증했습니다. 이 행보는 Docker가 단순한 도구를 넘어 컨테이너 생태계 전체의 기반 인프라를 만들겠다는 방향을 보여줍니다.
Kubernetes의 부상과 사업 구조 전환 (2017~2019)
이 시기의 결정적인 변수는 Google이 오픈소스로 공개한 Kubernetes였습니다. 컨테이너 오케스트레이션 영역에서 Docker Swarm과 Kubernetes가 경쟁하였으나, 업계는 빠르게 Kubernetes 중심으로 재편되었습니다.
이 흐름에서 Docker는 자신이 불을 붙인 시장에서 주도권을 잃었습니다. 결국 2019년 11월, Docker는 엔터프라이즈 사업부 전체를 Mirantis에 매각했습니다. Docker Enterprise에 포함된 컨테이너 엔진, 레지스트리, 오케스트레이션 플랫폼 등이 모두 Mirantis로 이전되었으며, Docker Inc.는 Docker Desktop과 Docker Hub 중심의 개발자 도구 회사로 사업을 재정의했습니다.
개발자 도구 회사로의 재집중 (2019~현재)
엔터프라이즈 매각 이후 Docker는 개발자 워크플로우에 집중하는 방향으로 전환했습니다. 이 전략은 결과적으로 유효했습니다. 2024년 기준으로 Docker는 Stack Overflow 개발자 설문에서 4년 연속 “가장 원하는 도구” 1위를 기록했으며, Docker Hub에는 월 250억 건의 이미지 풀(pull)이 발생하고 있습니다. 등록 개발자는 1,700만 명, 고객사는 79,000곳 이상입니다.
2025년 Docker의 2025 State of Application Development Report에 따르면, IT 업계의 컨테이너 사용률은 92%에 달하며, 전체 산업 평균도 30%에 이릅니다.
AI 시대의 Docker (2024~현재)
현재 Docker는 AI 개발 인프라로의 역할 확장을 적극 추진하고 있습니다. 대표적인 흐름은 다음과 같습니다.
- Docker Model Runner: 개발자가 로컬 머신에서 LLM을 직접 실행할 수 있는 환경을 제공합니다.
- Docker MCP Catalog & Toolkit: Anthropic이 주도한 MCP(Model Context Protocol) 를 채택하여, AI 에이전트가 도구와 서비스에 안전하게 접근할 수 있는 표준화된 방법을 Docker 생태계 내에서 제공합니다. 100개 이상의 MCP 서버가 Docker Hub를 통해 배포되고 있습니다.
- Docker Hardened Images: 보안 취약점(CVE)이 거의 없는 프로덕션용 강화 이미지를 무료로 제공하여, 컨테이너 보안의 기준선을 높이는 역할을 하고 있습니다.
컨테이너는 AI 에이전트 시대에도 "코드가 항상 동일하게 실행되는 신뢰할 수 있는 실행 환경"으로서의 역할을 이어가고 있으며, Docker는 그 기반 위에서 AI 개발 워크플로우를 통합하는 방향으로 진화하고 있습니다.
Docker란 무엇인가
공식 문서의 정의:
Docker is an open platform for developing, shipping, and running applications.
Docker는 애플리케이션을 개발(develop), 배포(ship), 실행(run) 하기 위한 오픈 플랫폼입니다.
Docker가 제공하는 핵심 능력은 컨테이너(container) 라는 느슨하게 격리된 환경에서 애플리케이션을 패키징하고 실행하는 것입니다. 이 격리성과 보안성 덕분에 하나의 호스트 위에서 여러 컨테이너를 동시에 실행할 수 있습니다.
Docker는 컨테이너의 생명주기 전체를 관리하는 도구와 플랫폼을 제공합니다.
- 컨테이너를 사용해 애플리케이션과 그 구성요소를 개발합니다.
- 컨테이너가 애플리케이션의 배포 및 테스트 단위가 됩니다.
- 준비가 완료되면 컨테이너 또는 오케스트레이션 서비스 형태로 프로덕션에 배포합니다.
핵심 개념: Container vs VM
Container(컨테이너)
컨테이너는 애플리케이션 구성 요소 각각을 위한 격리된 프로세스입니다.
공식 문서는 컨테이너의 네 가지 특성을 다음과 같이 정의합니다.
- Self-contained(자급자족): 호스트에 사전 설치된 의존성 없이 실행에 필요한 모든 것을 내부에 포함합니다.
- Isolated(격리됨): 격리된 환경에서 실행되므로 호스트와 다른 컨테이너에 미치는 영향이 최소화되어 보안이 향상됩니다.
- Independent(독립적): 각 컨테이너는 독립적으로 관리됩니다. 하나를 삭제해도 다른 것에 영향이 없습니다.
- Portable(이식 가능): 개발 머신에서 실행되는 컨테이너는 데이터센터나 클라우드 어디서든 동일하게 동작합니다.
VM(가상 머신)과의 차이
VM은 자체 커널, 하드웨어 드라이버, 운영체제를 가진 완전한 OS입니다. 애플리케이션 하나를 격리하기 위해 전체 OS를 올리는 것은 상당한 오버헤드입니다.
반면 컨테이너는 호스트 OS의 커널을 공유합니다. 여러 컨테이너를 실행해도 모두 같은 커널 위에서 동작하므로, 더 적은 인프라로 더 많은 애플리케이션을 실행할 수 있습니다. 그래서 Docker는 하이퍼바이저 기반 VM에 비해 비용 효율적이고 가벼운 대안이 됩니다.
실제로 VM과 컨테이너는 함께 사용되는 경우가 많습니다. 클라우드 환경에서는 VM 위에 컨테이너 런타임을 올려, 한 VM에서 여러 컨테이너 애플리케이션을 실행함으로써 자원 활용률을 높입니다.
핵심 개념: Image
컨테이너가 격리된 프로세스라면, 그 프로세스는 어디서 파일과 설정을 가져오는 걸까요? 그리고 어떻게 그 환경을 다른 사람과 공유할 수 있을까요? 이 질문에 대한 답이 이미지(Image) 입니다.
컨테이너 이미지는 컨테이너를 실행하는 데 필요한 모든 파일, 바이너리, 라이브러리, 설정을 포함한 표준화된 패키지입니다.
이미지의 두 가지 핵심 원칙이 있습니다.
- 불변성(Immutable): 이미지는 한번 생성되면 수정할 수 없습니다. 변경을 하려면 새 이미지를 만들거나 기존 이미지 위에 새 레이어를 추가해야 합니다.
- 레이어 구조(Layered): 이미지는 레이어들로 구성됩니다. 각 레이어는 파일 시스템 변경(추가, 삭제, 수정)의 집합을 나타냅니다.
이 두 원칙이 이미지를 강력하게 만듭니다. Ubuntu 이미지를 기반으로 Apache 웹 서버를 추가하고, 그 위에 자신의 애플리케이션을 얹는 방식으로 조합과 재사용이 가능합니다. Dockerfile에서 각 명령어가 하나의 레이어를 만들며, Dockerfile을 수정하고 이미지를 재빌드할 때 변경된 레이어만 재빌드되기 때문에 효율적입니다.
핵심 개념: Registry
이미지를 어떻게 저장하고 공유할까요? 이 역할을 하는 것이 레지스트리(Registry) 입니다.
Docker Hub는 Docker의 기본 공개 레지스트리입니다. 누구나 사용할 수 있으며, Docker는 기본적으로 Docker Hub에서 이미지를 찾습니다. 직접 프라이빗 레지스트리를 운영하는 것도 가능합니다.
Docker Hub는 신뢰할 수 있는 이미지를 다음과 같이 구분합니다.
- Docker Official Images: Docker가 직접 관리하는 공식 이미지 세트입니다. 대부분의 사용자에게 출발점이 되는 이미지들입니다.
- Docker Hardened Images: CVE(보안 취약점)를 거의 없앤, 프로덕션용으로 강화된 최소화 이미지입니다.
- Docker Verified Publishers: Docker가 검증한 상용 게시자의 고품질 이미지입니다.
- Docker-Sponsored Open Source: Docker가 후원하는 오픈소스 프로젝트가 게시하고 유지관리하는 이미지입니다.
Docker의 아키텍처
Docker는 클라이언트-서버 아키텍처를 사용합니다.
- Docker Daemon(
dockerd): API 요청을 수신하고 이미지, 컨테이너, 네트워크, 볼륨 등의 Docker 객체를 관리합니다. 다른 데몬과 통신하여 Docker 서비스를 관리할 수도 있습니다. - Docker Client(
docker): 사용자가 Docker와 상호작용하는 주요 수단입니다.docker run같은 명령을 입력하면 클라이언트가 이 명령을dockerd에 전달합니다. REST API를 통해 UNIX 소켓 또는 네트워크 인터페이스로 데몬과 통신합니다. - Docker Registry: Docker 이미지를 저장하는 저장소입니다.
클라이언트와 데몬은 동일한 시스템에서 실행될 수도 있고, 클라이언트를 원격 데몬에 연결할 수도 있습니다.
Docker가 해결하는 문제들
공식 문서는 Docker의 주요 사용 목적을 세 가지로 정리합니다.
빠르고 일관된 애플리케이션 배포
Docker는 개발자가 로컬 컨테이너를 사용하는 표준화된 환경에서 작업할 수 있게 함으로써 개발 생명주기를 간소화합니다. 이는 CI/CD 워크플로우에 특히 적합합니다.
- 개발자가 로컬에서 코드를 작성하고 Docker 컨테이너로 동료와 공유합니다.
- Docker를 사용해 테스트 환경으로 애플리케이션을 푸시하고 테스트를 실행합니다.
- 버그 수정 후 다시 테스트 환경에 배포하고 검증합니다.
- 테스트 완료 후, 업데이트된 이미지를 프로덕션 환경에 푸시하는 것만으로 배포가 완료됩니다.
신속한 배포와 스케일링
Docker 컨테이너는 개발자의 로컬 노트북, 데이터센터의 물리/가상 머신, 클라우드, 또는 이들의 혼합 환경 어디서든 실행될 수 있습니다. 이 이식성과 경량성 덕분에 비즈니스 요구에 따라 워크로드를 실시간에 가깝게 동적으로 관리하고 스케일링할 수 있습니다.
동일 하드웨어에서 더 많은 워크로드 실행
Docker는 가볍고 빠릅니다. 하이퍼바이저 기반 VM의 비용 효율적인 대안으로서, 동일한 서버 용량으로 더 많은 일을 처리할 수 있습니다. 고밀도 환경과 소규모~중규모 배포에서 특히 적합합니다.
Docker의 기술적 기반
Docker는 Go 언어로 작성되었으며, Linux 커널의 여러 기능을 활용하여 그 기능을 구현합니다.
공식 문서(docs.docker.com)는 Docker가 컨테이너 격리를 위해 Linux namespaces 기술을 사용한다고 명시합니다. 컨테이너를 실행할 때 Docker는 해당 컨테이너를 위한 네임스페이스 집합을 생성하며, 컨테이너의 각 측면은 별도의 네임스페이스에서 실행되어 해당 네임스페이스 내에서만 접근이 제한됩니다.
또한 Docker 공식 사이트(docker.com/resources/what-container)는 namespaces 외에 cgroups(Control Groups) 도 핵심 Linux 기술로 함께 언급합니다. 역할은 다음과 같이 구분됩니다.
- Namespaces: "무엇을 볼 수 있는가"를 제어합니다. 프로세스, 네트워크, 파일시스템 등 각 자원을 컨테이너별로 격리합니다.
- cgroups: "얼마나 사용할 수 있는가"를 제어합니다. CPU, 메모리 등 시스템 자원의 사용량을 컨테이너별로 제한하고 측정합니다.