Docker & Containers Explained: Docker 작동 방식에 대한 초보자 친화적인 가이드

발행: (2026년 1월 16일 오후 07:43 GMT+9)
15 min read
원문: Dev.to

Source: Dev.to

현대 소프트웨어 개발은 더 이상 단순히 코드를 작성하는 것만을 의미하지 않습니다. 그 코드를 어디서든 안정적으로 실행하는 것—노트북, 테스트 환경, 그리고 실제 운영 환경—이 또한 중요합니다. 여기서 컨테이너화와 Docker가 등장합니다.

이번 블로그에서는 다음 내용을 쉽게 이해할 수 있도록 풀어보겠습니다:

  • 컨테이너가 무엇인지
  • Docker가 왜 만들어졌는지
  • Docker가 내부적으로 어떻게 동작하는지

…완전히 처음 접하는 사람도 이해하기 쉬운 방식으로 설명합니다.

왜 우리는 컨테이너가 필요했는가

컨테이너가 등장하기 전에는 애플리케이션을 보통 서버나 가상 머신에 직접 배포했습니다. 이로 인해 여러 문제가 발생했습니다:

문제설명
환경 드리프트다양한 환경(개발, 테스트, 프로덕션)에서 동작이 달라짐
의존성 충돌애플리케이션이 라이브러리, 런타임 등을 두고 충돌함
배포 및 롤백 어려움수동 작업, 긴 릴리스 기간, 다운타임
확장성 부족용량을 늘리려면 전체 서버/VM을 복제해야 함

개발자들은 애플리케이션과 실행에 필요한 모든 것을 함께 패키징하고, 어디서든 동일하게 실행할 수 있는 방법이 필요했습니다.

컨테이너란 무엇인가

컨테이너는 가볍고 휴대 가능한 단위로 다음을 패키징합니다:

  • 애플리케이션 코드
  • 런타임 (Node, Python, Java 등)
  • 라이브러리 및 종속성
  • 설정

컨테이너는 호스트 운영 체제 커널을 공유하지만 격리된 사용자 공간에서 실행되어 빠르고 효율적입니다.

선박 컨테이너 비유

  • 내부 내용물은 선박에 중요하지 않다.
  • 컨테이너는 선박, 트럭, 항구 사이를 자유롭게 이동할 수 있다.
  • 내부에 있는 모든 것은 그대로 유지된다.

Virtual Machines vs. Containers

FeatureVirtual MachinesContainers
OSVM당 전체 게스트 OS호스트 OS 커널 공유
Startup time초 또는 밀리초
Resource usage무겁다가볍다
Isolation강력함프로세스 수준 격리
Portability제한적매우 높음

Analogy:
VM은 각 손님에게 전체 집을 임대하는 것과 같습니다.
컨테이너는 같은 건물 안의 방을 임대하는 것과 같습니다.

컨테이너 이전의 문제점

  • Dependency hell – 하나의 앱은 Node 16이 필요하고, 다른 앱은 Node 18이 필요 → 하나를 업그레이드하면 다른 앱이 깨짐.
  • “Works on my laptop” 증후군 – 개발자 노트북에서는 동작하지만 QA에서는 실패하고, 운영 환경에서는 OS 버전, 라이브러리, 설정, 런타임 차이 때문에 깨짐.
  • Scaling headaches – 트래픽 증가에 대비해 서버/VM을 복제하고, 모든 설정을 다시 구성하고, 기다려야 함.
  • Manual deployments – 긴 릴리스 기간, 오류가 발생하기 쉬운 롤백, 빈번한 다운타임.

컨테이너가 해결하는 문제

  • Same container runs everywhere – 환경 차이가 사라짐.
  • Scale by running more containers – 빠르고 저렴하며 자동화됨.
  • Rollback by switching container versions – 간단하고 신뢰성 있음.

Docker 소개

Docker는 다음을 도와주는 도구입니다:

  • 애플리케이션 패키징 – 실행에 필요한 모든 것을 포함합니다.
  • 어떤 머신에서도 동일하게 실행 – “앱을 한 번 빌드하면 어디서든 실행할 수 있습니다.”

환경을 수동으로 설정하는 대신, Docker는 컨테이너를 사용해 이를 자동화합니다.

