# Elastic/elasticsearch-docker not assigning permissions to data directory on run

**URL:** <https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812>\
**Category:** Elasticsearch\
**Created:** [November 11, 2016, 1:49pm UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812 "2016-11-11T13:49:53Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![skubi](https://avatars.discourse-cdn.com/v4/letter/s/9de053/32.png) [@skubi](https://discuss.elastic.co/u/skubi)\
**Post date:** [November 11, 2016, 1:49pm UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/1 "2016-11-11T13:49:53Z")

</div>

Hello,

I was trying to use elasticsearch-docker image for hosting dockerized elastichsearch cluster.

What I have noticed that the es-docker script:

[https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/bin/es-docker](https://github.com/elastic/elasticsearch-docker/blob/master/build/elasticsearch/bin/es-docker)

is not assigning any permissions though it is running under non-root user inside container:

```
USER elasticsearch
CMD ["/bin/bash", "bin/es-docker"]

```

and documentation suggests to mount a volume for data in README:

```
docker run -d -p 9200:9200 -v esdatavolume:/usr/share/elasticsearch/data $ELASTIC_REG/elasticsearch

```

This is how I was thinking to run it:

```
FROM docker.elastic.co/elasticsearch/elasticsearch

ADD jvm.options /usr/share/elasticsearch/config/
ADD elasticsearch.yml /usr/share/elasticsearch/config/

EXPOSE 9200 9300

```

And docker-compose:

```
version: '2'

services:
  elasticsearch1:
    container_name: es1
    build: ./build
    ports:
      - "9200:9200"
      - "9300:9300"
    volumes:
      - /data/elasticsearch1:/usr/share/elasticsearch/data:rw
    mem_limit: 3g
    restart: always

```

Which pretty aligns with README and docker-compose example in repository.  
But I was obviously getting exception regarding permissions:

```
[2016-11-11T10:36:18,442][INFO][o.e.n.Node] [] initializing ...
[2016-11-11T10:36:18,462][WARN][o.e.b.ElasticsearchUncaughtExceptionHandler] [] uncaught exception in thread [main]
Caused by: java.nio.file.AccessDeniedException: /usr/share/elasticsearch/data/nodes
        at sun.nio.fs.UnixException.translateToIOException(UnixException.java:84) ~[?:?]
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:102) ~[?:?]
        at sun.nio.fs.UnixException.rethrowAsIOException(UnixException.java:107) ~[?:?]
        at sun.nio.fs.UnixFileSystemProvider.createDirectory(UnixFileSystemProvider.java:384) ~[?:?]
        at java.nio.file.Files.createDirectory(Files.java:674) ~[?:1.8.0_92-internal]
        at java.nio.file.Files.createAndCheckIsDirectory(Files.java:781) ~[?:1.8.0_92-internal]
        at java.nio.file.Files.createDirectories(Files.java:767) ~[?:1.8.0_92-internal]
        at org.elasticsearch.env.NodeEnvironment.<init>(NodeEnvironment.java:220) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.node.Node.<init>(Node.java:240) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.node.Node.<init>(Node.java:220) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:191) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:191) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:286) ~[elasticsearch-5.0.0.jar:5.0.0]
        at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:112) ~[elasticsearch-5.0.0.jar:5.0.0]
        ... 6 more

```

Of course I have already fixed that with another entrypoint script that uses the initial one which is pretty ugly solution though:

```
#!/bin/bash
chown -R elasticsearch:elasticsearch /usr/share/elasticsearch/data;
su elasticsearch -c "/bin/bash es-docker"

```

And then Dockerfile change:

```
FROM docker.elastic.co/elasticsearch/elasticsearch

ADD jvm.options /usr/share/elasticsearch/config/
ADD elasticsearch.yml /usr/share/elasticsearch/config/

COPY entrypoint.sh bin/entrypoint.sh

USER root
CMD ["/bin/bash", "bin/entrypoint.sh"]

EXPOSE 9200 9300

```

I was really surprised that there was nobody creating any ticket/bug for this and now I am a bit confused if I misunderstood how this image should be used at all and I am missing some obvious solution for that? Am I doing something inappropriate?

---

<div class="post-metadata">

**Author:** ![dliappis](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dliappis/32/56174_2.png) [@dliappis](https://discuss.elastic.co/u/dliappis)\
**Post date:** [November 14, 2016, 9:50am UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/2 "2016-11-14T09:50:58Z")

</div>

Hello Aleksandr,

Thank you for your interest in the Elasticsearch images.

There are a number of different issues you are having in your setup.  
The permission errors you are getting in your example are because you are using a **host dir** as a data volume that doesn't match the uid/gid of the elasticsearch user in the image. Details in 2).

###1) Tuning Elasticsearch configuration parameters

The way that you were thinking of running the image, i.e. **creating your own custom image** based on the Elastic one is fine, but you need to remember to `chown` the `ADD`'ed configuration files in your `Dockerfile` to the user/group `elasticsearch`. This is something done in the Elasticsearch Dockerfile right after copying `elasticsearch.yml`, as shown [here](https://github.com/elastic/elasticsearch-docker/blob/5.0/build/elasticsearch/Dockerfile#L29):

So your `Dockerfile` would then look like:

```auto
FROM docker.elastic.co/elasticsearch/elasticsearch:5.0.0

ADD jvm.options /usr/share/elasticsearch/config/
ADD elasticsearch.yml /usr/share/elasticsearch/config/
USER root
RUN chown elasticsearch:elasticsearch config/jvm.options config/elasticsearch.yml

USER elasticsearch
EXPOSE 9200 9300

```

For example, using a simple `elasticsearch.yml` file:

```auto
$ cat elasticsearch.yml 
cluster.name: "custom-cluster"
network.host: 0.0.0.0

```

and the same `jvm.options` as in the original image with a change of -Xms/-Xmx to 1G, a new image can be built using

`docker build -t myes .`

and running it with:

`docker run -ti -p 9200:9200 -v /usr/share/elasticsearch/data myes`

produces a working image with the right permissions under `config/`

_NOTE_: If you were to omit the `chown` commands `elasticsearch.yml/jvm.options` would be owned by `0:0` as documented in the [Dockerfile ADD section](https://docs.docker.com/engine/reference/builder/#/add) but it wouldn't be catastrophic for the Elasticsearch start as it would still have read access to those files. Still it's best practice to `chown` then files afterwards. I will update the documentation to warn about that for this configuration method.1

_NOTE2_: You should be using `FROM: docker.elastic.co/elasticsearch/elasticsearch:THEVERSION` as opposed to relying on latest. Right now we have `5.0.0` and soon we will be pushing `5.0.1` (docker image versions are matching the Elasticsearch ones). Please try not to rely on `:latest` as it may bring whatever staging build and indeed, going forward, we will be deprecating `:latest` to avoid customers ending up with broken configurations.

### 2) Data volumes versus local mounts for `/usr/share/elasticsearch/data`

As you correctly mentioned in the README we recommend the use of a **named volume**. With docker cli this is accomplished with `-v <nameofvolume>:/usr/share/elasticsearch/data`. This volume will be created if not already present and can be seen with `docker volume ls`. The volume will persist even if you destroy the container, unless you explicitly remove it with `docker volume rm <nameofvolume>`.

In your `docker-compose.yml` example, however, you are using a host mounted directory (`/data/elasticsearch1/`). This will result in `/usr/share/elasticsearch/data` having the same permissions as your local dir. Therefore unless `/data/elasticsearch/` is owned by `1000:1000` or chmod'ed to `777`, Elasticsearch won't be able to write there! 2  
So you will either need to make sure your local dir is `chown -R elasticsearch:elasticsearch /data/elasticsearch1` before running the container or use non-host based data volumes.

The `docker-compose.yml` syntax for data volumes looks like:

```auto
# ...
    volumes:
      - esdata1:/usr/share/elasticsearch/data
volumes:
  esdata1:
    driver: local

```

Alternatively, if you don't mind ending up with a randomly named volume you can use

```auto
# ...
    volumes:
      - /usr/share/elasticsearch/data

```

The difference between `data volumes` and `host mounted data volumes` are described in the [Docker Documentation](https://docs.docker.com/engine/tutorials/dockervolumes/).

### Notes:

1: The Docker documentation will very soon be part of the docs on the Elastic web site, so stay tuned! The documentation for Kibana on Docker is already there: [https://www.elastic.co/guide/en/kibana/current/install.html](https://www.elastic.co/guide/en/kibana/current/install.html)

2: There are number of Docker feature requests to add support for setting the uid/gid when mounting local dirs e.g. [https://github.com/docker/docker/issues/2259;](https://github.com/docker/docker/issues/2259;)

---

<div class="post-metadata">

**Author:** ![skubi](https://avatars.discourse-cdn.com/v4/letter/s/9de053/32.png) [@skubi](https://discuss.elastic.co/u/skubi)\
**Post date:** [November 14, 2016, 11:37am UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/3 "2016-11-14T11:37:54Z")

</div>

Hello,

Thank you very much for the detailed description.

1. This seems not to be the issue in my case as permissions allow reading jvm.options for everybody (0644). This might be the issue for somebody else so it definitely is good idea to assign the ownership to elasticsearch user and group just to be on the safe side, thanks!

2. Yes, I did pay attention that you do recommend using the named volumes. The thing is that I am using external disk for storing the data due to the cloud limitations on boot drive. In my case /data directory is a mounted drive location.

If I am not mistaken and correct me if I am wrong but you cannot define location for named volume with local driver in Docker.

> <https://github.com/moby/moby/issues/19990>

I am just trying to avoid writing my own driver for that purpose and mounting host directory is workaround for such usage, isn't it? It still will persist data to the disk and then data will not be lost on container recreation.

Notes:  
2. Well, this is pretty old issue from 2013 so I would assume it is quite unlikely it will be implemented any time soon anyways.

---

<div class="post-metadata">

**Author:** ![dliappis](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/dliappis/32/56174_2.png) [@dliappis](https://discuss.elastic.co/u/dliappis)\
**Post date:** [November 14, 2016, 2:34pm UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/4 "2016-11-14T14:34:58Z")

</div>

> [@skubi](#):
>
> Yes, I did pay attention that you do recommend using the named volumes. The thing is that I am using external disk for storing the data due to the cloud limitations on boot drive. In my case /data directory is a mounted drive location.
> 
> If I am not mistaken and correct me if I am wrong but you cannot define location for named volume with local driver in Docker.

You **can** use a bind-mount for your specific use case, just ensure that the directory has such permissions that the elasticsearch user can write in it. Either tune your host OS mount parameters to ensure the external dir is writable when bind-mounted inside the container by the elasticsearch user or just create a subdir inside this external mount point owned by `1000:1000` using that instead.

In the Docker issue that you linked there is also mention of a method to create a named volume reflecting a host dir [https://github.com/docker/docker/issues/19990#issuecomment-248955005](https://github.com/docker/docker/issues/19990#issuecomment-248955005), but, as in the case of a bind-mount, the files will also retain the uid:gid and permissions of your host dir, so you'll need to address that.

Finally since you mentioned cloud usage, depending on the vendor, you may consider an alternative storage driver: a few open source projects include [GitHub - rexray/rexray: REX-Ray is a container storage orchestration engine enabling persistence for cloud native workloads](https://github.com/codedellemc/rexray) and [KING138 ## Situs Penyedia Pragmatic Play PG Soft dan No Limit City Terlengkap](https://clusterhq.com/flocker/introduction/).

---

<div class="post-metadata">

**Author:** ![skubi](https://avatars.discourse-cdn.com/v4/letter/s/9de053/32.png) [@skubi](https://discuss.elastic.co/u/skubi)\
**Post date:** [November 14, 2016, 3:51pm UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/5 "2016-11-14T15:51:30Z")

</div>

Alright, thanks a lot! It is much more clear now what was the idea behind such Dockerfile implementation.

It would help a lot if this information is included into the documentation and I hope it will at some point.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [December 12, 2016, 3:52pm UTC](https://discuss.elastic.co/t/elastic-elasticsearch-docker-not-assigning-permissions-to-data-directory-on-run/65812/6 "2016-12-12T15:52:31Z")

</div>

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.
