Docker
이 책의 실습은 대부분 컨테이너 위에서 이루어집니다. 파이토치 노트북을 띄우는 pydeep 이미지부터 Ollama, vLLM, Open WebUI 같은 서비스까지, 실행 환경 전체를 컨테이너로 다룹니다. 이 장은 그 바탕이 되는 Docker의 핵심 개념과 명령을 정리합니다.
설치 방법은 딥러닝 환경 설정에서 이미 다루므로, 여기서는 컨테이너를 이해하고 운용하는 데 필요한 개념에 집중합니다.
1왜 Docker인가¶
딥러닝 실습은 CUDA 버전, 파이썬 패키지, 시스템 라이브러리가 촘촘히 얽혀 있어, “내 컴퓨터에서는 되는데” 식의 환경 차이가 잦습니다. Docker는 애플리케이션과 그 실행에 필요한 모든 것(라이브러리·설정·런타임)을 하나의 이미지로 묶어, 어느 컴퓨터에서든 동일하게 재현합니다.
재현성: 같은 이미지는 어디서 실행해도 같은 환경을 보장하므로, 책의 실습 결과를 그대로 따라 할 수 있습니다.
격리: 컨테이너는 호스트 시스템과 분리되어 동작하므로, 실습 환경이 호스트의 파이썬이나 라이브러리를 오염시키지 않습니다.
이식성: 이미지를 레지스트리에서 내려받아 곧바로 실행하므로, 복잡한 설치 과정을 건너뜁니다.
2이미지와 컨테이너¶
이미지(Image) 는 실행 환경의 정지된 설계도이고, 컨테이너(Container) 는 그 이미지를 실제로 실행한 인스턴스입니다. 하나의 이미지로 여러 컨테이너를 띄울 수 있으며, 이미지는 변경분을 쌓아 올린 레이어(Layer) 의 집합이라 공통 레이어는 이미지 간에 공유되어 저장 공간을 아낍니다. 이미지는 레지스트리(Registry), 즉 Docker Hub 같은 저장소에서 배포됩니다.
설치된 Docker 버전은 다음과 같이 확인합니다.
docker --versionDocker version 29.1.3, build 29.1.3-0ubuntu3~22.04.2이미지를 내려받아(pull) 컨테이너로 실행(run)합니다.
다음은 책의 실습 이미지를 GPU와 함께 실행하는 예입니다(-p·--gpus는 뒤에서 설명합니다).
docker run --name pydeep -p 8888:8888 --gpus all -it codebasic/pydeep:26.04자주 쓰는 명령은 다음과 같습니다.
| 명령 | 설명 |
|---|---|
docker images | 내려받은 이미지 목록 |
docker pull <이미지> | 레지스트리에서 이미지 내려받기 |
docker ps / docker ps -a | 실행 중인 / 모든 컨테이너 목록 |
docker logs <컨테이너> | 컨테이너 로그 확인 |
docker exec -it <컨테이너> bash | 실행 중인 컨테이너 안에서 셸 열기 |
docker stop / docker rm <컨테이너> | 컨테이너 중지 / 삭제 |
실행 중인 컨테이너는 docker ps로 확인합니다.
docker psNAMES IMAGE STATUS PORTS
pydeep codebasic/pydeep:26.04 Up 6 hours 0.0.0.0:8888->8888/tcp내려받은 이미지는 docker images로 확인합니다.
docker imagesREPOSITORY:TAG SIZE
codebasic/pydeep:26.04 20.9GB
ollama/ollama:0.24.0 6.55GB3데이터 영속화: 볼륨¶
컨테이너는 일시적입니다. 삭제하면 그 안에서 만든 파일도 함께 사라집니다. 모델 가중치나 캐시처럼 보존해야 하는 데이터는 볼륨(Volume) 으로 컨테이너 바깥에 저장합니다.
볼륨은 두 가지 방식으로 연결합니다.
바인드 마운트(Bind Mount): 호스트의 특정 경로를 컨테이너에 직접 연결합니다. 경로를 눈으로 확인·편집해야 할 때 유용합니다.
docker run -v ~/.cache/huggingface:/home/me/.cache/huggingface codebasic/pydeep:26.04명명 볼륨(Named Volume): Docker가 관리하는 저장소에 이름을 붙여 사용합니다. 호스트 경로에 얽매이지 않아 이식성이 높습니다.
docker run -v openwebui_data:/app/backend/data ghcr.io/open-webui/open-webui:0.8-slim
-v <호스트 또는 볼륨이름>:<컨테이너 경로> 형식에서, 슬래시로 시작하는 경로는 바인드 마운트, 이름만 쓰면 명명 볼륨입니다.
명명 볼륨은 다음과 같이 확인합니다.
docker volume lsDRIVER VOLUME NAME
local openwebui_data4네트워킹¶
컨테이너는 격리된 자체 네트워크에서 동작하므로, 컨테이너 안의 서비스에 접근하려면 포트를 호스트로 공개(publish) 해야 합니다.
-p <호스트 포트>:<컨테이너 포트> 형식으로 매핑합니다.
docker run -p 8888:8888 codebasic/pydeep:26.04위 설정에서 호스트의 localhost:8888로 접속하면 컨테이너 내부 8888 포트로 전달됩니다.
격리 때문에 흔히 겪는 함정이 컨테이너에서 호스트로의 접근입니다.
컨테이너 안에서 localhost는 호스트가 아니라 컨테이너 자신을 가리킵니다.
호스트에서 도는 서비스(예: 호스트의 Ollama)에 접근하려면 다음을 씁니다.
Docker Desktop(Windows·macOS):
host.docker.internal호스트 이름으로 접근합니다.Docker Engine(Linux): 실행 시
--add-host=host.docker.internal:host-gateway를 더해 같은 이름을 활성화합니다.
docker run --add-host=host.docker.internal:host-gateway ...이 주제는 Ollama REST API와 Open WebUI의 서비스 연결에서 다시 다룹니다.
5GPU 가속¶
컨테이너에서 NVIDIA GPU를 사용하려면 호스트에 GPU 드라이버와 컨테이너 런타임 연동(NVIDIA Container Toolkit)이 갖춰져 있어야 하며, 실행 시 --gpus 플래그로 GPU를 컨테이너에 노출합니다.
docker run --gpus all codebasic/pydeep:26.04--gpus all은 모든 GPU를, --gpus '"device=0"'처럼 지정하면 특정 GPU만 노출합니다.
GPU 가속의 바탕이 되는 CUDA와 드라이버 준비는 환경 설정을 참조합니다.
6Docker Compose¶
서비스 하나를 띄우는 데에도 이미지·포트·볼륨·GPU 옵션이 줄줄이 붙습니다.
긴 docker run 명령을 매번 입력하는 대신, Docker Compose 는 이 설정을 compose.yaml 파일 하나에 선언적으로 모아 둡니다.
다음은 이 책의 Ollama 서비스 정의(docker/compose.ollama.yaml)입니다.
services:
ollama:
image: ollama/ollama:0.24.0
container_name: ollama
ports:
- "11434:11434"
volumes:
- ${USERPROFILE}/.ollama:/root/.ollama
gpus: all
restart: unless-stopped
volumes:
ollama:
external: true앞서 본 docker run의 각 옵션이 그대로 키로 대응합니다.
image— 사용할 이미지(docker run의 이미지 인자).ports— 포트 매핑(-p 11434:11434).volumes— 데이터 영속화(-v). 여기서는 호스트의.ollama디렉터리(${USERPROFILE}은 Windows 사용자 홈)를 바인드 마운트해 내려받은 모델을 보존합니다.gpus: all— GPU 노출(--gpus all).restart: unless-stopped— 호스트 재부팅이나 오류 종료 시 컨테이너를 자동 재시작합니다.
정의한 서비스는 다음 명령으로 운용합니다.
docker compose -f docker/compose.ollama.yaml up -d # 백그라운드로 시작
docker compose -f docker/compose.ollama.yaml logs -f # 로그 확인
docker compose -f docker/compose.ollama.yaml down # 중지 및 정리up -d는 이미지 내려받기부터 컨테이너 생성·실행까지 한 번에 처리하고, down은 컨테이너와 네트워크를 정리합니다(명명 볼륨의 데이터는 남습니다).
7이미지 빌드: Dockerfile¶
공개 이미지로 충분하지 않고 직접 환경을 꾸려야 할 때는 Dockerfile 로 이미지를 빌드합니다.
Dockerfile은 베이스 이미지에서 시작해 패키지 설치·파일 복사·실행 명령을 한 줄씩 쌓아 올린 빌드 명세입니다.
이 책에서는 Qwen3 TTS 서버를 컨테이너로 묶을 때 docker/qwen-tts/Dockerfile에서 이 방식을 사용합니다.
docker build -t qwen-tts docker/qwen-tts대부분의 실습은 공개 이미지와 Compose만으로 충분하므로, 이미지 빌드는 직접 서비스를 패키징할 때만 필요합니다.