You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel10+Docker环境注册用户时出现权限拒绝错误求助

Laravel 10 Docker环境日志文件权限问题修复方案

问题描述

搭建Laravel 10的Docker环境后应用可正常运行,但尝试向数据库添加新用户时触发权限错误:

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

已在Dockerfile中添加RUN chown -R www-data:www-data /var/www修改目录所有者,但问题仍未解决。

相关配置文件

Dockerfile

FROM php:8.2-fpm

COPY php.ini /usr/local/etc/php/
COPY docker.conf /usr/local/etc/php-fpm.d/docker.conf
COPY .bashrc /root/

RUN apt-get update \
&& apt-get install -y build-essential zlib1g-dev default-mysql-client curl gnupg procps vim git unzip libzip-dev libpq-dev \
&& docker-php-ext-install zip pdo_mysql pdo_pgsql pgsql
RUN apt-get update && apt-get install -y \
libfreetype-dev \
libjpeg62-turbo-dev \
libpng-dev \
&& docker-php-ext-configure gd --with-freetype --with-jpeg \
&& docker-php-ext-install -j$(nproc) gd
RUN apt-get install -y libicu-dev \
&& docker-php-ext-configure intl \
&& docker-php-ext-install intl
RUN pecl install xdebug-3.2.1 \
&& pecl install pcov \
&& docker-php-ext-enable xdebug pcov \
&& echo ";;zend_extension=xdebug" > /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini
RUN apt-get update && apt-get install -y libmemcached-dev libssl-dev zlib1g-dev \
&& pecl install memcached-3.2.0 \
&& docker-php-ext-enable memcached
RUN curl -sL https://deb.nodesource.com/setup_18.x | bash -
RUN apt-get install -y nodejs
RUN npm install npm@latest -g
RUN npm install yarn -g
RUN php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
RUN php composer-setup.php
RUN php -r "unlink('composer-setup.php');"
RUN mv composer.phar /usr/local/bin/composer
ENV COMPOSER_ALLOW_SUPERUSER 1
ENV COMPOSER_HOME /composer
ENV PATH $PATH:/composer/vendor/bin
RUN composer config --global process-timeout 3600
RUN composer global require "laravel/installer"

WORKDIR /root
RUN git clone https://github.com/seebi/dircolors-solarized

RUN chown -R www-data:www-data /var/www
EXPOSE 5173
WORKDIR /var/www

docker-compose.yml

version: '3'
name: laravel-project

services:
    ### PHP ###    
    php:
        build: .docker/php
        ports:
            - 5173:5173
        container_name: project_php 
        restart: unless-stopped
        volumes:
            - ./src:/var/www:cached

    ### Nginx ###
    nginx:
        image: nginx
        ports:
            - 80:80
        container_name: project_nginx
        restart: unless-stopped
        volumes:
            - ./src:/var/www
            - .docker/nginx/default.conf:/etc/nginx/conf.d/default.conf
            - .docker/nginx/nginx.conf:/etc/nginx/nginx.conf
        depends_on:
            - php
            - db
            - redis

    ### Database (MySQL)
    db:
        image: mysql:8.1
        ports:
            - 3306:3306
        container_name: project_db_MySQL
        restart: unless-stopped
        volumes:
            - .docker/db/data:/var/lib/mysql
            - .docker/logs:/var/log/mysql
            - .docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
            - .docker/db/sql:/docker-entrypoint-initdb.d
        environment:
            MYSQL_ROOT_PASSWORD: M$08154711$b
            MYSQL_DATABASE: indeed_db
            MYSQL_USER: indeed_user
            MYSQL_PASSWORD: qKFHxzq4yvtisrlNxPvS

    ### Database (MariaDB)
      # db:
      #     image: mariadb:latest
      #     ports:
      #         - 3306:3306
      #     container_name: project_db_mariaDB
      #     volumes:
      #         - .docker/db/data:/var/lib/mysql
      #         - .docker/logs:/var/log/mysql
      #         - .docker/db/my.cnf:/etc/mysql/conf.d/my.cnf
      #         - .docker/db/sql:/docker-entrypoint-initdb.d
      #     environment:
      #         MYSQL_ROOT_PASSWORD: root
      #         MYSQL_DATABASE: laravel_db_name
      #         MYSQL_USER: laravel_db_user
      #         MYSQL_PASSWORD: laravel_db_pass

    ### phpMyAdmin ###
    phpmyadmin:
        image: phpmyadmin/phpmyadmin
        ports:
            - 8080:80
        links:
            - db
        container_name: project_phpMyAdmin
        environment:
            PMA_HOST: db
            PMA_PORT: 3306
            PMA_ARBITRARY: 1
        volumes:
            - .docker/phpmyadmin/sessions:/sessions

    ### Redis ###
    redis:
        image: redis:latest
        container_name: project_redis
        restart: unless-stopped
        volumes:
            - redis:/var/lib/redis
            - redis-data:/data
            - redis-config:/us/local/etc/redis/redis.conf
        ports:
            - 6379:6379
        command: ["redis-server", "--appendonly", "yes"]
    ### Mailpit ###
    mail:
        image: axllent/mailpit:latest
        ports:
            - 8025:8025
            - 1025:1025
        restart: unless-stopped
        container_name: project_mail_mailpit

    ### Mailhog ###
    # mail1:
    #     image: mailhog/mailhog:latest
    #     logging: 
    #         driver: "none"
    #     container_name: project_mail_mailhog
    #     restart: unless-stopped
    #     ports: 
    #         - 8025:8025
    #         - 1025:1025

    ### Redis-Commander
    # redis-commander:
    #     image: rediscommander/redis-commander:latest
    #     restart: unless-stopped
    #     environment:
    #         REDIS_HOSTS: local:redis:6379
    #         REDIS_PASSWORD: $(REDIS_PASSWORD)
    #         HTTP_USER: root
    #         HTTP_PASSWORD: M$08154711$b
    #     container_name: project_redis_commander
    #     ports:
    #         - 8081:8081
    #     depends_on:
    #         - redis

