Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Docker

이 책의 실습은 대부분 컨테이너 위에서 이루어집니다. 파이토치 노트북을 띄우는 pydeep 이미지부터 Ollama, vLLM, Open WebUI 같은 서비스까지, 실행 환경 전체를 컨테이너로 다룹니다. 이 장은 그 바탕이 되는 Docker의 핵심 개념과 명령을 정리합니다.

설치 방법은 딥러닝 환경 설정에서 이미 다루므로, 여기서는 컨테이너를 이해하고 운용하는 데 필요한 개념에 집중합니다.

1왜 Docker인가

딥러닝 실습은 CUDA 버전, 파이썬 패키지, 시스템 라이브러리가 촘촘히 얽혀 있어, “내 컴퓨터에서는 되는데” 식의 환경 차이가 잦습니다. Docker는 애플리케이션과 그 실행에 필요한 모든 것(라이브러리·설정·런타임)을 하나의 이미지로 묶어, 어느 컴퓨터에서든 동일하게 재현합니다.

2이미지와 컨테이너

이미지(Image) 는 실행 환경의 정지된 설계도이고, 컨테이너(Container) 는 그 이미지를 실제로 실행한 인스턴스입니다. 하나의 이미지로 여러 컨테이너를 띄울 수 있으며, 이미지는 변경분을 쌓아 올린 레이어(Layer) 의 집합이라 공통 레이어는 이미지 간에 공유되어 저장 공간을 아낍니다. 이미지는 레지스트리(Registry), 즉 Docker Hub 같은 저장소에서 배포됩니다.

설치된 Docker 버전은 다음과 같이 확인합니다.

docker --version
Docker 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 ps
NAMES                 IMAGE                    STATUS          PORTS
pydeep                codebasic/pydeep:26.04   Up 6 hours      0.0.0.0:8888->8888/tcp

내려받은 이미지는 docker images로 확인합니다.

docker images
REPOSITORY:TAG            SIZE
codebasic/pydeep:26.04    20.9GB
ollama/ollama:0.24.0      6.55GB

3데이터 영속화: 볼륨

컨테이너는 일시적입니다. 삭제하면 그 안에서 만든 파일도 함께 사라집니다. 모델 가중치나 캐시처럼 보존해야 하는 데이터는 볼륨(Volume) 으로 컨테이너 바깥에 저장합니다.

볼륨은 두 가지 방식으로 연결합니다.

-v <호스트 또는 볼륨이름>:<컨테이너 경로> 형식에서, 슬래시로 시작하는 경로는 바인드 마운트, 이름만 쓰면 명명 볼륨입니다. 명명 볼륨은 다음과 같이 확인합니다.

docker volume ls
DRIVER    VOLUME NAME
local     openwebui_data

4네트워킹

컨테이너는 격리된 자체 네트워크에서 동작하므로, 컨테이너 안의 서비스에 접근하려면 포트를 호스트로 공개(publish) 해야 합니다. -p <호스트 포트>:<컨테이너 포트> 형식으로 매핑합니다.

docker run -p 8888:8888 codebasic/pydeep:26.04

위 설정에서 호스트의 localhost:8888로 접속하면 컨테이너 내부 8888 포트로 전달됩니다.

격리 때문에 흔히 겪는 함정이 컨테이너에서 호스트로의 접근입니다. 컨테이너 안에서 localhost는 호스트가 아니라 컨테이너 자신을 가리킵니다. 호스트에서 도는 서비스(예: 호스트의 Ollama)에 접근하려면 다음을 씁니다.

docker run --add-host=host.docker.internal:host-gateway ...

이 주제는 Ollama REST APIOpen 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의 각 옵션이 그대로 키로 대응합니다.

정의한 서비스는 다음 명령으로 운용합니다.

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만으로 충분하므로, 이미지 빌드는 직접 서비스를 패키징할 때만 필요합니다.