개발할 때는 보통 도커환경에서 테스트하지 않고 로컬에서 테스트를 한다. 하지만 테스트마저도 도커환경에서 하고 싶을 수 있다. 만약 이러한 상황에서 코드가 수정되면 어떤 일이 벌어질까? 컨테이너환경도 수정된 사항을 반영하기 위해 아래 작업을 수행한다.
- 도커 이미지를 재 빌드한다.
- 실행중인 컨테이너를 종료한다.
- 빌드한 이미지를 다시 실행시킨다.
크게 복잡한 과정은 없지만 수시로 변경되는 코드를 생각해보면 정말 귀찮은 작업이다. 이를 해결하기 위해 바인드 마운트를 사용하면 편리하게 사용할 수 있다.
프로젝트 준비
# main.py
from fastapi import FastAPI
import uvicorn
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello World"}
if __name__ == "__main__":
uvicorn.run("main:app", port=8000, host="0.0.0.0")
# requirements.txt
fastapi==0.95.1
uvicorn==0.22.0
# Dockerfile
FROM python:3.11
WORKDIR /app
COPY . .
RUN pip install -r requirements.txt
EXPOSE 8000
CMD ["python", "main.py"]
예제로 자주 사용하던 기본 fastapi 코드이다. 일단 이미지를 빌드하고 실행해보자.
docker build --tag bind .
docker run --rm --name bind -p 8000:8000 bind
잘 나오지만 로컬에서 수정해도 수정된 결과가 나오지 않고 위의 결과가 나오게 된다.
바인드 마운트
도커에서는 데이터 저장을 위한 볼륨 기능을 제공한다. 여기에서는 볼륨의 일종인 바인드 마운트를 사용한다. 이 기능은 로컬에 존재하는 폴더와 컨테이너 내부의 폴더를 바인딩하여 서로의 파일을 공유하게 된다. (가상머신에서 바인딩을 생각하면 된다.) 그렇게 되면 로컬에서 수정하면 컨테이너에서 반영되고, 컨테이너에서 수정하면 로컬에도 반영된다.
docker run --rm --name bind -v /home/riroan/bind:/app -p 8000:8000 bind
바인딩 마운트를 사용하려면 위와 같이 실행한다. -v 옵션이 볼륨을 사용한다는 옵션이고 {로컬 절대경로}:{컨테이너 내 절대경로}로 사용한다. (로컬 경로는 각자 맞게 수정한다.) 중요한 점은 절대 경로로 사용해야 한다는 것이다. 이제 코드를 수정하고 실제로 반영됐는지 확인해보자.
# main.py
...
@app.get("/")
async def root():
return {"message": "Hello World", "new object": "good"}
...
reload 옵션이 True로 돼있기때문에 수정사항이 서버에 바로 반영이 되고 따로 컨테이너를 재실행하지 않아도 적용된 것을 볼 수 있다.
'프로그래밍 > 도커' 카테고리의 다른 글
[도커] 14. ECR 무작정 사용하기 (2) | 2023.07.09 |
---|---|
[도커] 12. dockerignore (0) | 2022.08.19 |
[도커] 11. 환경변수 (0) | 2022.08.19 |
[도커] 10. 도커 네트워크 (3) | 2022.08.15 |
[도커] 9. 도커 이미지 만들기 (0) | 2022.01.03 |