Траблшутинг прав доступа к томам Docker: сопоставление UID/GID и chown
- Ошибка
EACCES: permission denied, open '/app/data/...'внутри контейнера. - Файлы, созданные контейнером, принадлежат пользователю
rootна хосте. - Блокировка монтирования каталогов политиками безопасности SELinux.
1. Запуск контейнера с UID и GID текущего пользователя хоста
docker run -d \
--name app \
--user $(id -u):$(id -g) \
-v /opt/data:/app/data \
my_image:latest2. Решение проблем с блокировками SELinux (флаги :z и :Z)
# Флаг :z — разрешает совместный доступ нескольких контейнеров к папке хоста
docker run -v /data/shared:/app/data:z my_image
# Флаг :Z — назначает приватный неразделяемый контекст контейнера
docker run -v /data/private:/app/data:Z my_image3. Использование entrypoint-скрипта с утилитой gosu (Drop Privileges)
Создайте entrypoint.sh для динамической смены владельца тома:
#!/bin/sh
USER_ID=${LOCAL_UID:-9001}
GROUP_ID=${LOCAL_GID:-9001}
# Создаем пользователя с динамическим UID хоста
groupadd -g $GROUP_ID appgroup 2>/dev/null || true
useradd -u $USER_ID -g $GROUP_ID -s /bin/sh appuser 2>/dev/null || true
chown -R $USER_ID:$GROUP_ID /app/data
exec gosu appuser "$@"4. Исправление прав на хосте
chown -R 1000:1000 /opt/data && chmod -R 775 /opt/data Частые вопросы (FAQ)
В чем отличие утилиты gosu от стандартной команды sudo / su?
Команда su/sudo создает дочерний процесс, что ломает проброс сигналов SIGTERM процессу приложения. gosu заменяет текущий процесс через системный вызов exec, сохраняя PID 1.
Почему тома Named Volumes не имеют проблем с UID в отличие от Bind Mounts?
При создании нового Named Volume Docker автоматически копирует права доступа и владельца из целевой папки образа в каталог тома на хосте (/var/lib/docker/volumes/).