如何在一台服务器上同时部署Vue前端和Node.js后端?

在一台服务器上同时部署Vue前端和Node.js后端有多种方式,我来介绍几种主流的方案:

方案一:前后端分离部署(推荐)

1. 前端构建

# 在Vue项目根目录
npm run build
# 生成dist目录

2. 后端代码结构

project/
├── backend/
│   ├── server.js
│   ├── routes/
│   └── package.json
├── frontend/
│   ├── dist/ (构建后的文件)
│   └── src/
└── package.json

3. Node.js后端配置

// backend/server.js
const express = require('express');
const path = require('path');
const app = express();

// 静态文件服务
app.use(express.static(path.join(__dirname, '../frontend/dist')));

// API路由
app.use('/api', require('./routes/api'));

// 所有其他请求返回index.html
app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
});

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});

方案二:使用Nginx反向

Nginx配置

server {
    listen 80;
    server_name your-domain.com;

    # 前端静态文件
    location / {
        root /var/www/frontend/dist;
        try_files $uri $uri/ /index.html;
    }

    # API请求到Node.js
    location /api/ {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
    }
}

Node.js后端(监听3001端口)

const express = require('express');
const app = express();

app.use(express.json());

// API路由
app.get('/api/users', (req, res) => {
    res.json({ users: [] });
});

app.listen(3001, () => {
    console.log('API server running on port 3001');
});

方案三:一体化部署

修改Vue配置

// vue.config.js
module.exports = {
    // 构建输出目录
    outputDir: 'dist',

    // 开发服务器
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:3000',
                changeOrigin: true,
            }
        }
    }
}

一体化Node.js服务器

const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const path = require('path');
const app = express();

// 生产环境:提供静态文件
if (process.env.NODE_ENV === 'production') {
    app.use(express.static(path.join(__dirname, 'dist')));

    // API路由
    app.use('/api', require('./routes/api'));

    // SPA路由
    app.get('*', (req, res) => {
        res.sendFile(path.join(__dirname, 'dist', 'index.html'));
    });
} 
// 开发环境:API请求
else {
    app.use('/api', createProxyMiddleware({
        target: 'http://localhost:5000',
        changeOrigin: true,
    }));
}

app.listen(process.env.PORT || 3000);

部署脚本示例

部署脚本 (deploy.sh)

#!/bin/bash

echo "开始部署..."

# 进入项目目录
cd /path/to/your/project

# 拉取最新代码
git pull origin main

# 安装依赖
npm install

# 构建前端
cd frontend
npm run build
cd ..

# 重启服务
pm2 restart app-name

echo "部署完成!"

PM2进程管理

// ecosystem.config.js
module.exports = {
    apps: [
        {
            name: 'my-app',
            script: './backend/server.js',
            instances: 1,
            autorestart: true,
            watch: false,
            max_memory_restart: '1G',
            env: {
                NODE_ENV: 'development'
            },
            env_production: {
                NODE_ENV: 'production'
            }
        }
    ]
};

环境变量配置

.env 文件

# 开发环境
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=27017

# 生产环境
NODE_ENV=production
PORT=80
DB_HOST=mongodb://db-server:27017

安全建议

  1. 使用HTTPS

    # Nginx HTTPS配置
    server {
     listen 443 ssl;
     ssl_certificate /path/to/cert.pem;
     ssl_certificate_key /path/to/key.pem;
    }
  2. CORS配置

    const cors = require('cors');
    app.use(cors({
     origin: ['https://yourdomain.com'],
     credentials: true
    }));
  3. 错误处理

    app.use((err, req, res, next) => {
     console.error(err.stack);
     res.status(500).json({ error: 'Something went wrong!' });
    });

推荐方案

对于生产环境,我推荐方案二(Nginx + Node.js),因为:

  • ✅ 更好的性能优化
  • ✅ 易于扩展
  • ✅ 更好的安全控制
  • ✅ 支持负载均衡
  • ✅ 静态文件缓存

选择哪种方案取决于你的具体需求、团队技能和运维能力。