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

Docker环境下Nginx容器无法加载静态文件求助

问题:Laravel项目Docker部署后静态文件404排查

背景信息

  • 基于composer:2.7.7和php:8.3.3-fpm-alpine3.19构建Docker镜像,镜像内安装node.js及依赖,执行composer update、composer install、npm install vite、npm run build并设置文件权限
  • 配置docker-compose.yml,包含PHP-FPM、Nginx、MySQL服务
  • 编写Nginx配置尝试路由静态文件,但浏览器控制台出现静态文件404错误,不确定是否需要挂载静态文件卷

相关配置文件

Dockerfile

FROM composer:2.7.7
FROM php:8.3.3-fpm-alpine3.19

# Install required packages
RUN apk add --no-cache nodejs npm

RUN docker-php-ext-install pdo_mysql

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

COPY --from=0 /usr/bin/composer /usr/bin/composer
# Ensure permissions are set correctly
RUN chmod -R 755 /var/www/html/public/build/assets
USER www-data

#composer run commands
RUN composer update
RUN composer install

#npm run commands
RUN npm install vite
RUN npm run build
USER root

docker-compose.yml

version: '3.8'

services:
    rental-project:
        image: rental-project:0.14.0
        container_name: rental-project
        env_file:
            - .env
        networks:
            - rentalProject-api-network

    web-server:
        image: nginx:1.24.0-alpine-slim
        container_name: web-server
        ports:
            - "8080:80"
        volumes:
            - ./laravel.conf:/etc/nginx/conf.d/default.conf
        networks:
            - rentalProject-api-network

    mysql:
        image: mysql:latest
        container_name: mysql_container
        environment:
            MYSQL_ROOT_PASSWORD: secret
            MYSQL_DATABASE: rentalProject
            MYSQL_USER: rentalProject
            MYSQL_PASSWORD: secret
        volumes:
            - mysql_data:/var/lib/mysql
            - ./dumps:/docker-entrypoint-initdb.d
        networks:
            - rentalProject-api-network

volumes:
    mysql_data:
    
networks:
    rentalProject-api-network:

Nginx配置文件(laravel.conf)

server {
    listen 80 default_server;
    listen [::]:80 default_server;

    root /var/www/html/public;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";

    index index.php;

    charset utf-8;

    location / {
        try_files $uri $uri /index.php?$query_string;
    }

    location /assets {
        alias /var/www/html/public/build/assests;
        autoindex on;
        autoindex_exact_size off;
        autoindex_localtime on;
    }

    location = /favicon.ico { access_log off; log_not_found off; }
    location = /robots.txt  { access_log off; log_not_found off; }

    error_page 404 /index.php;


    location ~ \.php$ {
        fastcgi_pass rental-project:9000;
        fastcgi_param SCRIPT_FILENAME $document_root/$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }
}

问题排查及解决方案

1. Nginx配置拼写错误

Nginx的/assets location块中,alias路径写为/var/www/html/public/build/assests——assets拼写成了assests,少了一个s,这是直接导致404的核心原因,修正后:

location /assets {
    alias /var/www/html/public/build/assets;
    autoindex on;
    autoindex_exact_size off;
    autoindex_localtime on;
}

2. Nginx无法访问PHP容器内的静态文件

当前docker-compose中,Nginx容器未挂载PHP容器内的静态文件目录,Nginx自身容器不存在/var/www/html/public/build/assets路径,即使修正拼写也无法找到文件。

解决方式有两种:

  • 方式一:共享静态文件目录(推荐)
    在docker-compose.yml中添加命名卷,让PHP和Nginx共享静态文件目录:

    services:
        rental-project:
            # 其他配置不变
            volumes:
                - rental-project-static:/var/www/html/public/build/assets
        web-server:
            # 其他配置不变
            volumes:
                - ./laravel.conf:/etc/nginx/conf.d/default.conf
                - rental-project-static:/var/www/html/public/build/assets
    # 新增命名卷
    volumes:
        mysql_data:
        rental-project-static:
    
  • 方式二:通过PHP-FPM转发静态文件(临时方案)
    删除单独的/assets location块,依赖根路径的try_files规则让PHP-FPM处理静态请求,但会增加PHP-FPM负载,不建议生产环境使用。

3. 静态文件卷挂载的必要性

  • 开发环境:需要挂载本地public/build/assets目录到容器,方便修改前端代码后实时生效:
    rental-project:
        volumes:
            - ./public/build/assets:/var/www/html/public/build/assets
    web-server:
        volumes:
            - ./laravel.conf:/etc/nginx/conf.d/default.conf
            - ./public/build/assets:/var/www/html/public/build/assets
    
  • 生产环境:静态文件已在镜像构建时生成,无需挂载卷,通过共享命名卷让Nginx访问镜像内的静态文件即可。

4. Dockerfile优化建议

  • 生产环境建议使用composer install配合composer.lock文件,替代composer update,保证依赖版本一致。
  • 将vite添加到项目package.json的依赖中,直接执行npm install即可,无需单独安装。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 11:37:27