본문 바로가기
IT Study/Docker

[Docker] 로컬과 컨테이너 마운트 시키기 (Volume)

by 하람 Haram 2026. 2. 25.
728x90

매번 Container에 접속해서 수정하고 하기엔 귀찮기 때문에

로컬과 컨테이너를 Mount 시켜서 관리하는 것이 편하다

 

근데, 처음할 때는 Trial이 너무 많았어서 방법을 그냥 정리해놓으려고 한다

 

가장 먼저 헷갈려 하는 것이 Volume과 Mount 이다

 

Volume (볼륨)

- Docker가 직접 관리하는 저장 공간
- docker volume create로 만들거나, -v volume_name:/path로 자동 생성
- 호스트의 실제 경로를 신경 쓸 필요 없이 Docker가 내부적으로 /var/lib/docker/volumes/... 아래에 저장
- 데이터를 컨테이너와 분리해서 보존할 때 유용. (컨테이너 삭제해도 데이터 유지)

docker run -v mydata:/app/data myimage

 

Bind Mount (바인드 마운트)

호스트의 특정 경로를 직접 연결하는 방식이에요.
-v /home/user/project:/app 또는 --mount type=bind,source=/home/user/project,target=/app 형태로 사용
호스트 파일이 그대로 반영되므로, 개발 중 코드 수정이 바로 컨테이너에 반영
하지만 호스트 경로가 바뀌거나 삭제되면 컨테이너도 영향을 받음

docker run -v /home/user/project:/app myimage

 

요약하자면
Step 1. 프로젝트 디렉토리로 이동을 한다
Step 2. Docker image를 Build 한다
Step 3. Docker run을 하면서 Mount 시킨다

 

 

Dockerfile 구성

가장 먼저 Dockerfile은 딱히 작업할 건 없지만 내 Dockerfile을 먼저 보자

FROM python:3.10.19
#EXPOSE 8501 도 추가하면 Docker가 포트 매핑을 인식하기 쉬움
EXPOSE 8501

WORKDIR /app
COPY . /app

ENV PYTHONUNBUFFERED=1 \
    PYTHONDONTWRITEBYTECODE=1 \
    PYTHONPATH=/app

# 대화형 방식의 terminal 방지
ENV DEBIAN_FRONTEND=noninteractive

# 패키지 목록 업데이트
RUN apt-get update
# 필수 패키지 설치
RUN apt-get -y install sudo

