"내 컴퓨터에서는 되는데요?" — 개발자라면 한 번쯤 들어봤거나 해본 말일 겁니다. 환경 차이로 인한 버그는 매우 흔하고 해결하기도 어렵습니다. Docker는 애플리케이션과 그 실행 환경을 하나의 컨테이너로 패키징해 어디서든 동일하게 실행할 수 있게 해줍니다.
핵심 개념
- 이미지(Image): 컨테이너를 만들기 위한 읽기 전용 템플릿. 레이어 구조로 효율적으로 관리됩니다.
- 컨테이너(Container): 이미지를 실행한 인스턴스. 격리된 환경에서 동작합니다.
- Dockerfile: 이미지를 만드는 설계도(명령어 모음).
- 레지스트리(Registry): Docker Hub처럼 이미지를 저장하고 공유하는 저장소.
기본 명령어
# 이미지 다운로드
docker pull nginx
# 컨테이너 실행 (-d: 백그라운드, -p: 포트 매핑)
docker run -d -p 8080:80 --name my-nginx nginx
# 실행 중인 컨테이너 목록
docker ps
# 모든 컨테이너 (중지 포함)
docker ps -a
# 컨테이너 중지 / 시작 / 삭제
docker stop my-nginx
docker start my-nginx
docker rm my-nginx
# 로그 확인
docker logs -f my-nginx
# 컨테이너 내부 접속
docker exec -it my-nginx bash
Dockerfile 작성하기
# Node.js 앱 Dockerfile
FROM node:20-alpine # 베이스 이미지 (경량 Alpine Linux)
WORKDIR /app # 작업 디렉토리 설정
# 의존성 먼저 복사 (캐시 최적화)
COPY package*.json ./
RUN npm install --production
# 소스 코드 복사
COPY . .
# 포트 노출 (문서용, 실제 바인딩은 docker run -p에서)
EXPOSE 3000
# 컨테이너 시작 명령
CMD ["node", "app.js"]
# 이미지 빌드
docker build -t my-app:1.0 .
# 실행
docker run -d -p 3000:3000 --name my-app my-app:1.0
.dockerignore
node_modules
.git
.env
*.log
README.md
docker-compose로 멀티 컨테이너 관리
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "3000:3000"
environment:
- DB_URL=mongodb://db:27017/mydb
depends_on:
- db
volumes:
- ./logs:/app/logs # 로그 파일 호스트와 공유
db:
image: mongo:7
ports:
- "27017:27017"
volumes:
- mongo_data:/data/db # 데이터 영속성
volumes:
mongo_data:
# 모든 서비스 시작
docker-compose up -d
# 로그 확인
docker-compose logs -f app
# 특정 서비스 재시작
docker-compose restart app
# 전체 종료 및 볼륨 삭제
docker-compose down -v
멀티 스테이지 빌드 (최적화)
# 빌드 스테이지
FROM node:20-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
# 실행 스테이지 (빌드 결과물만 복사)
FROM node:20-alpine
WORKDIR /app
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./
RUN npm install --production
CMD ["node", "dist/app.js"]
핵심 정리
Docker는 "환경 차이" 문제를 컨테이너로 해결합니다. Dockerfile로 이미지를 정의하고, docker-compose로 여러 서비스를 함께 관리하세요. 멀티 스테이지 빌드로 최종 이미지 크기를 최소화하는 것이 좋습니다.
Docker는 "환경 차이" 문제를 컨테이너로 해결합니다. Dockerfile로 이미지를 정의하고, docker-compose로 여러 서비스를 함께 관리하세요. 멀티 스테이지 빌드로 최종 이미지 크기를 최소화하는 것이 좋습니다.