한양과학기술고등학교

에듀테크 프로젝트 대시보드

컨테이너 & Docker 기초

🐳 컨테이너 & Docker 기초

컨테이너는 애플리케이션 + 실행에 필요한 모든 것(라이브러리·설정)을 하나로 묶어, 어느 컴퓨터에서든 똑같이 실행되게 만드는 기술이다. "내 컴퓨터에선 되는데요?" 문제를 없앤다. 이 서버의 FastAPI 앱들처럼 venv로 격리할 수도 있지만, 컨테이너는 OS 수준에서 훨씬 더 완전하게 격리한다.

가상 머신(VM) vs 컨테이너

VM은 하드웨어를 통째로 흉내 내서 그 위에 게스트 OS 전체를 올린다(무겁고 느린 부팅). 컨테이너는 호스트의 커널을 공유하고 프로세스만 격리한다(가볍고 즉시 실행).

🖥️ 가상 머신

App A
App B
App C
Guest OS
Guest OS
Guest OS
Hypervisor
Host OS
물리 하드웨어 (CPU·RAM·디스크)
게스트 OS가 앱마다 통째로 복제됨 → 수 GB, 부팅 수십 초

🐳 컨테이너

App A
App B
App C
컨테이너 런타임 (Docker Engine)
Host OS — 커널 공유
물리 하드웨어 (CPU·RAM·디스크)
커널을 공유하므로 앱당 수 MB, 시작 수 밀리초

이미지는 "레이어"로 쌓인다 — 빌드 캐시 체험

Dockerfile의 명령 한 줄 = 이미지 레이어 하나(읽기 전용). Docker는 위에서부터 명령을 실행하다가 바뀐 줄을 만나면 그 줄부터 아래를 전부 다시 빌드하고, 그 위는 캐시를 재사용한다. 그래서 자주 바뀌는 것(소스 코드 COPY)은 아래쪽에 둔다.

Dockerfile 줄을 클릭 → "수정됨" 표시
FROM python:3.12-slim~120 MB
두 번째 빌드부터 캐시가 동작합니다
$ 빌드를 실행해 보세요…

이미지 vs 컨테이너

이미지는 붕어빵 틀(읽기 전용 레이어의 묶음), 컨테이너는 그 틀로 찍어낸 붕어빵 (이미지 + 맨 위에 얇은 쓰기 가능 레이어 1장). 같은 이미지로 컨테이너 여러 개를 띄워도 아래 레이어는 공유되므로 디스크가 적게 든다.

이미지 (읽기 전용)

CMD gunicorn ...
COPY . /app
RUN pip install ...
FROM python:3.12-slim

컨테이너 #1

쓰기 레이어 (로그·임시파일)
CMD gunicorn ...
COPY . /app
RUN pip install ...
FROM python:3.12-slim

컨테이너 #2

쓰기 레이어 (각자 독립)
↓ 아래 레이어는
이미지와
공유됨 (복사 X)

리눅스 커널이 격리를 만든다

컨테이너는 마법이 아니라 리눅스 커널 기능 3가지의 조합이다.

Namespace

프로세스가 볼 수 있는 범위를 분리. 컨테이너 안에서 ps를 치면 자기 프로세스만, ip addr를 치면 자기 네트워크만 보인다. (PID·NET·MNT·UTS·IPC·USER)

cgroups

프로세스가 쓸 수 있는 자원을 제한. --memory=512m --cpus=1.5 처럼 CPU·메모리·디스크 I/O 상한을 건다. 한 컨테이너가 서버를 독차지하지 못하게 막는다.

Union FS (OverlayFS)

여러 읽기 전용 레이어 + 쓰기 레이어 1장을 겹쳐 하나의 파일 시스템처럼 보이게 한다. 레이어 공유와 빌드 캐시가 여기서 나온다.

Capabilities / seccomp

컨테이너 안 root라도 호스트에서 위험한 시스템 콜은 차단한다. 그래서 컨테이너 root는 진짜 root보다 권한이 훨씬 약하다.

자주 쓰는 명령어

명령설명
docker build -t myapp .현재 폴더의 Dockerfile로 myapp 이미지 빌드
docker run -d -p 8001:8001 myapp이미지를 컨테이너로 실행. -d 백그라운드, -p 호스트:컨테이너 포트 연결
docker ps / docker ps -a실행 중 / 전체(멈춘 것 포함) 컨테이너 목록
docker images로컬 이미지 목록
docker exec -it <id> bash실행 중인 컨테이너 안으로 셸 접속
docker logs -f <id>컨테이너 표준출력 로그 실시간 확인
docker stop / rm <id>컨테이너 정지 / 삭제
docker compose up -d여러 컨테이너(앱+DB 등)를 compose.yml 하나로 함께 실행
이 서버라면? 지금은 앱마다 venv + systemd + nginx로 운영 중이다. 컨테이너로 옮기면 각 FastAPI 앱을 이미지로 굳혀서 docker compose 한 줄로 4개를 동시에 띄우고, Python 버전이나 시스템 라이브러리가 앱마다 충돌할 걱정이 사라진다. 대신 이미지 빌드·레지스트리·볼륨(DB 파일 영속화) 관리라는 새로운 학습 비용이 생긴다.