# apt 캐시 정리
RUN rm -rf /var/lib/apt/lists/*

# pip 업그레이드
RUN python3 -m pip install --upgrade pip

# requirements.txt 설치 --ignore-installed 옵션 : 기존 시스템 패키지를 무시하고 새 버전을 덮어씀
RUN python3 -m pip install --no-cache-dir --ignore-installed -r requirements.txt

RUN python3 --version && pip --version

#CMD 컨테이너가 실행될 때 기본으로 실행할 명령을 지정(docker run 명령 뒤에 다른 명령을 주면, CMD는 덮어쓰기(overwrite))
#ENTRYPOINT 컨테이너가 실행될 때 항상 실행되어야 하는 명령을 지정합니다. (docker run 뒤에 추가 인자를 주면, 그것이 ENTRYPOINT의 인자로 전달)
CMD ["streamlit","run","sql_agent_webapp.py", "--server.address=0.0.0.0", "--server.port=8501"]

쉽게 Python image를 가져와서 Streamlit을 실행하는 Dockerfile이다

 

여기에서

WORKDIR /app

WORKDIR : 작업 디렉토리를 지정 (이게 없으면 root 디렉토리가 Default로 지정됨)

- 이러면 root 디렉토리가 정신 없어지기 때문에 WORKDIR 을 정해서 여기서 관리되도록 하는 것이다

- git pull 당기면 자동으로 Repository 안에 파일들이 들어가게 끔 하는 것과 유사

그래서 어플리케이션을 위한 소스들을 WORKDIR에 따로 관리하려고 (/app을 지정)

- 이거 아래 있는 모든 명령어 (RUN, COPY)등은 /app 디렉토리 기준으로 실행가게 된다

 

 

COPY . /app

여기에서 . 의 의미는 현재 폴더 전체를 뜻하고, docker build 명령을 실행할 때 지정한 폴더 안의 경로만 사용할 수 있다는 뜻이다.

    - 이래서 COPY의 첫 번째 인자는 항상 빌드 컨텍스트 기준의 상대경로여야 한다

여기서 빌드 컨텍스트란

docker build -t my_image_name /home/user/project

와 같은 명령어로 docker image를 만드는데 (사실 현재 폴더 기준으로 하는 아래의 명령어를 더 많이 씀)

docker build -t my_image_name .

 

이때 뒤에있는 . 이나 /home/user/project 가 빌드 컨텍스트 이다 (기준점 (cd 를 통해 들어왔다고 생각))

/home/user/project/
├── Dockerfile
├── src/
│   └── main.py
└── data/
    └── input.txt

이렇게 되어있고 COPY ./src app/ 이라고 한다면

현재 빌드 컨텍스트가 /home/user/project이기 때문에 /home/user/project/main.py 에 있는 녀석을 container에 복사한다

나는 위에 구조같이 소스코드가 Dockerfile 과 같이 있어서 위와 같이

COPY . /app

을 적어줬다.

 

ENV PYTHONPATH=/app 

PYTHONPATH는 import sys 와 같이 라이브러리 들을 사용할 때 모듈이 필요한데

이 모듈을 python이 찾을 때 폴더를 /app 도 찾아라 라고 하는 것이다

- 이 app 외에도 딴 곳에서 여기서 만든 모듈을 쓸 수 있게 하겠다 인데  사실 굳이 안써도 된다

 

Docker Image Build & RUN

이렇게 Dockerfile을 만들었으면 build를 해준다

cd my_project
docker build . -t "insp_db_agent-image:CPU"

 

자 이러면 내 Project 가 빌드 컨텍스트가 되고

image를 실행하면 여기를 기점으로 COPY와 RUN 등이 일어난다

 

이제 여기에 RUN 을 Mount 를 포함하여 시켜주면

sudo docker run -d \
  -p 8501:8501 \
  -v /home/python/Insp_DB_Agent:/app \
  --name insp_db_agent_program \
  insp_db_agent-image:CPU

 

정상적으로 반영된다

 

docker run -it -v $(pwd):/app/insp_db_agent -p 8501:8501 --name insp_db_agent harams/insp_db_agent-image:latest

이런 식으로 실행시킬 수 있는데

$(pwd) : 현재 터미널의 작업 디렉터리(pwd)를 컨테이너의 /app/insp_db_agent에 마운트

(실행 위치에 따라 마운트되는 경로가 달라짐)

-it : 터미널을 컨테이너 안으로 바로 연결하여 작업할 수 있게 해줌

-d : 백그라운드 실행

 

 

 

 

 

주의 사항

 -v /home/python/Insp_DB_Agent:/app 라고 할 때

/home/python/Insp_DB_Agent 에 소스코드가 미리 들어 있어야 한다

Dockerfile에서 백날 Copy 해봤자 마운트하면서 덮어쓰기 되기 때문에

소스코드를 미리 넣어두고

소스코드 옮길 때는 굳이 Docker를 이용하기 보단 GIT을 이용하는 게 편하고 빠르다

 

 

Trial & Error

1.  Error: EACCES: permission denied

Unable to write file 'vscode-remote://ssh-remote+7b22686f73744e616d65223a2255495365727665722831303329227d/home/python/Insp_DB_Agent/adfa' (NoPermissions (FileSystemError): Error: EACCES: permission denied, open '/home/python/Insp_DB_Agent/adfa')

이건 권한 문제여서

# 특정 유저에게만 권한을 주려고 할 때
sudo chown -R {username}:{username} {folder_path}
sudo chmod -R 755 {folder_path}

#모두에게 권한을 줄때
sudo chmod -R 775 {folder_path}

로 해결이 가능하다

 

 

2. /var/run/docker.sock의 permission denied

/var/run/docker.sock의 permission denied

이건 아래 링크에서 아주 친절히 설명했는데

https://github.com/occidere/TIL/issues/116

 

docker 설치 후 /var/run/docker.sock의 permission denied 발생하는 경우 · Issue #116 · occidere/TIL

docker 설치 후 /var/run/docker.sock의 permission denied 발생하는 경우 상황 docker 설치 후 usermod로 사용자를 docker 그룹에 추가까지 완료 후 터미널 재접속까지 했으나 permission denied 발생 (설치 참고: https://b

github.com

docker.sock에 대한 접근 권한 문제이다

sudo groupadd docker
sudo usermod -aG docker $USER
sudo chown root:docker /var/run/docker.sock
sudo newgrp docker

 

 

 

참고자료

https://www.daleseo.com/docker-volumes-bind-mounts/#google_vignette

 

Docker 컨테이너에 데이터 저장 (볼륨/바인드 마운트)

Docker 컨테이너의 데이터를 영속적으로 저장하는 두 가지 방법을 알아봅니다. 볼륨과 바인드 마운트의 차이점과 사용법을 실전 예제로 비교 설명합니다.

www.daleseo.com

https://velog.io/@hoplin/Docker-docker-volume

 

[Docker] docker volume

Dockerfile을 아래와 같이 간단히 정의했다고 가정해 보자이미지를 빌드 하고 컨테이너 하나를 만들어 본다.파일이 잘 만들어 졌으며, 도커 이미지에서 생성한 파이썬 파일도 존재하는것을 볼 수

velog.io

 

 

 

 

728x90