실무자를 위한 Docker 핵심 스터디 가이드

데이터 엔지니어 · AI 엔지니어를 위한 핵심 요약

DevOps Infrastructure Container 가이드 v1.0 작성일: 2026.03

1. Docker란?

Docker는 애플리케이션을 컨테이너라는 표준화된 단위로 패키징하고 실행하기 위한 오픈 소스 플랫폼입니다. 컨테이너는 코드, 런타임, 시스템 도구, 시스템 라이브러리 등 소프트웨어 실행에 필요한 모든 것을 포함하는 경량화된 실행 환경입니다.

📦 표준화된 패키징

"어디서나 동일하게 실행"을 보장합니다. 개발, 스테이징, 프로덕션 환경 간의 차이로 인한 문제("내 로컬에서는 되는데...")를 해결합니다.

⚡ 경량화 & 고밀도

가상 머신(VM)과 달리 게스트 OS를 포함하지 않아 훨씬 가볍고 빠르게 시작됩니다. 호스트 머신의 자원을 효율적으로 활용할 수 있습니다.

🔁 생명주기 관리

빌드, 배포, 실행, 모니터링, 로깅까지 컨테이너의 전 생명주기를 관리하는 도구와 생태계를 제공합니다.

2. 왜 써야 하는가? (기존 대안과 비교)

방식 장점 단점 Docker의 차별점
베어메탈 / 직접 설치 최대 성능, 완전한 제어 환경 구성 복잡, 확장/이전 어려움, 의존성 지옥 환경 구성의 코드화, 빠른 배포와 롤백
전통적 가상머신(VM) 강한 격리, 완전한 OS 제어 무거움(GB 단위), 느린 시작, 오버헤드 큼 경량(MB 단위), 빠른 시작/중지, 높은 밀도
클라우드 PaaS 관리 부담 감소, 빠른 출시 벤더 종속, 제어권 제한, 비용 증가 가능성 멀티 클라우드/하이브리드 호환성, 환경 일관성
💡 핵심 가치: Docker는 "환경의 불일치"라는 근본적인 문제를 해결하여 개발부터 운영까지의 흐름(DevOps)을 가속화합니다.

3. 핵심 개념

Docker는 클라이언트-서버 아키텍처로 동작합니다. 주요 구성 요소와 흐름을 이해해야 합니다.

+-----------------------------------------------------------------------+ | Docker Client (CLI) | | `docker build` `docker run` `docker ps` | +--------------------------|--------------------------------------------+ | (REST API / Socket) +--------------------------v--------------------------------------------+ | Docker Daemon (dockerd) | | - 이미지 관리 | | - 컨테이너 실행/관리 | | - 네트워크/볼륨 관리 | +-------------------|------------------------|---------------------------+ | | +-------v--------+ +--------v-------+ | 이미지 레이어 | | 컨테이너 레이어 | | (읽기 전용) | | (쓰기 가능) | | - Ubuntu Layer | | - App Data | | - Python Layer | | - Temp Files | | - App Code Layer| +----------------+ +-----------------+ | +-------v--------+ | 레지스트리 | | (Docker Hub, | | Private Registry)| +-----------------+

이미지 (Image)

컨테이너를 생성하기 위한 읽기 전용 템플릿. 여러 개의 레이어로 구성되며, Dockerfile로 빌드됩니다.

ubuntu:22.04, python:3.11-slim

컨테이너 (Container)

이미지를 실행한 상태. 쓰기 가능한 레이어가 추가되어 생성되며, 격리된 프로세스로 동작합니다.

docker run -it python:3.11 bash

Dockerfile

이미지를 빌드하기 위한 단계별 명령어 스크립트. 재현 가능한 빌드를 정의합니다.

볼륨 (Volume)

컨테이너의 데이터를 호스트에 유지하는 메커니즘. 컨테이너 삭제 후에도 데이터 보존.

4. 퀵스타트: 설치 → 설정 → 첫 예제

Step 1: 설치 (Ubuntu 기준)

CLI: Docker Engine 설치
# 기존 패키지 제거 (선택사항)
sudo apt-get remove docker docker-engine docker.io containerd runc

# 저장소 설정 및 패키지 설치
sudo apt-get update
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# Docker 공식 GPG 키 추가
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 저장소 설정
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# Docker Engine 설치
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 현재 사용자를 docker 그룹에 추가 (sudo 없이 실행)
sudo usermod -aG docker $USER
# **로그아웃 후 재로그인 필요**

Step 2: 기본 설정 확인

CLI: 설치 및 데몬 확인
# Docker 데몬 상태 확인
sudo systemctl status docker

# Docker 데몬 시작 및 부팅 시 자동 실행 설정
sudo systemctl start docker
sudo systemctl enable docker

# 간단한 테스트: Hello World 컨테이너 실행
docker run hello-world

Step 3: 첫 번째 Python 애플리케이션 컨테이너화

간단한 Flask 앱을 Dockerize 해봅니다.

app.py
from flask import Flask
import os
app = Flask(__name__)

