从零到一:Linux Vue前端项目部署与配置

本教程是系列教程的第四篇,紧接着《MySQL在Linux服务器上的部署与配置完全指南》,将详细介绍如何将Vue前端项目成功部署到Linux服务器,并解决可能遇到的各种问题。本文将基于实际部署经验,讲解整个部署流程和常见问题的解决方案。

从零到一:SpringBoot SSH远程部署基础篇
从零到一:SpringBoot SSH远程部署进阶篇
从零到一:Linux MySQL部署与配置

目录

1. 准备工作

在开始部署前,需要确保开发环境和服务器环境都已准备就绪。

1.1 前端项目结构检查

一个标准的Vue项目通常包含以下关键文件:

  • package.json: 项目依赖和脚本配置
  • vite.config.js/vue.config.js: 项目构建配置
  • src/: 源代码目录
  • public/: 静态资源目录

1.2 服务器环境要求

  • 一台运行Linux的服务器(本教程以CentOS/RHEL为例)
  • 已开放的80端口(用于HTTP访问)
  • 已安装的Node.js(如需在服务器上构建)
  • SSH访问权限

1.3 相关软件版本

本教程基于以下版本:

  • Vue.js 3.x
  • Vite 6.x
  • Node.js 16+
  • Nginx 1.20+

2. 安装配置Nginx

Nginx是一个高性能的HTTP和反向代理服务器,非常适合部署前端应用。

2.1 安装Nginx

# 安装Nginx
yum install -y nginx

# 启动Nginx并设置开机自启
systemctl start nginx
systemctl enable nginx

# 检查Nginx状态
systemctl status nginx

2.2 检查Nginx安装情况

成功安装后,应该看到类似以下输出:

● nginx.service - The nginx HTTP and reverse proxy server
   Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2025-04-30 14:01:25 CST; 13s ago
 Main PID: 126561 (nginx)
    Tasks: 3 (limit: 99676)
   Memory: 5.3M
   CGroup: /system.slice/nginx.service
           ├─126561 nginx: master process /usr/sbin/nginx
           ├─126562 nginx: worker process
           └─126563 nginx: worker process

2.3 创建网站目录

# 创建前端应用存放目录
mkdir -p /usr/share/nginx/html/vue-app

3. 前端项目构建

前端项目需要先构建生成静态文件,然后再部署到服务器。

3.1 调整前端配置

在部署前,需要调整前端项目的配置,特别是API请求路径。

(1) 检查Vite配置文件

vite.config.js中,确保正确配置了API代理和环境变量:

import { fileURLToPath, URL } from 'node:url'
import { resolve } from 'path'

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

export default defineConfig({
  plugins: [
    vue({
      template: {
        compilerOptions: {
          isCustomElement: tag => tag.startsWith('el-icon-')
        }
      },
      reactivityTransform: false
    }),
    vueDevTools(),
  ],
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src'),
    },
  },
  server: {
    port: 3000,
    proxy: {
      '/api': {
        target: 'http://您的后端服务器地址:8080',
        changeOrigin: true
      },
      '/ws': {
        target: 'http://您的后端服务器地址:8080',
        changeOrigin: true,
        ws: true
      }
    }
  },
  define: {
    // 定义全局变量
    global: 'window',
    'process.env': {
      NODE_ENV: JSON.stringify(process.env.NODE_ENV || 'development'),
      BASE_URL: JSON.stringify('/'),
      BACKEND_URL: JSON.stringify('http://您的后端服务器地址')  // 不要包含端口号
    }
  }
})
(2) 修改API请求文件

src/utils/request.js中,修改baseURL配置:

import axios from 'axios'
import router from '../router'
import { ElMessage } from 'element-plus'

// 创建axios实例
const request = axios.create({
  baseURL: '', // 移除硬编码的baseURL,使用相对路径
  timeout: 30000
})

// 其他代码保持不变...
(3) 修改WebSocket配置

src/utils/websocket.js中,修改WebSocket连接设置:

constructor() {
  this.stompClient = null;
  this.connected = false;
  this.subscriptions = {};
  this.reconnectTimeout = null;
  this.reconnectAttempts = 0;
  this.maxReconnectAttempts = 5;
  this.reconnectDelay = 3000; // 重连延迟3秒
  
  // 设置固定的服务器地址
  this.baseURL = ''; // 移除硬编码的baseURL
}

connect() {
  // 清理所有现有订阅,避免重复订阅
  this.clearAllSubscriptions();
  
  const token = localStorage.getItem('token') || '';
  
  console.log('Opening Web Socket...');
  
  const socket = new SockJS(`/ws?token=${token}`); // 使用相对路径
  this.stompClient = Stomp.over(socket);
  
  // 其他代码保持不变...
}

3.2 构建前端项目

在本地开发环境执行以下命令进行构建:

# 安装依赖
npm install

# 构建生产环境版本
npm run build

构建完成后,会在项目目录下生成一个dist目录,包含所有静态资源文件。

  1. 上传构建文件到服务器

4.1 使用SCP上传文件

使用SCP命令将构建好的文件上传到服务器:

# 在本地项目目录下执行,上传dist目录下所有文件到服务器
scp -r dist/* 用户名@服务器IP:/usr/share/nginx/html/vue-app/

4.2 常见上传问题

如果遇到上传错误,如:

scp: realpath /usr/share/nginx/html/vue-app/assets: No such file
scp: upload "/usr/share/nginx/html/vue-app/assets": path canonicalization failed

这通常是目标目录权限或结构问题,可以通过以下命令解决:

# 在服务器上创建完整的目录结构
mkdir -p /usr/share/nginx/html/vue-app/assets

# 设置目录权限
chmod -R 755 /usr/share/nginx/html/vue-app

4.3 检查上传结果

上传完成后,检查服务器上的文件:

# 查看上传的文件
ls -la /usr/share/nginx/html/vue-app/

确保index.html和其他资源文件都已正确上传。

5. 配置Nginx代理

5.1 创建Nginx配置文件

编辑Nginx配置文件,设置网站访问和代理规则:

vim /etc/nginx/nginx.conf

5.2 基本配置结构

一个完整的Nginx配置文件结构如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

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

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    include /etc/nginx/conf.d/*.conf;

    # 服务器配置
    server {
        listen 80;
        server_name 您的服务器IP或域名;  # 替换为你的服务器IP或域名

        # 前端文件
        location / {
            root /usr/share/nginx/html/vue-app;
            index index.html;
            try_files $uri $uri/ /index.html;
        }
    }
}

5.3 检查并重启Nginx

配置修改后,需要检查配置有效性并重启Nginx:

# 检查配置语法
nginx -t

# 重启Nginx
systemctl restart nginx

配置正确时,应该看到:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

6. 处理API请求和跨域问题

6.1 配置API代理

为了解决跨域问题,需要在Nginx中配置API代理:

# 在server块中添加
location /api/ {
    proxy_pass http://localhost:8080;  # 后端API地址
    proxy_http_version 1.1;
    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;

    # CORS 设置
    add_header Access-Control-Allow-Origin * always;
    add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, DELETE, PUT' always;
    add_header Access-Control-Allow-Headers '*' always;
    add_header Access-Control-Allow-Credentials 'true' always;
    
    if ($request_method = 'OPTIONS') {
        add_header Access-Control-Allow-Origin * always;
        add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, DELETE, PUT' always;
        add_header Access-Control-Allow-Headers '*' always;
        add_header Access-Control-Allow-Credentials 'true' always;
        add_header Content-Type 'text/plain charset=UTF-8';
        add_header Content-Length 0;
        return 204;
    }

    # 增加超时设置
    proxy_connect_timeout 60s;
    proxy_send_timeout 60s;
    proxy_read_timeout 60s;
}

6.2 测试API代理

配置完成后,可以使用curl测试API连接:

curl -X POST http://您的服务器IP/api/admin/login -H "Content-Type: application/json" -d '{"username":"管理员账号","password":"示例密码"}'

如果配置正确,应该能收到正常的JSON响应。

6.3 常见API代理问题

如果遇到404或者502错误,可能是:

  • 后端服务未运行
  • proxy_pass地址配置错误
  • 防火墙阻止了内部服务通信

解决方案:

# 检查后端服务是否运行
systemctl status 你的后端服务名称

# 检查防火墙是否开放了相应端口
firewall-cmd --list-all

# 测试后端服务是否直接可访问
curl -X POST http://localhost:8080/api/admin/login -H "Content-Type: application/json" -d '{"username":"管理员账号","password":"示例密码"}'

7. 配置WebSocket支持

7.1 WebSocket专用配置

WebSocket需要特殊的Nginx配置,添加以下内容:

# 在http块内增加WebSocket支持
map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}

# 在server块内添加WebSocket路由
location /ws {
    proxy_pass http://localhost:8080/ws;
    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;
    
    # WebSocket特定设置
    proxy_read_timeout 300s;
    proxy_send_timeout 300s;
    
    # 允许跨域
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
    add_header 'Access-Control-Allow-Headers' '*';
    
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' '*';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
    }
}

7.2 完整的Nginx配置

整合所有配置后,完整的nginx.conf文件应该如下:

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;

events {
    worker_connections 1024;
}

http {
    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;
    tcp_nodelay         on;
    keepalive_timeout   65;
    types_hash_max_size 2048;

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

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    include /etc/nginx/conf.d/*.conf;

    # WebSocket 支持
    map $http_upgrade $connection_upgrade {
        default upgrade;
        ''      close;
    }

    server {
        listen 80;
        server_name 您的服务器IP或域名;

        # 前端文件
        location / {
            root /usr/share/nginx/html/vue-app;
            index index.html;
            try_files $uri $uri/ /index.html;
        }

        # API 代理
        location /api/ {
            proxy_pass http://localhost:8080;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection $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;

            # CORS 设置
            add_header Access-Control-Allow-Origin * always;
            add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, DELETE, PUT' always;
            add_header Access-Control-Allow-Headers '*' always;
            add_header Access-Control-Allow-Credentials 'true' always;

            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin * always;
                add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS, DELETE, PUT' always;
                add_header Access-Control-Allow-Headers '*' always;
                add_header Access-Control-Allow-Credentials 'true' always;
                add_header Content-Type 'text/plain charset=UTF-8';
                add_header Content-Length 0;
                return 204;
            }

            # 增加超时设置
            proxy_connect_timeout 60s;
            proxy_send_timeout 60s;
            proxy_read_timeout 60s;
        }

        # WebSocket 配置
        location /ws {
            proxy_pass http://localhost:8080/ws;
            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;
            
            # WebSocket 特定设置
            proxy_read_timeout 300s;
            proxy_send_timeout 300s;
            
            # 允许跨域
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            add_header 'Access-Control-Allow-Headers' '*';
            
            if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
                add_header 'Access-Control-Allow-Headers' '*';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
            }
        }
    }
}

7.3 防火墙配置

确保防火墙允许WebSocket流量:

# 开放HTTP和WebSocket端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
firewall-cmd --reload

8. 常见问题与解决方案

8.1 MIME类型错误

问题表现:控制台出现"types" directive is not allowed here in /etc/nginx/mime.types:2

解决方案

创建一个正确的mime.types文件:

cat > /etc/nginx/mime.types << 'EOL'
types {
    text/html                             html htm shtml;
    text/css                              css;
    text/xml                              xml;
    image/gif                             gif;
    image/jpeg                            jpeg jpg;
    application/javascript                js;
    application/json                      json;
    text/plain                            txt;
    image/png                             png;
    image/svg+xml                         svg svgz;
    image/x-icon                          ico;
    application/x-font-woff               woff;
    application/font-woff2                woff2;
    application/pdf                       pdf;
    application/zip                       zip;
    audio/mpeg                            mp3;
    video/mp4                             mp4;
    video/webm                            webm;
}
EOL

8.2 API连接超时

问题表现:前端请求API时出现ERR_CONNECTION_TIMED_OUT错误

解决方案

  1. 检查后端服务是否正常运行
systemctl status 你的后端服务名称
netstat -tulpn | grep 8080
  1. 检查Nginx代理配置
location /api/ {
    proxy_pass http://localhost:8080;  # 不要在最后加斜杠
    # ...其他配置...
}
  1. 增加超时时间
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;

8.3 WebSocket连接错误

问题表现:浏览器控制台出现WebSocket connection to 'ws://...' failed错误

解决方案

  1. 确保Nginx配置了正确的WebSocket支持
  2. 检查ConnectionUpgrade头部设置
  3. 在前端代码中使用相对路径而非绝对路径
  4. 注意WebSocket路径大小写

8.4 静态资源404

问题表现:某些JS、CSS或图片资源加载失败

解决方案

  1. 检查文件权限
chmod -R 755 /usr/share/nginx/html/vue-app
  1. 确认文件路径配置正确
location / {
    root /usr/share/nginx/html/vue-app;
    index index.html;
    try_files $uri $uri/ /index.html;
}
  1. 使用绝对路径在HTML/JS中引用资源

8.5 前端路由问题

问题表现:刷新页面后404

解决方案

确保Nginx配置了try_files指令:

location / {
    root /usr/share/nginx/html/vue-app;
    index index.html;
    try_files $uri $uri/ /index.html;  # 将找不到的路径重定向到index.html
}

9. 安全与性能优化

9.1 启用HTTPS

为网站启用HTTPS可以提高安全性:

server {
    listen 443 ssl;
    server_name your_domain.com;
    
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    
    # 其他配置...
}

9.2 启用Gzip压缩

启用Gzip可以减少传输数据量,提高页面加载速度:

# 在http块中添加
gzip on;
gzip_comp_level 6;
gzip_min_length 1k;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
gzip_vary on;

9.3 设置缓存控制

优化静态资源缓存:

location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
    expires 30d;
    add_header Cache-Control "public, no-transform";
}

9.4 限制请求大小

防止大文件上传导致服务器压力过大:

# 在http块中添加
client_max_body_size 10M;

10. 持续部署流程建议

10.1 建立自动化部署流程

创建部署脚本deploy.sh

#!/bin/bash

# 前端项目路径
PROJECT_PATH="/path/to/your/frontend"
# 服务器信息
SERVER_USER="用户名"
SERVER_IP="您的服务器IP"
SERVER_PATH="/usr/share/nginx/html/vue-app"

# 构建项目
cd $PROJECT_PATH
npm install
npm run build

# 打包构建文件
cd dist
tar -czf dist.tar.gz ./*

# 上传到服务器
scp dist.tar.gz $SERVER_USER@$SERVER_IP:/tmp/

# 在服务器上部署
ssh $SERVER_USER@$SERVER_IP << EOF
  # 解压文件到网站目录
  mkdir -p $SERVER_PATH
  rm -rf $SERVER_PATH/*
  tar -xzf /tmp/dist.tar.gz -C $SERVER_PATH
  chmod -R 755 $SERVER_PATH
  rm /tmp/dist.tar.gz
  
  # 重新加载Nginx配置
  nginx -t && systemctl reload nginx
  
  echo "部署完成!"
EOF

10.2 CI/CD集成

可以将上述脚本集成到CI/CD系统中(如GitHub Actions、Jenkins等),实现自动化部署。

10.3 版本管理与回滚机制

保留历史版本,以便在出现问题时能够快速回滚:

# 在部署脚本中添加版本管理
DEPLOY_TIME=$(date "+%Y%m%d%H%M%S")
BACKUP_PATH="/backup/frontend"

# 备份当前版本
ssh $SERVER_USER@$SERVER_IP << EOF
  if [ -d "$SERVER_PATH" ] && [ ! -z "\$(ls -A $SERVER_PATH)" ]; then
    mkdir -p $BACKUP_PATH
    tar -czf $BACKUP_PATH/backup_$DEPLOY_TIME.tar.gz -C $SERVER_PATH .
  fi
EOF

通过本教程,您应该能够成功将Vue前端项目部署到Linux服务器,并解决可能遇到的各种问题。在部署过程中,针对不同的应用场景,可能需要对配置进行相应的调整。希望本文能对您的前端项目部署提供帮助!

如果遇到特殊情况或其他问题,欢迎在评论区留言讨论。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值