Docker Volume 적용 및 docker-compose 적용하는법. Docker volume이란? 왜 쓸까?

728x90

개인적으로 사용했던 이유

회사에서 업무를 맡으면서 주로 도커와 클라우드 스토리지 (S3) 를 사용하는데,

이번에 리눅스 서버 내 로컬 스토리지를 사용하는 일이 있었다.

 

이 때 서버 내 nginx 를 사용하여 백엔드 load balancer를 사용하여 같은 파일을 공유해야하는 문제가 발생했다.

(load balancer로 백엔드를 여러개 구성하면, 각각의 개인 저장 파일을 참조하기 때문에 문제가 발생함)

 

이 문제를 각각의 backend 를 공용 volume에 마운트하여 로컬 스토리지를 같이 공유하여 해결함.

 

도커 Volume이란?

도커를 사용하여 앱을 실행하여 어떤 이미지나 파일을 저장한다고 해보자.

나중에 사용하지 않는다고 그 앱(도커 이미지)을 지워버리면, 내부에 저장되어있는 이미지 혹은 파일도 다 날아간다.

하지만 그 앱을 Volume에 마운트하여 사용하면, 그 Volume을 지워버리지 않는 이상 파일이 보존된다.

즉, 파일들을 날라가지 않게 저장해주는 도커 전용 스토리지라고 보면 된다.

 

Docker 파일 Volume 사용하여 작성하는법

솔직히 Docker-compose 파일을 사용하지 않는다면 Dockerfile은 변경할게 없다.

 

하지만 Docker compose를 사용하지 않고 Docker만 사용하여 Volume을 마운트한다면?

아래와 같이 하면 됨. (파이썬 기본 예시로 듬)

FROM python:3.7.13-slim

WORKDIR /backend
COPY requirements.txt /backend/requirements.txt

RUN apt-get update && apt-get install ffmpeg libsm6 libxext6 -y
RUN pip install --upgrade pip && \
    pip install --no-cache-dir -r requirements.txt

COPY . .

# 여기다 volume 지정. 단순히 /backend는 그냥 volume 이름임
VOLUME ["/backend"]

EXPOSE 5000
CMD ["flask", "run", "--host=0.0.0.0"]

 

Docker compose 파일 Volume 사용하여 작성하는법

업무로 인해 로드밸런서 쓰고 공용으로 Volume을 마운트했다.

version: '3'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:80"
    environment:
      REACT_BACKEND_URL: http://localhost:80/api
    depends_on:
      - backend1
      - backend2
      # - backend3
      # - backend4
      # - backend5
      # - backend6
      # - backend7
      # - backend8
      # - backend9
      # - backend10
    networks:
      - my-network
# 공용 volume 이름 mount
  backend1:
    build: ./backend
    volumes:
      - shared-backend-data:/backend
    ports:
      - "5001:5000"
    networks:
      - my-network

  backend2:
    build: ./backend
    volumes:
      - shared-backend-data:/backend
    ports:
      - "5002:5000"
    networks:
      - my-network

  # Uncomment and repeat for backend3 to backend10
  # backend3:
  #   build: ./backend
  #   volumes:
  #     - shared-backend-data:/backend
  #   ports:
  #     - "5003:5000"
  #   networks:
  #     - my-network

  nginx:
    build:
      context: ./nginx
    ports:
      - "80:80"
    networks:
      - my-network
    environment:
      - REACT_FRONTEND_URL=http://frontend:80
      - REACT_BACKEND_URL=http://backend:5000
    depends_on:
      - frontend
      - backend1
      - backend2
      # - backend3
      # - backend4
      # - backend5
      # - backend6
      # - backend7
      # - backend8
      # - backend9
      # - backend10

networks:
  my-network:
    external: true
# 여기 하단에 mount할 volume 명시
volumes:
  shared-backend-data:

 

 

만약 개별로 volume을 지정하여 쓸 것이라면

각각 이름을 지정하고 하단에 각 이름을 다 명시하자

version: '3'

services:
  frontend:
    build: ./frontend
    ports:
      - "3000:80"
    environment:
      REACT_BACKEND_URL: http://localhost:80/api
    depends_on:
      - backend1
      - backend2
      # - backend3
      # - backend4
      # - backend5
      # - backend6
      # - backend7
      # - backend8
      # - backend9
      # - backend10
    networks:
      - my-network

# 아래 /app 을 본인의 Dockerfile WORKDIR 이름으로 변경!
  backend1:
    build: ./backend
    volumes:
      - backend1-data:/app
    ports:
      - "5001:5000"
    networks:
      - my-network

  backend2:
    build: ./backend
    volumes:
      - backend2-data:/app
    ports:
      - "5002:5000"
    networks:
      - my-network

  # Uncomment and repeat for backend3 to backend10
  # backend3:
  #   build: ./backend
  #   volumes:
  #     - backend3-data:/app
  #   ports:
  #     - "5003:5000"
  #   networks:
  #     - my-network

  nginx:
    build:
      context: ./nginx
    ports:
      - "80:80"
    networks:
      - my-network
    environment:
      - REACT_FRONTEND_URL=http://frontend:80
      - REACT_BACKEND_URL=http://backend:5000
    depends_on:
      - frontend
      - backend1
      - backend2
      # - backend3

networks:
  my-network:
    external: true

# 여기다 각각 volume 명시
volumes:
  backend1-data:
  backend2-data:
728x90