Как настроить права на чтение/запись Laravel
Пожалуйста помоги. Я бьюсь над этой проблемой уже битый день. Я перепробовал множество ответов из Интернета, в том числе и со Stackoverflow, но никак не могу решить следующую проблему.
Есть проект на Laravel, окружение в Docker: NGINX, PHP-FPM, MYSQL, REDIS. Мой docker-compose.yml имеет следующий вид:
version: '3'
services:
nginx:
build:
context: ./docker/nginx
depends_on:
- php-fpm
environment:
- TZ=Europe/Moscow
networks:
- sail
ports:
- "${NGINX_HOST_HTTPS_PORT}:443"
- "${NGINX_HOST_HTTP_PORT}:80"
volumes:
- ${NGINX_SSL_PATH}:/etc/nginx/ssl
- ./:/var/www/myproject
- ${NGINX_HOST_LOG_PATH}:/var/log/nginx
- ${NGINX_SITES_PATH}:/etc/nginx/sites-available
php-fpm:
build:
context: ./docker/php-fpm
volumes:
- ./:/var/www/myproject
networks:
- sail
expose:
- 9000
environment:
- TZ=Europe/Moscow
mysql:
image: 'mysql/mysql-server:8.0'
ports:
- '${FORWARD_DB_PORT:-3306}:3306'
environment:
MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}'
MYSQL_ROOT_HOST: '%'
MYSQL_DATABASE: '${DB_DATABASE}'
MYSQL_USER: '${DB_USERNAME}'
MYSQL_PASSWORD: '${DB_PASSWORD}'
MYSQL_ALLOW_EMPTY_PASSWORD: 1
volumes:
- 'sail-mysql:/var/lib/mysql'
- './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh'
networks:
- sail
healthcheck:
test:
- CMD
- mysqladmin
- ping
- '-p${DB_PASSWORD}'
retries: 3
timeout: 5s
redis:
image: 'redis:alpine'
ports:
- '${FORWARD_REDIS_PORT:-6379}:6379'
volumes:
- 'sail-redis:/data'
networks:
- sail
healthcheck:
test:
- CMD
- redis-cli
- ping
retries: 3
timeout: 5s
networks:
sail:
driver: bridge
volumes:
sail-mysql:
driver: local
sail-redis:
driver: local
Dockerfile NGINX выглядит так:
FROM nginx:alpine
COPY nginx.conf /etc/nginx/
RUN apk update \
&& apk upgrade \
&& apk --update add logrotate \
&& apk add --no-cache openssl \
&& apk add --no-cache bash
RUN apk add --no-cache curl
RUN set -x ; \
addgroup -g 82 -S www-data ; \
adduser -u 82 -D -S -G www-data www-data && exit 0 ; exit 1
ARG PHP_UPSTREAM_CONTAINER=php-fpm
ARG PHP_UPSTREAM_PORT=9000
# Create 'myapp' file used from 'logrotate'
RUN touch /var/log/myproject
# Copy 'logrotate' config file
COPY logrotate/nginx /etc/logrotate.d/
# Set upstream conf and remove the default conf
RUN echo "upstream php-upstream { server ${PHP_UPSTREAM_CONTAINER}:${PHP_UPSTREAM_PORT}; }" > /etc/nginx/conf.d/upstream.conf \
&& rm /etc/nginx/conf.d/default.conf
#ADD ./startup.sh /opt/startup.sh
#RUN sed -i 's/\r//g' /opt/startup.sh
#CMD ["/bin/bash", "/opt/startup.sh"]
EXPOSE 80 81 443
PHP-FRPM Dockerfile имеет также такой вид:
FROM php:8.1-fpm
MAINTAINER svinpauk78@gmail.com
ENV COMPOSER_MEMORY_LIMIT='-1'
WORKDIR /var/www/messenger
RUN apt-get update && \
apt-get install -y --force-yes --no-install-recommends \
libmemcached-dev \
libzip-dev \
libz-dev \
libzip-dev \
libpq-dev \
libjpeg-dev \
libpng-dev \
libfreetype6-dev \
libssl-dev \
openssh-server \
libmagickwand-dev \
git \
cron \
nano \
libxml2-dev \
libreadline-dev \
libgmp-dev \
mariadb-client \
unzip \
jpegoptim \
optipng \
pngquant \
gifsicle
# Install soap extention
RUN docker-php-ext-install soap
# Install for image manipulation
RUN docker-php-ext-install exif
...
#####################################
# PHPRedis:
#####################################
RUN pecl install redis && docker-php-ext-enable redis
#####################################
# Imagick:
#####################################
RUN pecl install imagick && \
docker-php-ext-enable imagick
#####################################
# GD:
#####################################
# Install the PHP gd library
RUN docker-php-ext-install gd && \
docker-php-ext-configure gd --with-freetype --with-jpeg && \
docker-php-ext-install gd
#####################################
# xDebug:
#####################################
# Install the xdebug extension
RUN pecl install xdebug
#####################################
# PHP Memcached:
#####################################
# Install the php memcached extension
RUN pecl install memcached && docker-php-ext-enable memcached
#####################################
# Composer:
#####################################
# Install composer and add its bin to the PATH.
RUN curl -s http://getcomposer.org/installer | php && \
echo "export PATH=${PATH}:/var/www/vendor/bin" >> ~/.bashrc && \
mv composer.phar /usr/local/bin/composer
# Source the bash
RUN . ~/.bashrc
#####################################
# Laravel Schedule Cron Job:
#####################################
RUN echo "* * * * * www-data /usr/local/bin/php /var/www/artisan schedule:run >> /dev/null 2>&1" >> /etc/cron.d/laravel-scheduler
RUN chmod 0644 /etc/cron.d/laravel-scheduler
#
#--------------------------------------------------------------------------
# Final Touch
#--------------------------------------------------------------------------
#
ADD ./laravel.ini /usr/local/etc/php/conf.d
#####################################
# Aliases:
#####################################
# docker-compose exec php-fpm dep --> locally installed Deployer binaries
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/vendor/bin/dep "$@"' > /usr/bin/dep
RUN chmod +x /usr/bin/dep
# docker-compose exec php-fpm art --> php artisan
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/artisan "$@"' > /usr/bin/art
RUN chmod +x /usr/bin/art
# docker-compose exec php-fpm migrate --> php artisan migrate
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/artisan migrate "$@"' > /usr/bin/migrate
RUN chmod +x /usr/bin/migrate
# docker-compose exec php-fpm fresh --> php artisan migrate:fresh --seed
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/artisan migrate:fresh --seed' > /usr/bin/fresh
RUN chmod +x /usr/bin/fresh
# docker-compose exec php-fpm t --> run the tests for the project and generate testdox
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/artisan config:clear\n/var/www/vendor/bin/phpunit -d memory_limit=2G --stop-on-error --stop-on-failure --testdox-text=tests/report.txt "$@"' > /usr/bin/t
RUN chmod +x /usr/bin/t
# docker-compose exec php-fpm d --> run the Laravel Dusk browser tests for the project
RUN echo '#!/bin/bash\n/usr/local/bin/php /var/www/artisan config:clear\n/bin/bash\n/usr/local/bin/php /var/www/artisan dusk -d memory_limit=2G --stop-on-error --stop-on-failure --testdox-text=tests/report-dusk.txt "$@"' > /usr/bin/d
RUN chmod +x /usr/bin/d
RUN rm -r /var/lib/apt/lists/*
RUN usermod -u 1000 www-data
# Add user for laravel application
#RUN groupadd -g 1000 www-data
#RUN useradd -u 1000 -ms /bin/bash -g www-data www-data
# Copy existing application directory permissions
COPY --chown=www-data:www-data . /var/www/messenger
# Change current user to www-data
USER www-data
#COPY ./docker-entrypoint.sh /usr/local/bin/
#RUN chmod +x /usr/local/bin/docker-entrypoint.sh
#RUN ln -s /usr/local/bin/docker-entrypoint.sh /
#ENTRYPOINT ["docker-entrypoint.sh"]
EXPOSE 9000
CMD ["php-fpm"]
Проект собирается, запускается отлично. Я работаю на сервере из под пользователя root. Далее я дал все необходимые права и добавил пользователя www-data на свой сервер следующим образом:
chown -R www-data:www-data /var/www/myproject
sudo usermod -a -G www-data $USER
sudo chmod -R 775 /var/www/myproject/storage
Далее я установил библиотеку для Laravel - Spatie Media Library, которая предназначена для работы с изображениями и другими файлами в проекте.
Проблема: при загрузке файлов на сервер у них слетают права на чтение и прочитать их становится невозможно. Клиент получает ошибку 404 и все. Хотя файл на сервере есть. Файл можно прочитать и загрузить с сервера только если я снова выполню команду:
sudo chmod -R 775 /var/www/myproject/storage
Когда снова загрузить новые файлы на сервер, у них снова сбрасываются права. Я выполнил команду ls -l storage/app/public/uploads (директория для сохранения загружаемых файлов) и вот что она выводит (красным отмечены новые загруженные файлы)
Соответсвенно эти файлы снова нельзя прочитать. Как мне исправить данную проблему, чтобы новые загружаемые файлы на сервер можно было без проблем прочитать и у них не слетали права? Что я делаю не так?