Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як уникнути проблем з власником файлів між контейнером і хостом?

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 для каталогів запису).

Докладніше в документації: Dockerfile: COPY --chown

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання