本教程是系列教程的第四篇,紧接着《MySQL在Linux服务器上的部署与配置完全指南》,将详细介绍如何将Vue前端项目成功部署到Linux服务器,并解决可能遇到的各种问题。本文将基于实际部署经验,讲解整个部署流程和常见问题的解决方案。
从零到一:SpringBoot SSH远程部署基础篇
从零到一:SpringBoot SSH远程部署进阶篇
从零到一:Linux MySQL部署与配置
目录
- 1. 准备工作
- 2. 安装配置Nginx
- 3. 前端项目构建
- 4. 上传构建文件到服务器
- 5. 配置Nginx代理
- 6. 处理API请求和跨域问题
- 7. 配置WebSocket支持
- 8. 常见问题与解决方案
- 9. 安全与性能优化
- 10. 持续部署流程建议
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
目录,包含所有静态资源文件。
- 上传构建文件到服务器
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
错误
解决方案:
- 检查后端服务是否正常运行
systemctl status 你的后端服务名称
netstat -tulpn | grep 8080
- 检查Nginx代理配置
location /api/ {
proxy_pass http://localhost:8080; # 不要在最后加斜杠
# ...其他配置...
}
- 增加超时时间
proxy_connect_timeout 300s;
proxy_send_timeout 300s;
proxy_read_timeout 300s;
8.3 WebSocket连接错误
问题表现:浏览器控制台出现WebSocket connection to 'ws://...' failed
错误
解决方案:
- 确保Nginx配置了正确的WebSocket支持
- 检查
Connection
和Upgrade
头部设置 - 在前端代码中使用相对路径而非绝对路径
- 注意WebSocket路径大小写
8.4 静态资源404
问题表现:某些JS、CSS或图片资源加载失败
解决方案:
- 检查文件权限
chmod -R 755 /usr/share/nginx/html/vue-app
- 确认文件路径配置正确
location / {
root /usr/share/nginx/html/vue-app;
index index.html;
try_files $uri $uri/ /index.html;
}
- 使用绝对路径在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服务器,并解决可能遇到的各种问题。在部署过程中,针对不同的应用场景,可能需要对配置进行相应的调整。希望本文能对您的前端项目部署提供帮助!
如果遇到特殊情况或其他问题,欢迎在评论区留言讨论。