Profile picture

[Docker Compose] Volumes

JaehyoJJAng2022년 04월 20일

Volume Container 란?

일반적으로 docker container는 컨테이너 내부에 있는 데이터를 관리하므로, 컨테이너가 삭제되면?

컨테이너 내의 모든 데이터가 싹 날아감 이는 mysql 같은 데이터 스토리지를 사용할 경우 매우 위험하게 되는데, 위의 예시처럼 MySQL 데이터 스토리지 사용 시, 컨테이너가 삭제되면 DB 데이터도 싹 날아가서 복구할 수가 없음

  • 이를 방지하기 위해 따로 볼륨을 설정해서 데이터를 저장해 줘야 함

호스트 OS 디렉터리를 마운트 시켜서 데이터를 관리할 수도 있음

예시

version: "3"
services:
  test:
    volumes:
      ./test/:/var/lib/mysql/

그러나 위와 같은 방식은

호스트 쪽 디렉터리에 의존이 생기고 만약 이 디렉터리의 데이터를 잘못 손대면 애플리케이션에 부정적 영향을 미칠 수 있기 때문에 이 방식은 사용하지 않는 것이 좋음

그래서 이에 대한 대안으로 추천되는 것이 볼륨 컨테이너임.

볼륨 컨테이너는 말 그대로 데이터를 저장하는 것이 목적인 컨테이너이고 기본적으로 Dockerfile 작성 시 아래와 같이 볼륨을 설정할 수 있음

FROM mysql:5.7

VOLUME /var/lib/mysql

위처럼 작성하게 되면 컨테이너 내의 /var/lib/mysql 디렉터리가 호스트 PC의 /var/lib/docker/volumes/${volume_name}/_data 에 마운트 된다

볼륨 이름은 임의의 해시값으로 생성

참고로 mac이나 windows의 경우 /var/lib/docker/volumes 디렉터리가없는데 이는 mac이나 windows의 경우 docker를 바로 실행할 수 없으므로 VM을 하나 띄운 뒤 docker를 실행하기 때문임 즉, /var/lib/docker/volumes 디렉터리는 mac과 docker 사이에 띄워진 VM 내에 감춰져있음

관련 래퍼런스 참고

volume container는 볼륨의 이러한 특징을 사용한 것

컨테이너 자체를 볼륨을 관리하는 애로 만들어서 캡슐화하고, 이를 다른 컨테이너의 볼륨에 매핑해서 결합을 느슨하게 하는 것

만약 아래와 같은 볼륨 컨테이너를 작성하고,

FROM busybox

VOLUME /var/lib/mysql
VOLUME /var/log

/var/lib/mysql

/var/log

두 개의 볼륨이 생성되고

각각 /var/lib/docker/volumes/${volume_name}/_data 에 마운트가 됨

빌드하고 컨테이너로 띄운 뒤

$ docker image build -t volume_container:latest .
$ docker container run -d volume_container:latest

참고로 볼륨 컨테이너를 띄우면 바로 종료되지만, 이렇게 종료된 컨테이너를 사용해도 상관은 없음


-volumes-from 옵션으로 다른 컨테이너에 연결한다면

$ docker container run --volumes-from volume_container mysql:5.7

아래와 같은 형태가 된다.

mysql container -> volume_container -> /var/lib/docker/volumes/var/lib/${mysql의 volume_name}/_data
                                    -> /var/lib/docker/volumes/var/log/${log의 volume_name}/_data

volumes 컨테이너

  • 위의 방식처럼 컨테이너를 직접 만들고 다른 컨테이너 실행 시 --volumes-from 속성으로 연결해 주는 방법도 있지만, docker-compose를 사용 시 좀 더 간단한 방법을 제공해 준다

아래처럼 작성하면 된다

version: "3"
services:
    test_database:
        image: mysql:5.7
        environment:
          MYSQL_DATABASE: test_db
          MYSQL_ROOT_PASSWORD: root
          MYSQL_ROOT_HOST: '%'
        ports:
          - 3306:3306
        volumes:
          - test_volume:/var/lib/mysql

    test_application:
        build: .
        expose:
          - 8080
        depends_on:
          - test_database

volumes:
    test_volume:

보다시피 test_volume이라는 볼륨을 생성하고, 사용하는 쪽에서 ${volume_name}:${mount를 원하는 디렉터리} 의 형태로 지정해 주면 된다

docker-compose 설정 파일 version : "2"의 형태로 보면 좀 더 직관적으로 이해가 감

version: "2"
services:
    test_database:
        image: mysql:5.7
        environment:
          MYSQL_DATABASE: test_db
          MYSQL_ROOT_PASSWORD: root
          MYSQL_ROOT_HOST: '%'
        ports:
          - 3306:3306
        volumes:
          - test_volume

    test_application:
        build: .
        expose:
          - 8080
        depends_on:
          - test_database

    test_volume:
        image: busybox
        volumes:
            - /var/lib/mysql
            - /var/log

version :"3" 의 경우 컨테이너를 따로 생성하지 않아도 된다는 장점이 있다

볼륨 컨테이너는 충분히 좋은 기능이지만, 그래도 범위가 같은 도커 호스트 안이라는 사실은 변하지 않음

Volume 명령어


볼륨 조회 도커 명령

$ docker volumes ls

도커 볼륨 상세 정보 조회하기

$ docker volume inspect 볼륨이름

볼륨 삭제 도커 명령

$ docker volume rm 볼륨이름

쓰지 않는 볼륨 삭제 도커 명령

$ docker volume prune <<< y

쓰지 않는 이미지 , 볼륨 , 네트워크 삭제

# 도커 볼륨 삭제
$ docker system prune -a --volumes <<< y

Loading script...