개발자를 위한 Docker: 이미지, 컨테이너, Compose
Docker가 개발 워크플로를 어떻게 단순화할 수 있는지 들어보셨을 것입니다. 하지만 이미지, 컨테이너, Docker Compose와 같은 용어를 처음 접하면 부담스러울 수 있습니다. 이 가이드는 혼란을 없애고 프로젝트에서 Docker를 효과적으로 사용하는 방법을 정확히 보여줍니다.
Docker란 무엇이며 왜 중요할까요?
Docker는 애플리케이션과 그 종속성을 컨테이너라는 표준화된 단위로 패키징하는 플랫폼입니다. 컨테이너는 가볍고 이식성이 뛰어나며 서로 격리되어 있습니다. 이들은 앱이 모든 곳에서 동일하게 실행되도록 보장하여 고전적인 "내 컴퓨터에서는 작동해" 문제를 해결합니다.
가상 머신과 달리 컨테이너는 호스트 OS 커널을 공유하므로 시작 속도가 빠르고 더 효율적입니다. 이것이 Docker가 현대 개발 및 배포 파이프라인에서 필수 요소가 된 이유입니다.
이미지 vs. 컨테이너: 빌딩 블록
이미지는 애플리케이션 코드, 런타임, 라이브러리, 설정을 포함하는 읽기 전용 템플릿입니다. 컨테이너는 이미지의 실행 인스턴스입니다. 이미지를 클래스, 컨테이너를 객체라고 생각하세요.
Dockerfile을 사용하여 이미지를 생성합니다. 다음은 Node.js 앱을 위한 간단한 예입니다:
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]
Dockerfile의 각 줄은 레이어를 생성합니다. 레이어는 캐시되므로 이후 단계만 변경될 때 재빌드가 더 빠릅니다.
일반적인 Docker 명령어
docker build -t my-app .— 현재 디렉토리에서 이미지 빌드docker run -p 3000:3000 my-app— 컨테이너 실행 및 포트 매핑docker ps— 실행 중인 컨테이너 목록docker stop <container_id>— 컨테이너 중지docker rmi <image_id>— 이미지 제거
Docker Compose: 멀티 컨테이너 앱 관리
실제 앱은 종종 웹 서버, 데이터베이스, 캐시 등 하나 이상의 서비스가 필요합니다. Docker Compose를 사용하면 단일 YAML 파일로 멀티 컨테이너 애플리케이션을 정의하고 실행할 수 있습니다.
다음은 PostgreSQL과 Redis를 사용하는 Node.js 앱을 위한 docker-compose.yml입니다:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- DATABASE_URL=postgres://user:pass@db:5432/mydb
- REDIS_URL=redis://cache:6379
depends_on:
- db
- cache
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
volumes:
- pgdata:/var/lib/postgresql/data
cache:
image: redis:7
volumes:
pgdata:
docker compose up을 실행하면 모든 서비스가 함께 시작됩니다. depends_on은 데이터베이스와 캐시가 웹 서비스보다 먼저 시작되도록 보장합니다.
주요 Compose 명령어
docker compose up -d— 모든 서비스를 백그라운드 모드로 시작docker compose down— 컨테이너, 네트워크 중지 및 제거docker compose logs -f web— 특정 서비스의 로그 팔로우docker compose exec web sh— 실행 중인 컨테이너 내부에서 셸 열기
개발을 위한 모범 사례
- .dockerignore 사용 — 빌드 컨텍스트에서 node_modules, .git 및 기타 불필요한 파일 제외.
- 이미지 크기 최소화 — Alpine 기반 이미지와 멀티 스테이지 빌드 사용.
- 루트로 실행하지 마세요 — 보안을 위해 Dockerfile에서 비루트 사용자 생성.
- 영구 데이터에는 볼륨 사용, 개발 중 라이브 코드 리로딩에는 바인드 마운트 사용.
- 버전 고정 — 예상치 못한 업데이트를 피하기 위해 Dockerfile과 Compose 파일에서 버전 고정.
Docker를 사용해야 할 때 (그리고 사용하지 말아야 할 때)
Docker는 팀 간 일관된 환경, 쉬운 종속성 관리 또는 마이크로서비스가 필요할 때 빛을 발합니다. 간단한 정적 사이트나 스크립트에는 과잉일 수 있습니다. 프로젝트의 복잡성과 배포 요구 사항을 기준으로 평가하세요.
FAQ
이미지와 컨테이너의 차이점은 무엇인가요?
이미지는 정적 템플릿이고, 컨테이너는 해당 이미지의 실행 인스턴스입니다. 동일한 이미지에서 여러 컨테이너를 실행할 수 있습니다.
단일 컨테이너에 Docker Compose가 필요한가요?
아니요, 단일 컨테이너에는 docker run을 사용할 수 있습니다. Compose는 통신이 필요한 여러 서비스가 있을 때 유용합니다.
Docker에서 데이터를 영구적으로 저장하려면 어떻게 해야 하나요?
볼륨이나 바인드 마운트를 사용하세요. 볼륨은 Docker가 관리하며 데이터베이스에 이상적이고, 바인드 마운트는 호스트 디렉토리를 컨테이너에 매핑하여 개발에 유용합니다.
Docker화된 앱을 최적화할 준비가 되셨나요? 컨테이너 내부에서 Nginx 로그를 다루고 있다면, 로그를 빠르게 파싱하고 분석할 수 있는 Nginx Log Analyzer를 사용해 보세요.