Search code examples
docker-composesymlinkmountdocker-volumeelasticsearch-7

Using a Docker-Volume with a Mount to a Symlink, But It's Persisting Data to the Host Too. Why?


I created a Docker volume as such:

sudo docker volume create --driver=local --name=es-data1 --opt type=none --opt o=bind --opt device=/usr/local/contoso/data1/elasticsearch/data1
  • /usr/local/contoso/data1/elasticsearch/data1 is a symlink.

And I'm instantiating three Elasticsearch Docker containers in my docker-compose.yml file as such:

version: '3.7'
services:
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
    logging:
      driver: none
    container_name: elasticsearch1
    environment:
      - node.name=elasticsearch1
      - cluster.name=docker-cluster
      - cluster.initial_master_nodes=elasticsearch1
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1G -Xmx1G"
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - network.host=_eth0_          
    ulimits:
      nproc: 65535
      memlock:
        soft: -1
        hard: -1
    cap_add:
      - ALL
    # privileged: true
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '1'
          memory: 1G
      restart_policy:
        condition: unless-stopped
        delay: 5s
        max_attempts: 3
        window: 10s
    volumes:
      - es-logs:/var/log
      - es-data1:/usr/share/elasticsearch/data
    networks:
      - elastic
      - ingress
    ports:
      - 9200:9200
      - 9300:9300
    healthcheck:
      test: wget -q -O - http://127.0.0.1:9200/_cat/health
  elasticsearch2:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
    logging:
      driver: none
    container_name: elasticsearch2
    environment:
      - node.name=elasticsearch2
      - cluster.name=docker-cluster
      - cluster.initial_master_nodes=elasticsearch1
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1G -Xmx1G"
      - "discovery.zen.ping.unicast.hosts=elasticsearch1"
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - network.host=_eth0_          
    ulimits:
      nproc: 65535
      memlock:
        soft: -1
        hard: -1
    cap_add:
      - ALL
    # privileged: true
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '1'
          memory: 1G
      restart_policy:
        condition: unless-stopped
        delay: 5s
        max_attempts: 3
        window: 10s
    volumes:
      - es-logs:/var/log
      - es-data2:/usr/share/elasticsearch/data
    networks:
      - elastic
      - ingress
    ports:
      - 9201:9200
    healthcheck:
      test: wget -q -O - http://127.0.0.1:9200/_cat/health
  elasticsearch3:
    image: docker.elastic.co/elasticsearch/elasticsearch:7.6.0
    logging:
      driver: none
    container_name: elasticsearch3
    environment:
      - node.name=elasticsearch3
      - cluster.name=docker-cluster
      - cluster.initial_master_nodes=elasticsearch1
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms1G -Xmx1G"
      - "discovery.zen.ping.unicast.hosts=elasticsearch1"
      - http.cors.enabled=true
      - http.cors.allow-origin=*
      - network.host=_eth0_          
    ulimits:
      nproc: 65535
      memlock:
        soft: -1
        hard: -1
    cap_add:
      - ALL
    # privileged: true
    deploy:
      replicas: 1
      update_config:
        parallelism: 1
        delay: 10s
      resources:
        limits:
          cpus: '1'
          memory: 1G
        reservations:
          cpus: '1'
          memory: 1G
      restart_policy:
        condition: unless-stopped
        delay: 5s
        max_attempts: 3
        window: 10s
    volumes:
      - es-logs:/var/log
      - es-data3:/usr/share/elasticsearch/data
    networks:
      - elastic
      - ingress
    ports:
      - 9202:9200
    healthcheck:
      test: wget -q -O - http://127.0.0.1:9200/_cat/health
volumes:
  es-data1:
    driver: local
    external: true
  es-data2:
    driver: local
    external: true
  es-data3:
    driver: local
    external: true
  es-logs:
    driver: local
    external: true     
networks:
  elastic:
    external: true
  ingress:
    external: true

My Problem:

  • The Elasticsearch containers are persisting index data to both the host filesystem and the mounted symlink.

My Question:

  • How do I modify my configuration so that the Elasticsearch containers are only persisting index data to the mounted symlink?

Solution

  • It seems to be the default behavior of the local volume driver that the files are additionally stored on the host machine. You can change the volume settings in your docker-compose.yml to prevent the docker from persisting (copying) files on the host file system (see nocopy: true), like so:

    version: '3.7'
    services:
      elasticsearch:
        ....
        volumes:
          - type: volume
            source: es-data1
            target: /usr/share/elasticsearch/data
            volume:
              nocopy: true
        ....
    volumes:
      es-data1:
        driver: local
        external: true
    

    You may also want to check this question here: Docker-compose - volumes driver local meaning. So, there seem to be some docker volume plugins that are made specifically for the portability reasons; such as flocker or hedvig. But I didn't use a plugin for such purpose, so I can't really recommend one, yet.