Docker
도커(Docker)
컨테이너(Container) 기반 가상화 기술을 활용하여 애플리케이션을 실행하고 관리하는 플랫폼
애플리케이션과 해당 애플리케이션 실행에 필요한 모든 요소(코드 라이브러리, 환경설정, 의존성, 정절 파일 등)를 패키징하여, 이식성과 재현성 보장
- Container
애플리케이션과 필요한 모든 환경(서버 엔진, 애플리케이션, 정적 파일, 환경 설정, 의존성, OS)을 포함한 독립적인 실행 단위
가볍고 빠르게 배포 가능 - Container Engine (Docker Engine)
컨테이너를 실행하고 관리하는 역할을 수행하는 프로그램
Docker가 대표적인 컨테이너 엔진 - Infrastructure
컨테이너를 실행하는 물리적인 리소스(Memory, CPU, Disk 등) - Host OS
컨테이너를 실행하는 운영체제 (예 : macOS, Linux, Windows) - 커널(Kernel)
하드웨어와 소프트웨어를 연결하는 핵심 요소
Docker 컨테이너는 호스트 OS의 커널을 공유하며 동작
→ 가상화 기술: 하드웨어 가상화가 아닌 운영체제 수준의 가상화
→ 이식성: “한번 빌드하면 어디서든 실행 가능”이라는 장점을 제공
Docker의 주요 구성 요소
- Dockerfile
도커 이미지의 설정 파일
컨테이너 실행에 필요한 애플리케이션, 라이브러리, 의존성 등을 정의 - Image
애플리케이션 실행에 필요한 모든 것을 포함한 읽기 전용 템플릿
이미지는 Dockerfile로 정의되며, 컨테이너의 기반이 됨 - Container
이미지를 실행 가능한 상태로 만든 것
애플리케이션이 실제로 실행되는 환경
도커파일(Dockerfile)
도커 이미지를 생성하기 위한 스크립트 파일, Dockerfile을 기반으로 컨테이너를 빌드
특정 애플리케이션 환경을 정의하기 위한 명령어들을 포함
빌드 과정 자동화
도커파일의 구조
• FROM: 베이스 이미지 지정 (예: FROM python:3.10-slim)
• RUN: 쉘 명령어 실행 (예: RUN apt-get update && apt-get install -y ...)
• COPY 또는 ADD: 파일 복사
• CMD 또는 ENTRYPOINT: 컨테이너 시작 시 실행할 명령어 지정
# Python 베이스 이미지 선택
FROM python:3.10-slim
RUN apt-get update && apt-get install -y --no-install-recommends \
gcc \
build-essential \
libffi-dev \
libssl-dev \
zlib1g-dev \
python3-dev \
&& rm -rf /var/lib/apt/lists/*
# 작업 디렉토리 설정
WORKDIR /app
# 의존성 파일 복사 및 설치
COPY requirements.txt /app/
RUN pip install --no-cache-dir -r requirements.txt
# --no-cache-dir 캐시 파일을 사용하지 않도록 설정, 이미지 크기를 줄임
# requirements.txt파일에 명시된 패키지를 한 번에 설치
# 애플리케이션 파일 복사
COPY . /app
# 애플리케이션 실행 명령어
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Dockerfile은 위에서 아래로 실행되며, 각 명령어는 새로운 Layer를 형성
- 베이스 이미지 선택 → FROM
- 작업 디렉토리 설정 →WORKDIR
- 의존성 파일 복사 및 설치 → COPY & RUN
- 애플리케이션 파일 복사 → COPY
- 컨테이너 실행 시 실행할 명령어 지정 → CMD
*기타 주요 명령어
ADD : 로컬 파일을 컨테이너 이미지 내부로 복사
ENTRYPOINT : CMD와 비슷하지만, 매개변수 추가 가능 (컨테이너 실행 시 기본적으로 실행할 명령어)
ENV : 환경 변수 설정
EXPOSE : 컨테이너가 사용할 네트워크 포트를 정의
VOLUME : 데이터를 컨테이너 외부와 공유하도록 볼륨 설정
LABEL : 이미지에 메타데이터를 추가
* CMD vs. ENTRIPOINT vs. RUN
명령어 | 실행 시점 | 용도 |
RUN | 이미지 빌드 시 | 패키지 설치, 환경 설정 |
CMD | 컨테이너 실행 시 | 기본 실행 명령 지정 (재정의 가능) |
ENTRYPOINT | 컨테이너 실행 시 | 필수 실행 명령 (인자 추가 가능) |
Docker Layer 구조
BASE Layer (기본 레이어)
- FROM으로 지정된 베이스 이미지가 포함됨 (예 : python:3.10-slim)
- 변하지 않는 OS 및 런타임 환경 (예 : Python, Node.js 등)
- 변경될 가능성이 적으므로 하단에 위치
중간 레이어
- RUN, WORKDIR, ENV 등의 명령어로 생성됨
- 애플리케이션 실행에 필요한 패키지 및 의존성 설치
상위 레이어 (자주 변경되는 부분)
- COPY 또는 ADD로 복사한 애플리케이션 코드, 설정 파일
- 코드가 자주 바뀌므로 최대한 마지막 단계에서 추가하는 것이 캐싱 최적화에 유리
*Docker의 Layer 캐싱 원리
- Docker는 Dockerfile의 각 명령어를 실행할 때 레이어를 생성
- 이전 단계(FROM, RUN, COPY 등)가 변경되지 않으면 캐싱된 레이어를 재사용
- 어느 한 단계가 변경되면 그 이후 모든 단계 재빌드
→ 변하지 않는 파일을 먼저 배치, 자주 바뀌는 파일을 나중에 배치하는 것이 효율적
디렉토리 구조
project/
├── Dockerfile # 도커파일
├── app.py # 애플리케이션 소스 코드
├── requirements.txt # Python 의존성 파일
└── static/ # 정적 파일
*Dockerfile 작성 시 주의사항
이미지 경량화
- 불필요한 패키지 설치 지양
- 경량화된 베이스 이미지 사용
캐시 최적화
- Dockerfile의 명령어 순서를 최적화하여 빌드 캐시를 효율적으로 사용
환경 변수 설정
- 중요한 정보를 ENV 또는 ARG로 설정하고, 하드코딩 지양
포트 설정
- 컨테이너에서 사용할 포트를 명시적으로 EXPOSE로 지정
도커컴포즈(Docker Compose)
여러 컨테이너를 정의하고 함께 실행하기 위한 도구
• 복잡한 애플리케이션(여러 컨테이너 필요)을 쉽게 관리
• 하나의 docker-compose.yml 파일로 여러 컨테이너를 정의
예시 파일 (docker-compose.yml)
version: '3.8'
services:
web:
build: .
ports:
- "5000:5000"
volumes:
- .:/code
environment:
- FLASK_ENV=development
redis:
image: "redis:alpine"
• services: 컨테이너 목록 정의
• web, redis: 각각의 컨테이너 이름
• build: 도커파일 경로
• ports: 호스트와 컨테이너 간 포트 매핑
• volumes: 파일 공유
• docker-compose up: 컨테이너 시작
• docker-compose down: 컨테이너 정리
도커허브(Docker Hub)
도커 이미지를 공유할 수 있는 온라인 저장소 플랫폼
• 도커 이미지를 업로드, 공유
• 인기 있는 베이스 이미지들이 제공됨 (예: nginx, node, python 등)
• docker pull <이미지 이름>: 이미지 다운로드
• docker push <이미지 이름>: 이미지 업로드
• docker login: 허브에 로그인
사용 예시
• docker pull python:3.10
Python 3.10 이미지 다운로드
• docker push myapp:latest
myapp 이미지를 도커허브에 업로드