volumes:
    redis:
    redis-data:
    redis-config: 

Nginx default.conf

server {
  listen 80;
  index index.php index.html;
  root /var/www/public;

  client_max_body_size 100M; # 413 Request Entity Too Large

  location / {
    root /var/www/public;
    index  index.html index.php;
    try_files $uri $uri/ /index.php?$query_string;
  }

  location ~ \.php$ {
    try_files $uri =404;
    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    fastcgi_pass php:9000;
    fastcgi_read_timeout 3600;
    fastcgi_index index.php;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param PATH_INFO $fastcgi_path_info;
    send_timeout 3600;
    proxy_connect_timeout 3600;
    proxy_read_timeout    3600;
    proxy_send_timeout    3600;
  }
}

Nginx nginx.conf

user  nginx;
worker_processes  1;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    server_tokens off;
    chunked_transfer_encoding off;

    gzip on;
    gzip_types application/json;
    gzip_min_length 1000;

    include /etc/nginx/conf.d/*.conf;
}

问题原因

Dockerfile中执行chown的时机错误——构建镜像时修改了/var/www权限,但启动容器时本地./src目录被挂载到/var/www,挂载操作会覆盖容器内原目录的权限设置,导致storage目录的所有者为本地系统用户,而非容器内的www-data。

修复方案

方案1:容器启动后手动修正权限

进入PHP容器执行命令:

docker exec -it project_php chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache

直接修正Laravel需要写入权限的两个核心目录。

方案2:添加容器启动脚本自动修正权限

  1. 在.docker/php目录下创建startup.sh脚本:
#!/bin/bash
chown -R www-data:www-data /var/www/storage /var/www/bootstrap/cache
php-fpm
  1. 给脚本添加执行权限:
chmod +x .docker/php/startup.sh
  1. 修改Dockerfile,添加复制脚本并设置为启动命令:
    在Dockerfile末尾追加:
COPY startup.sh /usr/local/bin/startup.sh
RUN chmod +x /usr/local/bin/startup.sh
CMD ["startup.sh"]

每次容器启动时,会自动修正权限后再启动php-fpm。

方案3:调整本地目录权限(开发环境适用)

在本地项目目录执行:

sudo chown -R 33:33 ./src/storage ./src/bootstrap/cache

33是Debian/Ubuntu系统中www-data用户默认的UID,挂载后容器内的www-data即可正常读写目录。

方案4:使用Laravel自带命令修复

进入容器执行:

docker exec -it project_php php artisan storage:link
docker exec -it project_php chmod -R 775 /var/www/storage
docker exec -it project_php chown -R www-data:www-data /var/www/storage

内容的提问来源于stack exchange,提问作者Mario Basten

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 10:47:02