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

Docker部署VueJS应用Nginx报403目录索引禁止及503错误

问题现象
  • 使用Nginx容器化部署VueJS应用时服务持续报错,Nginx错误日志重复输出以下内容:
[error] 8#8: *1 directory index of "/etc/nginx/html/" is forbidden, client: x.x.x.x, server: localhost, request: "GET / HTTP/1.1", host: "x.x.x.x:80"
  • 浏览器访问服务返回503 Service Temporarily Unavailable - nginx提示

现有配置

Dockerfile

FROM nginx:1.17-alpine

# Copy built app into nginx 
COPY /dist /etc/nginx/html/studio

# copy nginx conf
COPY nginx.conf /etc/nginx/nginx.conf

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"';
  sendfile        on;
  keepalive_timeout  65;

  map $http_user_agent $loggable {
    "~kube-probe/.*"        0;
    default                 1;
  }
  access_log  /var/log/nginx/access.log main if=$loggable;

  server {
    listen       80;
    server_name  localhost;

    location /studio/ {
      try_files $uri $uri/ /studio/index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   html;
    }
  }
}

根因分析
  1. 根路径无匹配规则:当前配置仅为/studio/路径设置了路由规则,访问根路径/时Nginx会 fallback 到默认静态目录查找资源,该路径下没有配置默认首页index.html,同时未开启目录列表权限,因此抛出directory index is forbidden错误。
  2. 缺少显式root配置:/studio/的location块未指定静态资源根目录,Nginx自动拼接路径时会出现寻址偏差,即使直接访问/studio/路径也可能找不到对应文件。
  3. 子路径部署适配缺失:如果要把应用部署在/studio/子路径下,Vue构建时的publicPath参数未同步配置,会导致静态资源加载失败。

排查思路
  • 先进入运行中的容器执行ls /etc/nginx/html/studio,确认index.html、js/css/img等静态资源是否存在,排除Docker COPY命令执行错误导致的文件缺失问题。
  • 检查Nginx配置中所有对外暴露的访问路径是否都有对应的location匹配规则,重点确认根路径/的处理逻辑。
  • 核对location块内root/alias配置与实际文件存放路径是否一致,避免路径拼接错误。
  • 如果使用Vue Router的history模式,确认try_files规则是否正确配置,避免刷新页面出现403/404错误。
  • 若部署在K8s集群中,额外检查Service是否正确关联Pod端口、Ingress转发规则是否配置正确,排除网络层面的转发故障。

修复方案

根据实际部署需求二选一即可:

场景1:应用部署在根路径(直接访问IP/域名即可打开应用)

  1. 修改Dockerfile,将构建产物复制到Nginx官方镜像默认的静态资源目录:
FROM nginx:1.17-alpine
# 把dist目录下的所有文件直接复制到nginx默认静态目录
COPY /dist /usr/share/nginx/html/
COPY nginx.conf /etc/nginx/nginx.conf
# 修正静态目录权限,避免nginx用户无读权限
RUN chown -R nginx:nginx /usr/share/nginx/html
  1. 修改nginx.conf,补充根路径路由规则、显式指定root目录:
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"';
  sendfile        on;
  keepalive_timeout  65;

  map $http_user_agent $loggable {
    "~kube-probe/.*"        0;
    default                 1;
  }
  access_log  /var/log/nginx/access.log main if=$loggable;

  server {
    listen       80;
    server_name  localhost;
    # 显式指定静态资源根目录
    root /usr/share/nginx/html;
    index index.html;
    # 关闭目录索引,避免安全风险
    autoindex off;

    # 根路径适配Vue Router history模式
    location / {
      try_files $uri $uri/ /index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /usr/share/nginx/html;
    }
  }
}
  1. 确认Vue项目vue.config.js中publicPath配置为'/'(默认值即为/,未修改过则无需调整),重新执行npm run build生成最新dist包后构建镜像即可。

场景2:应用部署在/studio/子路径(访问IP/studio/打开应用)

  1. 原有Dockerfile的复制逻辑无需调整,补充权限修正命令即可:
FROM nginx:1.17-alpine

COPY /dist /etc/nginx/html/studio
COPY nginx.conf /etc/nginx/nginx.conf
RUN chown -R nginx:nginx /etc/nginx/html
  1. 修改nginx.conf,补充根路径跳转规则、子路径root配置:
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"';
  sendfile        on;
  keepalive_timeout  65;

  map $http_user_agent $loggable {
    "~kube-probe/.*"        0;
    default                 1;
  }
  access_log  /var/log/nginx/access.log main if=$loggable;

  server {
    listen       80;
    server_name  localhost;
    root /etc/nginx/html;
    index index.html;
    autoindex off;

    # 访问根路径时自动跳转到子路径
    location = / {
      return 302 /studio/;
    }

    # 子路径适配Vue Router history模式
    location /studio/ {
      try_files $uri $uri/ /studio/index.html;
    }

    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
      root   /etc/nginx/html;
    }
  }
}
  1. 修改Vue项目vue.config.js,配置publicPath匹配子路径:
module.exports = {
  publicPath: '/studio/'
}

重新执行npm run build生成最新dist包后构建镜像即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 21:36:25