-
쉽게 배우는 도커 스토리지 - PC방 편클라우드 2026. 10. 27. 00:25
들어가며
안녕하세요, 쉽게 배우는 시리즈입니다.
오늘 다룰 내용은 도커 스토리지 입니다.
이번에도 어려운 용어는 잠시 내려놓고, 이런 경험 하나 떠올려 보겠습니다.
PC방에 제가 하고 싶은 게임이 안깔려 있어, 30분 걸려서 직접 설치하고 플레이 했습니다. 다음 날, 다시 까는 수고를 하지 않기 위해 어제 그 자리에 앉았는데… 게임이 없습니다. 결국 또 30분 걸려 재설치하며 PC방 시간을 날렸던 경험이 있습니다.
혹시 이런 경험 있으신가요? 그렇다면 이해가 빠르실 겁니다.
다들 아시다시피 게임이 사라진 이유는 PC방 컴퓨터에 깔린 초기화 프로그램 때문입니다. 컴퓨터를 끄면 사장님이 정해둔 기본 상태로 싹 돌아가죠.
도커 컨테이너도 똑같습니다. 전편에서 봤듯이 컨테이너를 지우면 그 안에서 만든 파일은 모두 사라집니다. 오늘은 이 문제를 어떻게 해결하는지 알아보겠습니다.
PC방으로 보는 도커 스토리지
PC방을 도커에 연결하면 다음과 같습니다.
(약간 억지스러운 것도 있지만 너그럽게 봐주시면 감사하겠습니다.)
PC방 도커 모든 자리에 똑같이 깔린 기본 상태 이미지 내가 앉은 자리의 컴퓨터 컨테이너 컴퓨터를 끄면 초기화 컨테이너를 지우면 데이터 삭제 내가 직접 설치한 게임 컨테이너 안에서 만든 데이터 클라우드에 저장 볼륨 (Volume) 내 USB를 꽂아서 사용 바인드 마운트 (Bind mount) 메모장에 적고 저장 안 하기 tmpfs 마운트 컴퓨터를 끄면 초기화되기 때문에 데이터를 남겨야 하는 건 컴퓨터 안이 아니라 바깥에 두어야 합니다.
이제 실습을 통해 확인해보겠습니다.
게임 대신, 컨테이너에서 가장 잃어버리면 곤란한 데이터인 데이터베이스(MySQL)을 써보겠습니다.
실습1. 어제 깐 게임이 사라지는 문제
먼저 PC방 자리에 앉아보겠습니다. MySQL 컨테이너를 실행합니다.
docker run -d --name pc1 -e MYSQL_ROOT_PASSWORD=1234 -e MYSQL_PWD=1234 mysql:latest이후 데이터베이스를 만들고 Starcraft를 설치합니다.
docker exec pc1 mysql -uroot -p1234 -e "CREATE DATABASE pcbang; \ CREATE TABLE pcbang.games (name VARCHAR(50)); \ INSERT INTO pcbang.games VALUES ('starcraft');"비밀번호를 CLI에 입력하는건 위험하다는 경고가 나오지만 실습이라 괜찮고, 잘 깔린 것을 확인해보겠습니다.
docker exec -e MYSQL_PWD=1234 pc1 mysql -uroot -e "SELECT * FROM pcbang.games;"
이제 PC방 컴퓨터를 끄고, 다음 날 같은 자리에 다시 앉아보겠습니다. 컨테이너를 지우고 같은 이름으로 다시 실행합니다.
docker rm -f pc1 docker run -d --name pc1 -e MYSQL_ROOT_PASSWORD=1234 mysql:latest다시 조회해봅니다.
docker exec pc1 mysql -uroot -p1234 -e "SELECT * FROM pcbang.games;"
다들 예상하셨겠지만, 데이터베이스가 없다고 나옵니다. 자리도 같고(pc1) 이미지(mysql)도 같지만 초기화 프로그램이 돌아간 PC방 컴퓨터 이기 때문입니다.
실습 2. 볼륨: 게임을 클라우드에 저장하기
해결 방법은 게임을 컴퓨터 안이 아닌 바깥 저장소에 두면 됩니다. 도커에서는 이걸 볼륨이라고 부릅니다. 볼륨이 실제로 어디에 저장되는지는 도커가 알아서 관리하니, 우리는 이름만 기억하면 됩니다.
먼저 내 저장 공간을 하나 만듭니다.
docker rm -f pc1 docker volume create my-game이번에는 -v 옵션을 통해 저장 공간을 연결해서 실행합니다.
docker run -d --name pc1 -e MYSQL_ROOT_PASSWORD=1234 \ -v my-game:/var/lib/mysql mysql:latest-v “볼륨이름:컨테이너경로” 형식입니다. 그런데 왜 하필 /var/lib/mysql 일까요?
게임마다 설치 폴더가 정해져 있듯이, MySQL은 데이터를 항상 /var/lib/mysql에 저장하기 때문입니다. 저장 위치는 프로그램이 정하고, 저희는 그 위치에 바깥 저장소를 연결해주는 거라고 보시면 됩니다.
아까처럼 게임을 설치해보겠습니다.
docker exec -e MYSQL_PWD=1234 pc1 mysql -uroot -e "CREATE DATABASE pcbang; \ > CREATE TABLE pcbang.games (name VARCHAR(50)); \ > INSERT INTO pcbang.games VALUES ('starcraft');"이제 컴퓨터를 끄고, 아예 다른 자리(pc2)에 앉고, 같은 저장 공간만 연결합니다.
docker rm -f pc1 docker run -d --name pc2 -e MYSQL_ROOT_PASSWORD=1234 -v my-game:/var/lib/mysql mysql:latest docker exec -e MYSQL_PWD=1234 pc2 mysql -uroot -e "SELECT * FROM pcbang.games;"
게임이 그대로 있습니다. 다시 설치하는 30분이 사라졌습니다. 그렇다면 이 저장 공간은 실제로 어디에 있을까요?
docker volume inspect my-game
MountPoint가 도커가 관리하는 실제 위치입니다.
(Docker Desktop을 쓰신다면 이 경로는 내 컴퓨터가 아니라 도커가 띄운 가상 머신 안에 있습니다.)
평소에는 이 위치를 몰라도 이름만으로 쓸 수 있다는게 볼륨의 장점입니다.
실습3. 바인드 마운트: 내 USB 꽃기
최근에는 클라우드가 발전하여 파일 이동이 편했지만 예전에는 USB를 통해 파일을 이동했습니다. 도커에서는 내 컴퓨터(호스트)의 폴더를 컨테이너에 그대로 꽂는 것을 바인드 마운트라고 합니다.
이번에는 nginx로 해보겠습니다. 먼저 내 컴퓨터에 USB 폴더를 만들고 파일을 하나 넣습니다.
mkdir usb echo '<h1>내 USB에 있는 페이지</h1>' > usb/index.html이 폴더를 nginx가 웹페이지를 읽는 위치인(/usr/share/nginx/html)에 꽂아서 실행합니다.
docker run -d --name web -p 8080:80 \ -v "$(pwd)/usb":/usr/share/nginx/html nginx바인드 마운트는 -v 옵션을 사용하고 내컴퓨터경로:컨테이너경로 로 사용합니다.
(바인드 마운트는 절대 경로로 써야해서 pwd를 통한 절대 위치를 붙였습니다.)
-p 옵션은 포트포워딩(외부 포트:내부 포트)인데 이후 네트워크를 다룰 일이 있다면 설명하도록 하겠습니다.
브라우저에서 localhost:8080에 접속해봅니다.