@app.route('/')
def hello():
    hostname = os.environ.get('HOSTNAME', 'unknown')
    return f"Hello from Docker Container! Hostname: {hostname}"

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
Dockerfile
# 베이스 이미지 선택 (경량 Python)
FROM python:3.11-slim

# 작업 디렉토리 설정
WORKDIR /app

# 의존성 파일 복사 및 설치
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 애플리케이션 소스 복사
COPY app.py .

# 환경 변수 설정 (선택)
ENV HOSTNAME=my-first-container

# 컨테이너가 사용할 포트 노출
EXPOSE 5000

# 컨테이너 실행 시 실행할 명령
CMD ["python", "app.py"]
CLI: 빌드 및 실행
# requirements.txt 생성
echo "Flask==3.0.0" > requirements.txt

# Docker 이미지 빌드 (태그 지정)
docker build -t my-python-app:1.0 .

# 빌드된 이미지 확인
docker images

# 컨테이너 실행 (포트 매핑, 백그라운드 실행)
docker run -d -p 8080:5000 --name my-app my-python-app:1.0

# 실행 중인 컨테이너 확인
docker ps

# 로그 확인
docker logs my-app

# 브라우저에서 http://localhost:8080 접속 테스트

# 컨테이너 중지 및 삭제
docker stop my-app
docker rm my-app

5. 핵심 설정 레퍼런스 (Dockerfile & docker run)

구분 지시어 / 옵션 설명 예시
Dockerfile FROM 베이스 이미지 지정 FROM ubuntu:22.04
COPY / ADD 파일 복사 (ADD는 URL/압축 해제 추가) COPY ./src /app
RUN 이미지 빌드 중 명령 실행 RUN apt-get update && apt-get install -y python3
ENV 환경 변수 설정 ENV PYTHONUNBUFFERED=1
EXPOSE 사용 포트 정보 제공 (실제 개방X) EXPOSE 8080
CMD / ENTRYPOINT 컨테이너 기본 실행 명령 CMD ["python", "app.py"]
docker run -d 데몬 모드 (백그라운드 실행) docker run -d nginx
-p 포트 매핑 (호스트:컨테이너) -p 80:8080
-v 볼륨 마운트 (호스트:컨테이너) -v /data:/app/data
--env / -e 환경 변수 설정 -e DB_HOST=localhost
--name 컨테이너 이름 지정 --name my-nginx
--restart 재시작 정책 (always, unless-stopped) --restart unless-stopped

6. 실무 팁 & 트러블슈팅

✅ 팁 1: 캐시를 활용한 효율적인 빌드

Dockerfile에서 자주 변경되지 않는 부분(의존성 설치)을 앞쪽에, 자주 변경되는 부분(소스코드 복사)을 뒤쪽에 배치하여 빌드 캐시를 최대한 활용하세요.

# 좋은 예: 패키지 설치가 먼저
COPY requirements.txt .
RUN pip install -r requirements.txt # 캐시 활용
COPY app.py .                       # 변경 시 여기부터 재빌드
✅ 팁 2: .dockerignore 필수 사용

불필요한 파일(로그, 가상환경, 빌드 캐시, .git)이 이미지에 포함되는 것을 방지하여 이미지 크기를 줄이고 보안을 강화합니다.

# .dockerignore 예시
.git
__pycache__
*.log
.env
Dockerfile
README.md
venv/
*.pyc
🚨 문제 1: 컨테이너는 실행 후 바로 종료됩니다.

원인: 컨테이너 내부의 메인 프로세스가 종료되었기 때문입니다. (예: 단순히 echo "hello"를 실행하는 경우)

해결: 장기 실행 프로세스(웹 서버, 데이터베이스)를 포그라운드에서 실행하거나, tail -f /dev/null과 같은 명령으로 프로세스를 유지합니다.

# 잘못된 예: 바로 종료
docker run ubuntu echo "hello"

# 해결 1: 인터랙티브 모드로 쉘 유지
docker run -it ubuntu bash

# 해결 2: 웹 서버 실행 (메인 프로세스가 지속됨)
docker run -d -p 80:80 nginx
🚨 문제 2: 호스트의 파일 시스템 권한 문제

원인: 호스트에서 마운트된 볼륨 내 파일의 소유자/권한이 컨테이너 내부의 사용자(보통 root가 아닌 UID 1000 등)와 맞지 않을 때 발생합니다.

해결: Dockerfile에서 적절한 사용자 생성 및 전환을 하거나, 호스트와 컨테이너의 UID/GID를 맞춥니다.

# Dockerfile 내에서
RUN groupadd -r appuser && useradd -r -g appuser appuser
USER appuser
WORKDIR /home/appuser
# 이후 COPY/RUN 명령은 appuser 권한으로 실행
🔍 디버깅 명령어 모음
# 실행 중인 컨테이너 내부 쉘 접근
docker exec -it [container_name] /bin/bash

# 컨테이너 로그 실시간 확인
docker logs -f [container_name]

# 컨테이너 상세 정보 (IP, 마운트, 네트워크 등)
docker inspect [container_name]

# 시스템 자원 사용량 확인
docker stats

# 사용하지 않는 이미지, 컨테이너, 볼륨 일괄 정리
docker system prune -a --volumes

7. 참고 자료