Docker 이전

  • 컨테이너는 존재했지만 사용하기 어려웠습니다.
  • 각 회사마다 자체 도구가 있었습니다.
  • 개발자들은 설정 및 일관성 문제에 어려움을 겪었습니다.

Docker의 해답

  • 표준 포맷Dockerfile 및 이미지.
  • 간단한 명령docker build, docker run.
  • 쉬운 이미지 공유 – 레지스트리(Docker Hub, GHCR, 사설 레지스트리).

Docker는 우리가 논의한 문제들을 직접 해결합니다:

문제Docker 해결책
의존성 충돌각 앱마다 별도의 컨테이너를 사용
환경 불일치동일한 이미지가 어디서든 실행
배포 지연컨테이너를 몇 초 안에 시작
롤백 어려움이미지 버전을 쉽게 전환

Docker가 복잡성을 없애는 것은 아닙니다—오히려 깔끔하게 패키징합니다.

현대 워크플로우에서 Docker의 위치

  • Local development – 모든 개발자가 동일한 설정을 사용합니다.
  • CI/CD pipelines – 예측 가능한 빌드와 테스트.
  • Microservices – 각 서비스가 자체 컨테이너에서 실행됩니다.
  • Cloud & Kubernetes – Docker 이미지가 표준 단위입니다.

Docker는 종종 first step toward:

  • Kubernetes
  • DevOps
  • Cloud‑native architectures

Source:

Docker 빌딩 블록

ComponentWhat it does
Docker Client사용자가 입력하는 (docker build, docker run) 명령이나 GUI가 호출하는 부분. 요청을 daemon에 보냅니다.
Docker Daemon (dockerd)실제로 이미지를 빌드하고 컨테이너를 실행하는 백그라운드 서비스.
containerd & runcdaemon이 이미지를 실행 중인 프로세스로 전환할 때 사용하는 저수준 도구들. 외우기보다는 Docker이 실제 프로세스 생성을 이 도구들에 위임한다는 점만 기억하면 됩니다.
Image레시피나 설계도와 같은 읽기 전용(frozen) 스냅샷.
Container이미지의 실행 인스턴스. 얇은 쓰기 가능한 레이어를 추가해 애플리케이션이 실행 중에 파일을 변경할 수 있게 합니다.
Dockerfile이미지를 빌드하기 위한 명령들을 담은 간단한 텍스트 파일(베이스 이미지, 복사할 파일, 실행할 명령 등). docker build가 이를 읽어 이미지를 생성합니다.
Registry이미지 저장소(Docker Hub, GitHub Container Registry, 사설 레지스트리 등). docker pushdocker pull을 통해 어디서든 이미지를 주고받을 수 있게 합니다.

Docker가 의존하는 커널 기능

  • Namespaces – 컨테이너마다 프로세스, 네트워크, 파일시스템 등을 독립적인 시각으로 제공합니다. 마치 각각의 방이 별도의 시야를 갖는 것과 같습니다.
  • cgroups (control groups) – 컨테이너가 사용할 CPU, 메모리, 디스크 등을 제한합니다. 방의 전력 제한기와 같은 역할을 합니다.

이 두 기능이 결합돼 전체 OS를 구동하는 오버헤드 없이 격리된 환경을 제공합니다.

이미지 레이어

Dockerfile 단계는 레이어를 생성합니다. 레이어가 변경되지 않았다면 캐시가 활용되어, Dockerfile 순서를 적절히 잡으면 빌드 속도가 빨라집니다.

네트워킹

Docker는 각 컨테이너에 네트워크 인터페이스를 할당하고, 호스트 포트(-p host:container)를 매핑해 서비스에 접근할 수 있게 합니다.

볼륨

컨테이너 재시작 후에도 유지되어야 하는 데이터는 볼륨을 사용합니다. 볼륨은 컨테이너의 일시적인 쓰기 레이어 밖에 데이터를 보관합니다.

Example Dockerfile

# Use an official Node runtime as a parent image
FROM node:18-alpine

# Set working directory inside the container
WORKDIR /app

# Copy package.json and package-lock.json first (for caching)
COPY package*.json ./

# Install app dependencies
RUN npm ci --only=production

# Copy the rest of the application source code
COPY . .

# Expose the port the app runs on
EXPOSE 3000

# Define the command to run the app
CMD ["node", "index.js"]

이미지 빌드:

