Linux визначає права за числовими ідентифікаторами користувача й групи (UID/GID), а не за іменами. Контейнер і хост ділять ядро, тож файл, створений у контейнері процесом з UID 33 (www-data у Debian), на хості належатиме користувачу з UID 33 - яким би не було його ім'я.
Типові симптоми:
- у розробці з bind mount: застосунок у контейнері (UID 33 чи root) створює файли в
storage/іvendor/- на хості розробник (UID 1000) не може їх змінити чи видалити безsudo. Або навпаки: контейнер не може писати в каталог, створений на хості; - у продакшені: «Permission denied» при записі в
storage/logsчиbootstrap/cache, бо файли скопійовано з власникомroot, а процес працює якwww-data.
Рішення в образі:
FROM php:8.5-fpm
COPY --chown=www-data:www-data . /var/www/html
USER www-data
COPY --chown- власник одразу при копіюванні, без окремогоRUN chown -R(той дублює всі файли в новому шарі);USER- процес працює не від root.
Рішення для розробки - узгодити UID:
ARG UID=1000
ARG GID=1000
RUN groupmod -o -g ${GID} www-data && usermod -o -u ${UID} -g ${GID} www-data
docker compose build --build-arg UID=$(id -u) --build-arg GID=$(id -g)
Тепер www-data у контейнері має той самий UID, що й розробник на хості, - файли з обох сторін належать одній людині. Так робить Laravel Sail (WWWUSER, WWWGROUP).
Альтернативи:
docker run --user $(id -u):$(id -g)- запуск від імені користувача хоста (але в образі може не бути такого користувача й домашнього каталогу);- іменовані томи замість bind mount для
vendor,node_modules- вони живуть у Docker, без конфлікту з хостом; - rootless Docker чи
userns-remap- root у контейнері відображається на непривілейованого користувача хоста.
На macOS і Windows з Docker Desktop проблема менш помітна: файлова система хоста монтується у віртуальну машину з перетворенням власників. Тому налаштування, що «працює на Mac», ламається на Linux-сервері чи в CI.
Пастка chmod -R 777 - «швидке рішення» проблем з правами, яке дає будь-якому процесу право змінювати код застосунку. Правильно - потрібний власник і мінімальні права (775 для каталогів запису).