이 글에서는 도커에 대한 간단한 개념을 다뤄보도록 하겠습니다. 시리즈물로 도커에 대한 공부를 진행할 예정입니다.
도커(Docker)는 애플리케이션을 신속하게 구축, 테스트 및 배포할 수 있게 해주는 컨테이너화 플랫폼입니다. 애플리케이션과 그 실행에 필요한 모든 것(라이브러리, 시스템 도구, 코드, 런타임 등)을 컨테이너라는 표준화된 단위로 패키징하여, 개발 환경이나 서버 환경에 관계없이 동일하게 작동하도록 보장합니다.
"제 컴퓨터에선 잘 됐는데..." 라는 말을 없애기 위해서입니다.
개발 환경과 실제 서버 환경이 달라 발생하는 오류를 원천적으로 차단합니다. 애플리케이션이 어디서든 똑같이 실행되도록 보장하는 것이죠.

쉽게 비유하자면, 도커는 '어디에나 둘 수 있는 완벽한 미니 생태계, 테라리움(Terrarium)'과 같습니다.
도커는 '어디에나 둘 수 있는 완벽한 미니 생태계, 테라리움(Terrarium)'과 같습니다.
- 식물 : 내가 만든 애플리케이션
- 흙, 물 : 실행에 필요한 라이브러리와 각종 도구들
- 유리 벽 : 외부와 완벽히 격리된 독립 환경
이 테라리움을 통째로 옮기기만 하면, 어느 곳(서버)에 두든 식물은 똑같이 자랍니다. 테라리움 안에는 식물(애플리케이션)뿐만 아니라, 그 식물이 자라는 데 필요한 흙, 자갈, 수분, 영양분(라이브러리, 시스템 도구 등)이 모두 갖춰져 있습니다.
이처럼 도커는 애플리케이션이 필요로 하는 환경 전체를 하나의 '독립된 생태계(컨테이너)'로 만들어, 어디서든 문제없이 똑같이 작동하도록 보장하는 기술입니다.
1. 의존성 지옥 (Dependency Hell)
2. 환경 불일치

이 문제를 해결하기 위해 가상 머신(VM, Virtual Machine)이 등장했습니다. VM은 각 애플리케이션을 위한 독립된 운영체제(Guest OS)를 통째로 가상화하여 환경을 완벽히 분리했습니다. 하지만 OS 자체를 포함하기 때문에 매우 무겁고 느리며 자원을 많이 차지하는 단점이 있었습니다.
이러한 VM의 단점을 보완하기 위해 등장한 것이 바로 컨테이너(Container) 기술이며, 이 컨테이너 기술을 누구나 쉽고 편리하게 사용할 수 있도록 만든 것이 도커(Docker)입니다.
가상 머신과 컨테이너는 모두 격리된 실행 환경을 제공하는 기술이지만, 그 방식은 전혀 다릅니다. 가장 핵심적인 차이는 운영체제(OS)를 어떻게 다루느냐에 있습니다.

VM은 물리 서버 위에 설치된 하이퍼바이저(Hypervisor)를 통해 완전히 독립적인 컴퓨터(게스트 OS)를 여러 개 생성하는 방식입니다.
- VM 하나는 CPU, 메모리, 저장공간 등 하드웨어 자원을 가상화하여 자체 운영체제를 실행합니다.
- 이 게스트 OS는 실제 물리 서버의 OS(호스트 OS)와 완전히 분리되어 있어, 시스템 충돌이나 보안 침해로부터 강력한 격리를 제공합니다.
- 대표적인 하이퍼바이저로는 VMware ESXi, Microsoft Hyper-V, KVM, VirtualBox 등이 있습니다.
- 구조 요약 : 하드웨어 → 호스트 OS → 하이퍼바이저 → 게스트 OS → 애플리케이션

