개발자를 위한 Docker: 이미지, 컨테이너, Compose
Docker와 컨테이너에 대해 들어보셨겠지만, 이것이 일상적인 개발 워크플로에 어떻게 적용되는지 잘 모르실 수 있습니다. 아니면 Docker를 시도해봤지만 이미지, 컨테이너, Compose 개념이 혼란스러울 수도 있습니다. 이 가이드는 실용적인 예제와 함께 필수 사항을 안내하여 프로젝트에서 Docker를 효과적으로 사용할 수 있도록 도와드립니다.
Docker 이미지와 컨테이너란 무엇인가요?
Docker 이미지를 애플리케이션의 청사진이라고 생각하세요. 이미지에는 코드를 실행하는 데 필요한 모든 것(운영 체제, 런타임, 라이브러리, 애플리케이션 파일)이 포함됩니다. 이미지는 불변이며 Dockerfile에서 빌드됩니다.
컨테이너는 이미지의 실행 인스턴스입니다. 컨테이너를 시작하면 Docker가 이미지에서 격리된 환경을 만듭니다. 동일한 이미지에서 여러 컨테이너를 실행할 수 있으며 각각 고유한 상태를 가집니다.
주요 차이점
| 이미지 | 컨테이너 |
|---|---|
| 읽기 전용 템플릿 | 실행 가능한 인스턴스 |
| Dockerfile에서 빌드 | 이미지에서 생성 |
| 레지스트리에 저장 | 호스트에서 실행 |
| 불변 | 일시적 (중지, 시작, 삭제 가능) |
첫 번째 Docker 이미지 빌드하기
간단한 Node.js 앱을 만들고 컨테이너화해 보겠습니다. 프로젝트 루트에 Dockerfile을 만드는 것으로 시작하세요:
# 공식 Node.js 런타임을 부모 이미지로 사용
FROM node:18-alpine
# 작업 디렉터리 설정
WORKDIR /app
# package.json 및 package-lock.json 복사
COPY package*.json ./
# 의존성 설치
RUN npm ci --only=production
# 나머지 애플리케이션 코드 복사
COPY . .
# 앱이 실행되는 포트 노출
EXPOSE 3000
# 앱을 실행할 명령 정의
CMD ["node", "server.js"]
다음 명령으로 이미지를 빌드하세요:
docker build -t my-node-app .
이미지에서 컨테이너를 실행하세요:
docker run -p 3000:3000 -d my-node-app
이제 http://localhost:3000에서 앱에 접속할 수 있습니다.
컨테이너 관리하기
컨테이너를 관리하는 데 필요한 필수 명령은 다음과 같습니다:
docker ps– 실행 중인 컨테이너 목록docker ps -a– 모든 컨테이너 목록 (중지된 것 포함)docker stop <container_id>– 실행 중인 컨테이너 중지docker rm <container_id>– 중지된 컨테이너 제거docker logs <container_id>– 컨테이너 로그 보기docker exec -it <container_id> sh– 실행 중인 컨테이너 내부에서 셸 열기
Docker Compose로 멀티 컨테이너 앱 간소화하기
실제 애플리케이션은 종종 여러 서비스(웹 서버, 데이터베이스, 캐시 등)가 필요합니다. 이러한 서비스를 개별 docker run 명령으로 관리하는 것은 번거롭습니다. Docker Compose를 사용하면 YAML 파일로 멀티 컨테이너 애플리케이션을 정의하고 실행할 수 있습니다.
docker-compose.yml을 만드세요:
version: '3.8'
services:
web:
build: .
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- DB_HOST=db
depends_on:
- db
db:
image: postgres:15-alpine
environment:
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
- POSTGRES_DB=mydb
volumes:
- postgres_data:/var/lib/postgresql/data
volumes:
postgres_data:
다음 명령으로 모든 서비스를 시작하세요:
docker compose up -d
다음 명령으로 중지하고 제거하세요:
docker compose down
개발을 위한 모범 사례
- .dockerignore 사용: 빌드 컨텍스트에서 불필요한 파일(node_modules, .git)을 제외하세요.
- 레이어 캐싱 활용: 소스 코드를 복사하기 전에 의존성이 설치되도록 Dockerfile 명령 순서를 정하세요.
- 멀티 스테이지 빌드 사용: 프로덕션 이미지를 작게 유지하세요.
- 데이터는 볼륨에 저장: 데이터베이스 및 기타 상태 저장 서비스를 위해 볼륨을 사용하세요.
- 로컬 개발에 Compose 사용: 프로덕션과 유사한 환경을 재현하세요.
자주 묻는 질문
이미지와 컨테이너의 차이점은 무엇인가요?
이미지는 애플리케이션과 그 의존성을 정의하는 읽기 전용 템플릿입니다. 컨테이너는 이미지의 실행 인스턴스로, 그 위에 쓰기 가능한 레이어가 있습니다.
프로덕션에서 Docker Compose를 사용할 수 있나요?
Docker Compose는 주로 개발 및 테스트용으로 설계되었습니다. 프로덕션에서는 Kubernetes나 Docker Swarm과 같은 오케스트레이션 도구를 고려하세요.
Docker에서 데이터를 어떻게 유지하나요?
볼륨이나 바인드 마운트를 사용하세요. 볼륨은 Docker가 관리하며 컨테이너에서 생성된 데이터를 유지하는 데 선호되는 방법입니다.
앱을 컨테이너화할 준비가 되셨나요? 팀을 위해 문서나 가이드를 PDF로 변환해야 한다면, Word to PDF 변환기를 사용해 보세요.