docker build -t my-node-app:1.0 .

컨테이너 실행:

docker run -d -p 8080:3000 --name my-app my-node-app:1.0

TL;DR

Docker는 앱을 패키징하고 어디서든 동일하게 실행할 수 있게 도와주는 작은 시스템입니다. 위에서 설명한 컨테이너, 이미지, Dockerfile, 레지스트리, 그리고 기본 커널 기능을 이해하면 Docker를 워크플로에 적용하고 현대적인 클라우드‑네이티브 아키텍처로 원활히 전환할 준비가 됩니다.

컨테이너화된 Node.js 앱 실행

이 섹션에서는 명령을 복사‑붙여넣기하여 실제로 컨테이너화된 앱을 실행합니다. 사전 Docker 경험은 필요 없습니다. 매우 간단한 Node.js 웹 서버를 컨테이너화합니다.

사전 요구사항

  • Docker가 설치되어 있음(docker --version 명령이 작동해야 함)
  • 운영체제는 Windows / macOS / Linux 중 어느 것이든 상관없음

1. 프로젝트 폴더 설정

mkdir simple-docker-app
cd simple-docker-app

2. 애플리케이션 소스 생성

index.js

const http = require('http');

const PORT = 3000;

const server = http.createServer((req, res) => {
  res.writeHead(200, { 'Content-Type': 'text/plain' });
  res.end('Hello from Docker Container!');
});

server.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

package.json

{
  "name": "simple-docker-app",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "node index.js"
  }
}

3. Dockerfile 작성

다음 내용을 가진 Dockerfile(확장자 없음) 파일을 생성합니다:

# Use an official Node.js runtime
FROM node:18

# Set working directory inside container
WORKDIR /app

# Copy package files first (for caching)
COPY package*.json ./

# Install dependencies
RUN npm install

# Copy application source code
COPY . .

# Expose application port
EXPOSE 3000

# Start the application
CMD ["npm", "start"]

4. Docker 이미지 빌드

Dockerfile과 같은 폴더에서 다음 명령을 실행합니다:

docker build -t simple-web-app .

This creates a Docker image called simple-web-app.

5. 컨테이너 실행

docker run -p 3000:3000 simple-web-app
  • 컨테이너 내부 포트 3000이 호스트의 포트 3000에 매핑됩니다.

6. 앱 확인

브라우저를 열고 다음 주소에 접속합니다:

http://localhost:3000

다음과 같은 화면이 표시됩니다:

Hello from Docker Container!

방금 무슨 일이 일어났나요?

  • Docker는 애플리케이션 + Node.js + 설정을 하나의 이미지로 패키징합니다.
  • 해당 이미지로부터 컨테이너가 생성됩니다.
  • 컨테이너 내부 포트 3000이 여러분의 머신에 매핑되었습니다.
  • 애플리케이션은 어디서든 동일하게 실행됩니다.

왜 중요한가

  • 모든 개발자 노트북에서 앱을 실행할 수 있습니다.
  • CI/CD 파이프라인에서 사용할 수 있습니다.
  • 추가 설정 없이 클라우드 서버에서도 동작합니다.

Docker는 단순한 도구가 아니라 소프트웨어를 구축하고 배포하는 방식에 대한 근본적인 변화입니다.

컨테이너의 장점

  • 환경 문제를 제거합니다.
  • 배포를 단순화합니다.
  • 자신 있게 확장할 수 있습니다.

이해했다면

  • 컨테이너가 무엇인지.
  • Docker가 존재하는 이유.
  • Docker가 내부적으로 어떻게 동작하는지.

…실제 프로젝트에 Docker를 사용할 준비가 된 것입니다!

Back to Blog

관련 글

더 보기 »

Linus Torvalds는 'Vibe Coding'이다.

음, 논쟁은 공식적으로 끝났습니다. Linux와 Git의 창시자이자 현대 인터넷에서 가장 중요한 엔지니어 중 한 명이라 할 수 있는 Linus Torvalds가 방금 이…

왜 클라우드 인프라가 이벤트 기반인가?

왜 클라우드 인프라스트럭처는 event‑driven인가? 클라우드는 예측 가능성을 위해 구축된 것이 아니다. 변화에 대비해 구축되었다. traffic spikes가 예고 없이 발생한다. costs drift가 조용히 일어난다.