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

Чому Laravel у контейнері падає з помилкою «Permission denied» на storage і як це виправити?

Laravel пише у два каталоги:

  • storage/ - логи, скомпільовані шаблони Blade, файловий кеш, сесії, завантаження на диск local;
  • bootstrap/cache/ - кеш конфігурації, маршрутів, подій, packages.php, services.php.

Типова помилка:

The stream or file "/var/www/html/storage/logs/laravel.log" could not be opened in append mode: Failed to open stream: Permission denied

Причина: процес PHP працює від одного користувача (www-data, UID 33 в офіційних образах Debian чи 82 в Alpine), а файли належать іншому - найчастіше root, бо COPY у Dockerfile за замовчуванням створює файли власника root.

Виправлення в Dockerfile:

COPY --chown=www-data:www-data . /var/www/html

# або для вже скопійованих файлів - лише каталоги для запису
RUN chown -R www-data:www-data storage bootstrap/cache \
 && chmod -R ug+rwX storage bootstrap/cache

USER www-data

--chown при COPY кращий за окремий RUN chown -R: окремий chown створює ще один шар з копією всіх файлів і збільшує образ.

Чого не робити:

  • chmod -R 777 storage - «працює», але дає запис усім і маскує справжню проблему;
  • запускати PHP від root, щоб «не було проблем з правами» - якщо зловмисник виконає код, він отримає root у контейнері.

Типові пастки:

  • bind mount у розробці (./:/var/www/html) - файли мають власника з хоста (UID 501 на macOS, 1000 на Linux). На Linux процес у контейнері з іншим UID не може писати. Рішення - запускати PHP з UID розробника (Sail робить це через WWWUSER);
  • том для storage створюється при першому запуску з правами root - потрібно задати власника в образі до оголошення тому чи при старті;
  • файли, створені php artisan від root через docker exec (наприклад, кеш конфігурації чи лог) потім недоступні для www-data. Виконувати команди від того самого користувача: docker exec -u www-data app php artisan ....

Докладніше в документації: Laravel: права на каталоги

1

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