Я создал пользователя с uid 1000 в Dockerfile и создал каталог /app, изменив владельца /app на uid 1000. Spring Boot также начинает использовать пользователя с uid 1000.
RUN adduser --uid 1000 -D appuser
RUN mkdir /app
RUN chown -R appuser:appuser /app
USER 1000
ENTRYPOINT [ "./docker-entrypoint.sh" ]
Когда Spring Boot запускается, он создает каталог /app/portal/logs и записывает журналы в каталог журналов. До использования Docker Compose для монтирования журналов в каталог на хосте с томом весь путь /app/portal/logs имел uid 1000 в качестве владельца, и проблем не возникало.
Однако когда я создал том для монтирования /app/portal/logs в /data на хосте, владелец каталогов приложения и журналов внутри контейнера остался с идентификатором uid 1000, но владелец промежуточного каталога, портала, стал пользователем root.
services:
portal:
image: myapp:latest
volumes:
- /data:/app/portal/logs
user: "1000:1000"
/app $ ls -al / | grep app
drwxr-xr-x 1 appuser appuser 83 Jun 7 16:13 app
/app $ ls -al /app | grep portal
drwxr-xr-x 3 root root 18 Jun 7 16:13 portal
/app $ ls -al /app/portal/
drwxr-xr-x 3 root root 18 Jun 7 16:13 .
drwxr-xr-x 1 appuser appuser 83 Jun 7 16:13 ..
drwxr-xr-x 2 appuser appuser 4096 Jun 7 14:54 logs
Это приводит к тому, что Spring Boot не имеет достаточных разрешений при создании других каталогов в /app/portal. Как я могу изменить владельца всего пути, созданного томом, на uid 1000?
Я попытался добавить пользователя: «1000:100» в Docker Compose YAML, но это не сработало. Предварительное создание /app/portal и предварительное изменение владельца всего пути на uid 1000 в Dockerfile может решить эту проблему, но это кажется немного странным.
Мне нужны только логи. /app/portal не существует в образе. Он создается приложением.


Docker автоматически создает для вас каталог с набором разрешений, который не соответствует вашему желанию. Вероятно, вам придется либо смонтировать этот родительский каталог как том, либо создать его в Dockerfile, либо и то, и другое; установка родителя облегчит получение разрешений.
volumes:
- /data:/app/portal
# ^^^^^^^^^^^ for the entire writable directory
user: 1000:1000 # matching the numeric owner for this directory on this system
Docker необходимо создать файловую систему контейнера, прежде чем он сможет запустить процесс. В комментарии вы уточняете, что каталога /app/portal на изображении нет. Но ваш файл Compose монтирует содержимое на /app/portal/logs. Это означает, что Docker необходимо создать точку монтирования, что также означает, что ему необходимо создать каталог, в котором она будет храниться.
На этом этапе Docker необходимо выбрать владельца и разрешения. «Принадлежит пользователю root» — это один из нескольких разумных вариантов, которые он может сделать, но он не работает для вашего приложения.
Я упоминал, что вы также можете создать каталог в изображении. Наверное, это хорошая идея
RUN adduser -D appuser
RUN mkdir /app/portal && chown appuser:appuser /app/portal
В вашем текущем файле Docker это позволит избежать проблемы с разрешениями: родительский каталог будет существовать, а его владелец на изображении будет соответствовать user: в файле Compose. Однако в целом вы не можете гарантировать, что среда выполнения user: будет точно соответствовать тому, что встроено в образ. В этом последнем фрагменте я удалил конкретный числовой идентификатор пользователя из файла Dockerfile; но это означает, что вам всегда нужно будет монтировать том по всему доступному для записи каталогу, если вы собираетесь использовать нестандартный user:.
Можете ли вы смонтировать том на весь каталог
/app/portal? Есть ли/app/portalв вашем изображении?