웹 서비스를 개발하고 배포할 때 가장 기본이 되는 것은 정적 파일(HTML, CSS, JS)을 웹 서버에 띄우는 것이다.
Docker를 사용하면 Nginx와 같은 웹 서버를 순식간에 실행할 수 있다.
하지만 보다 확장성 있는 아키텍처를 위해서는 단순히 컨테이너를 띄우는 것에서 나아가, 호스트의 파일을 컨테이너와 연결하고(Bind Mount), 여러 컨테이너가 동일한 데이터를 바라보게 설정(--volumes-from)할 수 있어야 한다.
간단한 포트폴리오 웹사이트 예제를 통해 Docker Volume의 활용법을 알아보자.
1. 실습 환경 준비: 정적 파일 준비
먼저 웹 서버에 띄울 소스 코드가 필요하다.
구글에 "free bootstrap template"을 검색해서 Bootstrap 기반의 간단한 포트폴리오 템플릿을 다운로드한다.
# 상위 디렉토리 이동 및 다운로드 폴더 진입
cd ../../
cd Downloads/
# 파일 확인
ls
# 출력: startbootstrap-stylish-portfolio-gh-pages.zip
# 압축 해제 (-d . 옵션으로 현재 폴더에 해제)
unzip startbootstrap-stylish-portfolio-gh-pages.zip -d .
# 디렉토리 이동 및 파일 확인
cd startbootstrap-stylish-portfolio-gh-pages
ls
# 출력: assets css index.html js
이제 index.html을 포함한 웹 리소스들이 준비되었다. 이 파일들을 Docker 컨테이너 내부가 아닌, 내 로컬 컴퓨터(Host)에 위치시킨 상태에서 웹 서버를 구동해 볼 것이다.
2. 첫 번째 컨테이너 배포: Bind Mount 활용
Nginx 이미지를 이용하여 첫 번째 웹 서버 컨테이너(webserver_1)를 실행한다.
핵심은 -v (Volume) 옵션이다.
# 현재 경로 확인
pwd
# /home/ubuntu/Downloads/startbootstrap-stylish-portfolio-gh-pages
# Docker 컨테이너 실행
docker run -d --name webserver_1 -v $(pwd):/usr/share/nginx/html -p 2010:80 nginx
-v $(pwd):/usr/share/nginx/html: 호스트의 현재 경로($(pwd))를 컨테이너 내부의 /usr/share/nginx/html 디렉토리와 마운트(연결) 한다. 즉, 내 컴퓨터의 파일이 수정되면 컨테이너 내부의 웹 파일도 즉시 변경된다.
실행 확인:
docker ps로 상태가 'Up'인지 확인하고 포트 매핑(2010->80)을 확인한다.
브라우저(Firefox 등)를 열어 http://localhost:2010/에 접속하면 다운받은 샘플 사이트가 정상적으로 보이는 것을 확인할 수 있다.
Bind Mount 매핑 구조
호스트의 파일 시스템이 컨테이너의 특정 경로에 직접 매핑되는 구조다.

웹사이트 구동 시퀀스 다이어그램(Sequence Diagram)

3. 두 번째 컨테이너 배포: --volumes-from 활용
이제 동일한 소스 코드를 보여주는 두 번째 웹 서버(webserver_2)를 띄운다.
이때 다시 -v 옵션으로 긴 경로를 입력하는 대신, 이미 실행 중인 webserver_1 컨테이너의 볼륨 설정을 그대로 가져오는 방식을 사용한다.
# docker run 도움말 확인 (옵션 참고용)
docker run --help | grep volumes-from
# --volumes-from list Mount volumes from the specified container(s)
# 두 번째 컨테이너 실행
docker run -d --name website-nine --volumes-from website-eight -p 2011:80 nginx:latest
- --volumes-from website-eight: webserver_1 컨테이너가 가지고 있는 볼륨 마운트 설정(호스트 경로 <-> 컨테이너 경로)을 그대로 상속받는다.
- -p 2011:80: 포트 충돌을 방지하기 위해 이번에는 호스트의 2011번 포트를 사용한다.
이제 http://localhost:2011/로 접속해도 2010번 포트와 완전히 동일한 웹사이트가 보인다.
Volumes From을 이용한 데이터 공유
두 컨테이너가 호스트의 동일한 원본 데이터를 바라보고 있는 형태가 된다.

4. 볼륨 매핑이 필요한 이유
단순히 웹사이트 두 개를 띄운 것처럼 보이지만, 이 구조에는 서버 아키텍처의 중요한 개념들이 숨어 있다.
1) 무중단 배포와 확장성 (Scalability)
동일한 소스 코드를 바라보는 컨테이너가 2개(webserver_1, webserver_2) 실행되었다.
이는 트래픽이 급증할 경우 컨테이너 webserver_3, webserver_4 등을 계속 추가하여 수평적 확장(Scale-out) 이 가능함을 의미한다.
2) 로드 밸런싱 (Load Balancing)과 라운드 로빈 (Round Robin)
현재는 사용자가 2010, 2011 포트를 직접 입력해서 들어오지만, 실제 운영 환경에서는 이 앞단에 로드 밸런서(Load Balancer) 를 둔다.
- 라운드 로빈(Round Robin): 로드 밸런서가 들어오는 요청을 순서대로 webserver_1 -> webserver_2 -> webserver_3... 순으로 분배한다.
- 이를 통해 하나의 서버에 트래픽이 몰리는 것을 방지한다.
3) 결함 감내 (Fault Tolerance)
만약 webserver_1 컨테이너가 오류로 인해 죽었다고 가정해보자.
단일 서버였다면 서비스 전체가 중단(Downtime)되었을 것이다.
하지만 webserver_2가 살아있으므로 로드 밸런서는 죽은 컨테이너를 감지하고 트래픽을 webserver_2으로만 보내면 된다.
이렇게 되면 사용자는 서비스 중단을 느끼지 못한다.
이것이 시스템이 오류를 견뎌내는 Fault Tolerance이다.
로드 밸런싱 적용 시 아키텍처

지금까지 docker run의 -v 옵션과 --volumes-from 옵션을 사용하여 정적 웹사이트를 배포하고 컨테이너 간에 데이터를 공유하는 방법을 알아보았다.
이러한 컨테이너 구성이 고가용성(High Availability) 웹 서비스를 구축하는 가장 기초적인 블록이 됨을 이해하는 것이 중요하다.
'AI Journey > 클라우드' 카테고리의 다른 글
| [Docker] Dockerfile을 이용해서 이미지 빌드하고 실행하기 (2) - Apache (0) | 2026.01.07 |
|---|---|
| [Docker] Dockerfile을 이용해서 이미지 빌드하고 실행하기 (1) - Nginx (0) | 2026.01.07 |
| [Docker] 바인드 마운트(Bind Mount)를 활용한 데이터 동기화 (3) (0) | 2026.01.06 |
| [Docker] 바인드 마운트(Bind Mount)를 활용한 데이터 동기화 (2) (0) | 2026.01.05 |
| [Kubernetese] 스프링부트(Spring boot) 서버를 파드(Pod)로 띄우기 (0) | 2026.01.03 |