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

使用Vite+Nginx+Docker Compose部署Vue应用时出现500错误

问题:Vue+Vite+Nginx本地部署出现500内部服务器错误

技术栈

  • 前端:Vue
  • 构建工具:Vite
  • 部署方式:Nginx(本地Docker部署)

问题现象

完成本地部署后,访问http://localhost:8080时触发500内部服务器错误。浏览器开发者工具Sources面板无额外信息,无法定位问题根源。

项目相关文件

项目目录结构

├── Makefile
├── app
│   ├── capacitor
│   │   └── capacitor.config.ts
│   ├── dist
│   │   ├── css
│   │   │   └── chunk-vendors.a51efc20.css
│   │   ├── index.html
│   │   └── js
│   │       ├── app.38461d29.js
│   │       ├── app.38461d29.js.map
│   │       ├── chunk-vendors.6a82c935.js
│   │       └── chunk-vendors.6a82c935.js.map
│   ├── package-lock.json
│   ├── package.json
│   ├── public
│   │   └── index.html
│   ├── src
│   │   ├── App.vue
│   │   ├── main.js
│   │   ├── router
│   │   │   └── index.js
│   │   └── views
│   │       └── Home.vue
│   └── vite.config.js
├── docker-compose.yml
├── dockerfiles
│   ├── android-build.Dockerfile
│   ├── web-build.Dockerfile
│   ├── web-serve.Dockerfile
├── scripts
│   └── generate-env.sh
└── server
    └── nginx.conf

web-build.Dockerfile(构建dist目录)

FROM node:20-alpine AS build
COPY app /app
WORKDIR /app
RUN npm install && npm install @vue/cli-service
CMD npx vue-cli-service build

web-serve.Dockerfile(部署dist目录)

FROM nginx:stable-alpine
COPY /app/dist /usr/share/nginx/html/
COPY /server/nginx.conf /etc/nginx/nginx.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]

Docker Compose配置片段

services:
  web-builder:
    build:
      dockerfile: dockerfiles/web-build.Dockerfile
    volumes:
      - ./app/dist:/app/dist

  web-server:
    build:
      dockerfile: dockerfiles/web-serve.Dockerfile
    ports:
       - "8080:80"

vite.config.js

import {defineConfig} from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
    plugins: [vue()],
    // base: './',
    root: '.',
    build: {
        outDir: 'dist',
        emptyOutDir: true,
        rollupOptions: {
            input: {
                main: 'public/index.html'
            }
        },
        manifest: true
    },
    publicPath: '/'
});

public/index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>Urban Umbrella</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="../src/main.js"></script>
</body>
</html>

src/main.js

import {createApp} from 'vue';
import App from './App.vue';

import {createRouter, createWebHistory} from 'vue-router';
import routes from './router';

import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue-next/dist/bootstrap-vue-next.css';

import {createBootstrap} from 'bootstrap-vue-next';

const router = createRouter({
    // history: createWebHistory(),
    routes,
});

const app = createApp(App);

app.use(createBootstrap());
app.use(router);

app.mount('#app');

src/App.vue

<template>
  <div id="app">
    <router-view></router-view>
  </div>
</template>

<script>
import { defineComponent } from 'vue';

export default defineComponent({
  name: 'App',
});
</script>

src/router/index.js

import {createRouter, createWebHistory} from 'vue-router';
import Home from '../views/Home.vue';

const routes = [
    {path: '/', component: Home},
];

const router = createRouter({
    history: createWebHistory(),
    routes,
});

export default router;

server/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;
    keepalive_timeout 65;
    server
    {
        listen 80;
        server_name localhost;
        location /
        {
            root /app;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
        error_page 500 502 503 504 /50x.html;
        location = /50x.html
        {
            root /usr/share/nginx/html;
        }
    }
}

调试排查思路

1. 查看Nginx错误日志

500错误优先排查Nginx错误日志,进入容器执行以下命令:

# 获取web-server容器ID
docker ps
# 进入容器
docker exec -it <容器ID> /bin/sh
# 查看错误日志
cat /var/log/nginx/error.log

日志会直接指出错误原因,比如文件路径不存在、权限不足等。

2. 修正Nginx路径配置

当前nginx.conf中location /的root设置为/app,但web-serve.Dockerfile是将dist目录复制到/usr/share/nginx/html/,路径不匹配导致找不到静态文件,需修改为:

location /
{
    root /usr/share/nginx/html;
    index index.html;
    try_files $uri $uri/ /index.html;
}

3. 修复构建命令冲突

项目使用Vite构建,但web-build.Dockerfile用了vue-cli-service build,需替换为Vite的构建命令:

FROM node:20-alpine AS build
COPY app /app
WORKDIR /app
RUN npm install
CMD npm run build

同时确保package.json中有"build": "vite build"脚本,否则改为CMD npx vite build。

4. 验证dist目录完整性

进入web-builder容器,检查dist目录是否正确生成:

docker exec -it <web-builder容器ID> /bin/sh
ls /app/dist

确认index.html、css、js等文件都存在且路径正确。

5. 检查文件权限

确保Nginx容器中静态文件目录的权限允许nginx用户读取:

docker exec -it <web-server容器ID> /bin/sh
chmod -R 755 /usr/share/nginx/html

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 16:42:03