senzacionale
senzacionale

Reputation: 20926

docker-compose type: volume persist in external folder

version: '3.2'
    
services:
  elasticsearch:
    container_name: elasticsearch
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      LOGSPOUT: ignore
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      ELASTIC_PASSWORD: changeme
      # Use single node discovery in order to disable production mode and avoid bootstrap checks.
      # see: https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
      discovery.type: single-node
    networks:
      - elk

networks:
  elk:
    driver: bridge

volumes:
  elasticsearch:

I want to use elasticsearch to pesrist data in folder /WDC1TB/docker/volumes/elasticsearch/data but I can not set it correctly. Or I am getting that volume is not a string or similar error.

How to correctly use docker-compose and persist data in external folder /WDC1TB/docker/volumes/elasticsearch/data

Upvotes: 0

Views: 3407

Answers (2)

JandaTheMan
JandaTheMan

Reputation: 94

With your current configuration:

services:
  elasticsearch:
    container_name: elasticsearch
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      LOGSPOUT: ignore
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      ELASTIC_PASSWORD: changeme
      # Use single node discovery in order to disable production mode and avoid bootstrap checks.
      # see: https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
      discovery.type: single-node
    networks:
      - elk


networks:
  elk:
    driver: bridge 
volumes:
    elasticsearch:

You are creating a Volume on top of the container directory /usr/share/elasticsearch/data specified in:

 - type: volume
        source: elasticsearch
        target: /usr/share/elasticsearch/data

At the same time you are indicating to docker to create this volume with:

volumes:
  elasticsearch:

This means docker engine is creating a volume named elasticsearch and is mounting the container specified directory there.

You can check the volume mountpoint with:

$ docker volume inspect elasticsearch

In order to mount the data to host filesystem directory, you should use bind mounts with the next compose file:

services:
  elasticsearch:
    container_name: elasticsearch
    build:
      context: elasticsearch/
      args:
        ELK_VERSION: $ELK_VERSION
    volumes:
      - type: bind
        source: ./elasticsearch/config/elasticsearch.yml
        target: /usr/share/elasticsearch/config/elasticsearch.yml
        read_only: true
      - type: bind
        source: /WDC1TB/docker/volumes/elasticsearch/data
        target: /usr/share/elasticsearch/data
    ports:
      - "9200:9200"
      - "9300:9300"
    environment:
      LOGSPOUT: ignore
      ES_JAVA_OPTS: "-Xmx256m -Xms256m"
      ELASTIC_PASSWORD: changeme
      # Use single node discovery in order to disable production mode and avoid bootstrap checks.
      # see: https://www.elastic.co/guide/en/elasticsearch/reference/current/bootstrap-checks.html
      discovery.type: single-node
    networks:
      - elk


networks:
  elk:
    driver: bridge 

With that, using a bind mount, a file or directory /WDC1TB/docker/volumes/elasticsearch/data on the host machine is mounted into a container.

In the opposite case, the way your current solution is done, you are using a volume that are completely managed by Docker and is the engine itself responsible to assing a mount point for the volume.

Upvotes: 2

When you use a volume with type: volume it will be saved where Docker service says to, in my case is in /var/lib/docker/volumes/{projectname_containername}/_data/.

If you want to save it in a specific folder you will need a type: bind volume that points to the desired folder in your host, in your case /WDC1TB/docker/volumes/elasticsearch/data.

You should replace:

  - type: volume
    source: elasticsearch
    target: /usr/share/elasticsearch/data

with

  - type: bind
    source: /WDC1TB/docker/volumes/elasticsearch/data
    target: /usr/share/elasticsearch/data

If /WDC1TB/docker/volumes/elasticsearch/data doesn't exist, Docker will create it. In this case check file permission afterwards.

Also, now that you won't use named volumes you can delete

volumes:
  elasticsearch:

Upvotes: 1

Related Questions