컨테이너는 하이퍼바이저 없이 호스트 OS의 커널을 직접 공유하면서, 각각의 애플리케이션과 그 의존 환경을 논리적으로 분리하여 실행하는 경량 가상화 기술입니다. 프로세스 및 파일 시스템, 네트워크 등을 분리하여 마치 별도의 시스템처럼 동작합니다.
- 대표적인 컨테이너 런타임은 Docker, containerd, Podman 등이 있으며, 이들은 리눅스 커널의 기능들(Namespace, cgroup 등)을 활용하여 가벼운 격리 환경을 구현합니다.
- 컨테이너는 운영체제를 자체적으로 포함하지 않기 때문에 매우 가볍고 빠르게 실행할 수 있습니다.
- 구조 요약 : 하드웨어 → 호스트 OS → 컨테이너 엔진(Docker 등) → 앱 및 런타임 환경
1. 가상 머신의 장점
강력한 보안 격리
각각의 VM은 독립된 OS를 포함하므로, 하나의 VM이 공격받아도 다른 VM이나 호스트 시스템에 영향을 주지 않습니다. 금융기관이나 정부 기관에서 선호되는 이유입니다.
이기종 OS 가능
맥OS에서 윈도우 VM을 실행하거나, 윈도우 서버에서 리눅스 VM을 실행하는 것처럼, 다른 운영체제 실행이 가능합니다.
고립된 시스템 테스트에 적합
예: 윈도우10, 윈도우11, Ubuntu 20.04, Ubuntu 22.04 등 다양한 OS 기반의 테스트 환경을 구축할 때 유리합니다.
2. 가상 머신의 단점
높은 자원 소모
각 VM이 OS 전체를 포함하므로 수 GB 이상이며, 부팅 후 대기 상태만으로도 CPU 및 RAM을 상당히 소비합니다.
부팅 및 실행 속도 느림
마치 실제 컴퓨터를 켜는 것처럼 부팅 시간이 수 분 걸릴 수 있으며, 복제나 이관도 무겁습니다.
관리의 복잡성
패치, 업그레이드, 백업 등 OS 단위의 작업을 VM마다 수행해야 합니다.
3. 컨테이너의 장점
초경량 환경
컨테이너는 운영체제를 포함하지 않기 때문에 이미지 크기가 작고, 시작 속도도 수 초 내외로 매우 빠릅니다.
개발과 배포의 민첩성
DevOps, CI/CD 파이프라인에 매우 적합하며, 코드 변경 → 테스트 → 배포까지의 사이클이 짧습니다.
자원 효율성
수십~수백 개의 컨테이너를 하나의 서버에서 동시에 운영할 수 있으며, 리소스 할당도 유연합니다.
애플리케이션 이식성
Docker 이미지로 애플리케이션을 패키징하면, 어떤 환경에서도 동일하게 실행할 수 있어 "한 번 빌드하면 어디서든 실행"이 가능합니다.
4. 컨테이너의 단점
OS 커널 의존성
호스트 OS의 커널을 공유하므로, 윈도우 호스트에서는 윈도우 컨테이너만 실행 가능하며, 리눅스는 리눅스만 됩니다.
상대적으로 낮은 보안 격리
Namespace, cgroup 등의 논리적 격리이기 때문에, 호스트 커널에 취약점이 있을 경우 전체 컨테이너가 영향을 받을 수 있습니다.
Persistent 환경 구축 복잡
데이터베이스처럼 상태를 유지해야 하는 앱은 별도로 스토리지를 연결하고 관리해야 하므로 VM에 비해 약간의 관리 복잡성이 생길 수 있습니다.
| 상황 | 추천 기술 | 이유 |
|---|---|---|
| 서로 다른 운영체제에서 테스트가 필요할 때 | VM | 완전히 별개의 OS 실행 가능 |
| 보안이 최우선인 업무 (예: 금융, 공공기관) | VM | 높은 격리성과 안정성 |
| 마이크로서비스 기반의 시스템 운영 시 | 컨테이너 | 빠른 배포와 확장성 |
| DevOps, CI/CD 자동화 환경 구축 | 컨테이너 | 빠른 실행, 이식성, 통합성 |
| 여러 앱을 동일 OS에서 운영하고자 할 때 | 컨테이너 | 리소스 효율적 분산 가능 |
실제로 많은 기업들은 하이브리드 구조를 채택하고 있습니다.
이러한 구조는 VM의 안정성과 컨테이너의 민첩성을 모두 확보할 수 있는 전략으로, 클라우드 플랫폼(AWS, Azure, GCP)에서도 널리 채택되고 있습니다.
| 항목 | 가상 머신 (VM) | 컨테이너 (Container) |
|---|---|---|
| 비유 | 단독 주택 | 아파트 |
| 격리 방식 | 하이퍼바이저 기반 OS 격리 | 커널 공유 기반 논리적 격리 |
| 커널 | 독립적인 게스트 커널 | 호스트 OS 커널 공유 |
| 크기 | 크고 무거움 (수 GB) | 작고 가벼움 (수십~수백 MB) |
| 부팅 속도 | 느림 (분 단위) | 빠름 (초 단위) |
| OS 호환성 | 자유롭고 유연함 | 제한적 (호스트 OS 기반) |
| 이식성 | 낮음 (환경에 민감함) | 매우 높음 (Docker 이미지 기반) |
| 보안 격리 | 매우 강함 | 상대적으로 약함 |
| 적합한 용도 | 이기종 OS, 보안, 테스트 환경 | DevOps, MSA, 대규모 확장 서비스 |
Docker Image는 컨테이너(Container)를 만들기 위한 템플릿입니다.단순히 실행 파일만이 아닌, 아래의 모든 요소가 포함된 전체 실행 환경 패키지입니다
실제 여러분이 작성한 애플리케이션의 핵심 로직입니다.
애플리케이션이 동작하기 위해 외부에서 가져오는 도구들입니다. 보통 npm install, pip install 같은 명령어로 설치하죠.
예를 들어 import flask 라고 했는데 flask가 없다면 앱은 실행 도중 에러가 발생합니다.
코드나 라이브러리를 실제로 실행하기 위해 필요한 시스템 도구들입니다.
어떤 앱은 단순한 코드 실행 외에도 시스템 도구에 의존합니다. 이런 도구가 없다면 컨테이너 내부에서 오류가 발생할 수 있어, 이미지 빌드 시 함께 포함시킵니다.
컨테이너 내부에서 사용할 수 있는 기초적인 OS 환경을 제공합니다.
Docker Image는 단순히 코드만 담는 것이 아닙니다. 코드를 실행할 환경 자체가 포함되어야 함
컨테이너는 실제 OS를 따로 설치하지 않지만, 리눅스 기반의 기본 파일 시스템이 필요합니다.
컨테이너가 시작될 때 자동으로 실행할 명령입니다.
CMD ["node", "server.js"]
이렇게 설정해두면, 누군가 이 이미지를 기반으로 컨테이너를 실행할 때
docker run my-app
→ 자동으로 node server.js 명령어가 실행됩니다.
Dockerfile은 Docker Image를 자동으로 생성하기 위한 설정 파일(스크립트) 입니다. 이 파일에 적힌 내용대로 Docker가 이미지를 하나하나 단계별로 명령을 해석하고 실행해서 최종적으로 하나의 완성된 Docker Image를 만들어 줍니다.
docker run -it ubuntu
apt install nodejs
copy 내코드 /
npm install
그래서 이 모든 작업을 미리 스크립트로 저장해놓고, 자동으로 이미지를 생성하는 것이 바로 Dockerfile입니다.
FROM node:18 # 1. Node.js가 포함된 이미지 사용 (운영체제 + 런타임 포함)
WORKDIR /app # 2. 이후 작업할 디렉토리를 /app으로 설정
COPY . . # 3. 현재 프로젝트 폴더의 모든 파일을 이미지 안 /app으로 복사
RUN npm install # 4. npm으로 라이브러리 설치
CMD ["npm", "start"] # 5. 컨테이너가 실행되면 'npm start' 명령을 자동 실행
Docker Container는 Docker Image로부터 생성된 실행 가능한 실체입니다. 쉽게 말해, Image가 요리법(설계도)이라면, Container는 실제로 요리된 음식(실행 중인 앱)입니다.
| 요소 | 격리됨? | 설명 |
|---|---|---|
| 파일시스템 | ✅ | 각 컨테이너는 자신의 파일만 접근 가능 |
| 메모리 | ✅ | 다른 컨테이너와 메모리 공간 공유 안함 |
| 네트워크 | ✅ | 독립된 IP, 포트 사용 가능 |
| 프로세스 | ✅ | 호스트와 별도의 프로세스 공간 사용 |
즉, 마치 작은 가상 서버처럼 느껴집니다. 하지만 VM보다 훨씬 가볍고 빠릅니다.
docker run -d --name web nginx:1.25
이 명령어는 nginx 웹서버를 컨테이너로 실행시킵니다.
기본적으로 컨테이너는 일시적인 환경입니다. 컨테이너가 삭제되면 데이터도 함께 사라집니다. 하지만 중요한 데이터가 있다면? 예: DB, 로그, 업로드 파일 등 → 이를 보존하기 위해 Volume을 연결합니다.
docker run -d -v /mydata:/data myapp
컨테이너가 데이터를 /data에 쓰면, 실제로는 /mydata에 저장됨
https://docs.docker.com/guides/
https://opensource.microsoft.com/blog/2019/07/15/how-to-get-started-containers-docker-kubernetes/
https://helpezee.wordpress.com/category/docker/