Docker persisted volum has no permissions (Apache Solr)
Asked Answered
M

3

8

My docker-compose.yml:

solr:
    image: solr:8.6.2
    container_name: myproject-solr
    ports:
     - "8983:8983"
    volumes:
      - ./data/solr:/var/solr/data
    networks:
      static-network:
        ipv4_address: 172.20.1.42

After bringing up the docker with docker-compose up -d --build, the solr container is down and the log (docker logs myproject-solr) shows this:

Copying solr.xml
cp: cannot create regular file '/var/solr/data/solr.xml': Permission denied

I've noticed that if I give full permissions on my machine to the data directory sudo chmod 777 ./data/solr/ -R and I run the Docker again, everything is fine.

I guess the issue comes when the solr user is not my machine, because Docker creates the data/solr folder with root:root. Having my ./data folder gitignored, I cannot manage these folder permissions.

I'd like to know a workaround to manage permissions properly with the purpose of persisting data

Mabelmabelle answered 21/9, 2020 at 14:8 Comment(0)
C
15

It's a known "issue" with docker-compose: all files created by Docker engine are owned by root:root. Usually it's solved in one of the two ways:

  1. Create the volume in advance. In your case, you can create the ./data/solr directory in advance, with appropriate permissions. You might make it accessible to anyone, or, better, change its owner to the solr user. The solr user and group ids are hardcoded inside the solr image: 8983 (Dockerfile.template)
mkdir -p ./data/solr
sudo chown 8983:8983 ./data/solr
  1. If you want to avoid running additional commands before docker-compose, you can create additional container which will fix the permissions:
version: "3"

services:

  initializer:
    image: alpine
    container_name: solr-initializer
    restart: "no"
    entrypoint: |
      /bin/sh -c "chown 8983:8983 /solr"
    volumes:
      - ./data/solr:/solr
    
  solr:
    depends_on: 
      - initializer
    image: solr:8.6.2
    container_name: myproject-solr
    ports:
     - "8983:8983"
    volumes:
      - ./data/solr:/var/solr/data  
    networks:
      static-network:
        ipv4_address: 172.20.1.42
Chimerical answered 22/9, 2020 at 9:0 Comment(1)
It would be possible to add the 'initializer' entrypoint to the solr container in any way (entrypoint in the container or writing it in a Dockerfile that uses solr image)?Mabelmabelle
D
8

There is docker-compose-only solution :)

Problem

Docker mounts local folders with root permissions.

In Solr's docker image, the default user is solr - for a good reason: Solr commands should be run with this user (you can force to run them with root but that is not recommended).

Most Solr commands require write permissions to /var/solr/, for data and logs storage.

In this context, when you run a solr command as the solr user, you are rejected because you don't have write permission to /var/solr/.

Solution

What you can do is to first start the container as root to change the permissions of /var/solr/. And then switch to solr user to run all necessary solr commands. You can't start our Solr server.

In the example below, we use solr-precreate to create a default core and start solr.

version: '3.7'

services:

  solr:
    image: solr:8.5.2
    volumes:
      - ./mnt/solr:/var/solr
    ports:
      - 8983:8983
    user: root # run as root to change the permissions of the solr folder
    # Change permissions of the solr folder, create a default core and start solr as solr user
    command: bash -c "
      chown -R 8983:8983 /var/solr
      && runuser -u solr -- solr-precreate default-core"
Dyeline answered 29/7, 2021 at 9:22 Comment(2)
Why is this not in the official instructions? And why do they distribute a broken container?Ripply
If you don't mount anything, there is no permission issue. As for the official instructions... well I am not a maintainer :)Dyeline
K
4

Set with a Dockerfile

It's possibly not exactly what you wanted as the files aren't persisted when rebuilding the container, but it solves the 'rights' problem. Copy the files over and chown them with a Dockerfile:

FROM solr:8.7.0
COPY --chown=solr ./data /var/solr/data

This is more useful if you're trying to initialise a single core:

FROM solr:8.7.0
COPY --chown=solr ./core /var/solr/data/someCollection

It also has the advantage that you can create an image for reuse.

With a named volume

For persistence, you can also create a volume (in this case core) and copy the contents of a directory (also called core here), assigning the rights to the files on the way:

docker container create --name temp -v core:/data tianon/true || exit $?
tar -cf - --directory core --owner 8983 --group 8983 . | docker cp - temp:/data
docker rm temp

This was adapted from these answers:

Then you can mount the named volume in your Docker Compose file:

version: '3'
services:
  solr:
    image: solr:8.7.0
    networks:
      - internal
    ports:
      - 8983:8983
    volumes:
      - core:/var/solr/data/someCollection

volumes:
  core:
    external: true

This solution persists the data without overriding the data on the host. And it doesn't need the extra build step. And can obviously be adapted for mounting the entire /var/solr/data folder.

It doesn't seem to matter that the mounted volume/directory doesn't have the correct rights (/var/solr/data/someCollection has owner root:root).

Kwang answered 24/11, 2020 at 12:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.