엄청 깨져서 나오는데 이건 utf-8 설정이 없어서이고, utf8 설정을 추가해주겠습니다.
echo '<meta charset="utf-8"><h1>내 USB에 있는 페이지</h1>' > usb/index.html
그리고 재시작 없이 브라우저를 새로고침 하면 글자가 깨지지 않고 잘 나오는 것을 확인 할 수 있습니다.
✓ 주의할 점 : 바인드 마운트를 하면 원래 파일은 가려집니다.
Nginx 이미지에는 원래 Welcome to Nginx! 기본 페이지가 들어있지만 우리 화면에서는 그 페이지가 보이지 않았습니다.
바인드 마운트를 하게 되면 내 컴퓨터 경로의 파일이 컨테이너의 파일을 덮어씌웁니다. 컨테이너의 파일이 사라진 것은 아닙니다.
추가 학습1. tmpfs: 메모장에 적고 저장 안 하기
반대로 절대 남기면 안되는 것도 있습니다. 내 계정 아이디와 비밀번호 등이 남아있으면 해킹 당해서 예전 메이플로 치면 슬리피우드에 갇혀서 캐삭 해야하는 무시무시한 상황이 벌어질 수 있습니다.
한글 혹은 워드 파일을 떠올려보시면 저장안하고 컴퓨터가 꺼지면 그동안 작업했던 것이 날아가죠? 그게 메모리에 저장되고, 저장 버튼을 통해 디스크에 저장되는 것인데 tmpfs는 메모리에만 저장합니다.
docker run -d --name memo --tmpfs /memo nginx docker exec memo sh -c "echo 비밀 > /memo/secret.txt" docker exec memo cat /memo/secret.txt docker restart memo docker exec memo cat /memo/secret.txt
컨테이너를 지우지 않고 재시작만 해도 사라집니다. 투명 종이(쓰기 레이어)에 쓴 파일은 재시작해도 남지만, tmpfs는 메모리라서 컨테이너가 멈추는 순간 지워집니다.
추가학습 2. 사실 실습 1의 게임은 어딘가 남아있었습니다.
실습 1에서 게임이 사라졌다고 했지만, 사실 완전히 사라진 것은 아닙니다.
볼륨 목록을 확인해보겠습니다.
docker volume ls
만든 기억이 없는 ec076…, f0da30 등의 볼륨들이 보입니다. 이 볼륨들은 어디서 왔을까요? 아까 mysql 이미지의 config를 보겠습니다.
docker image inspect mysql:latest --format '{{.Config.Volumes}}'
MySQL 이미지에는 /var/lib/mysql은 바깥에 저장하라는 설정이 들어있어, -v를 붙이지 않아도 도커가 이름 없는 볼륨(익명 볼륨)을 알아서 만들어 줍니다.
문제는 이름표가 없다는 것입니다. PC방 컴퓨터 어딘가에 내 게임이 들어있긴 한데, 이름이 안 적혀있어서 다음 날 같은 자리에 앉아도 찾아오지 못한 것입니다. 새로 설치된 게임은 또 컴퓨터에 어딘가에 저장되겠죠? 이러면 생기는 문제가 저장공간이 부족해진다는 것입니다.
다음 명령어를 통해 볼륨을 제거할 수 있습니다.
docker rm -v [컨테이너이름] # 컨테이너를 지울 때 익명 볼륨도 같이 삭제 docker volume prune # 아무 컨테이너도 쓰지 않는 익명 볼륨 정리정리
볼륨바인드 마운트
PC방으로 치면 클라우드 저장 내 USB 저장 위치 도커가 관리 내 컴퓨터의 폴더 컨테이너 삭제 후 남음 남음 주로 쓰는 곳 데이터베이스 등 꼭 남길 데이터 개발 중인 코드, 설정 파일 - 컨테이너는 PC방 컴퓨터처럼 지우면 안에서 만든 데이터가 사라집니다.
- 남겨야 하는 데이터는 컨테이너 바깥(볼륨, 바인드 마운트)에 저장합니다.
- 저장 위치는 프로그램이 정하고(MySQL은 /var/lib/mysql), 우리는 그 경로에 바깥 저장소를 연결합니다.
- 이름 없는 볼륨은 쌓이기 쉬우니, 남길 데이터에는 이름을 붙입시다.
그런데 근본적인 해결책이 있습니다. PC방 사장님에게 “이 게임 기본으로 깔아주세요”라고 부탁하는 겁니다. 그러면 어느 자리에 앉든, 몇 번을 껐다 켜든 게임이 처음부터 깔려있습니다.
도커에서는 나만의 이미지를 만들기를 통해 이게 가능합니다.
다음편에서는 Dockerfile로 내가 원하는 프로그램이 기본으로 깔린 이미지를 만들어보겠습니다.
'클라우드' 카테고리의 다른 글
Redis 클러스터 구성 (1) 2025.07.28 Github Actions Self-hosted-runner 사용 방법 (5) 2025.07.12 EC2로 SSH 접속이 되는 원리 (0) 2025.06.30 CloudFront + S3 + ACM + Route53으로 프론트(Vite + React) 정적 파일 배포 하기 (2) 2025.06.14 Infisical CLI 설치하는 파이프라인 최적화 (1) 2025.06.07