Skip to content

前端程序部署

4238字约14分钟

2025-08-21

🚀 快速开始

#!/bin/bash
# frontend-deploy.sh - 前端快速部署脚本
# 这个脚本用于自动化部署前端应用到生产服务器
# 使用方法:chmod +x frontend-deploy.sh && ./frontend-deploy.sh

# ==================== 配置变量区域 ====================
# 这些变量可以根据实际项目进行调整
APP_NAME="myapp-frontend"                    # 应用名称,用于日志和备份文件命名
BUILD_DIR="dist"                            # 构建输出目录,通常是dist或build
DEPLOY_DIR="/var/www/myapp"                 # 生产环境部署目录
BACKUP_DIR="/var/backup/myapp"              # 备份文件存储目录
NGINX_CONF="/etc/nginx/sites-available/myapp"    # Nginx配置文件路径
NGINX_ENABLED="/etc/nginx/sites-enabled/myapp"   # Nginx启用配置的符号链接路径

echo "🚀 开始部署前端应用 $APP_NAME..."

# ==================== 第一步:检查构建目录 ====================
# 这一步确保在部署前项目已经成功构建
# 如果构建目录不存在,说明构建失败,需要先解决构建问题
if [ ! -d "$BUILD_DIR" ]; then
    # [ ! -d "$BUILD_DIR" ] 检查目录是否不存在
    # ! 表示逻辑非,-d 表示检查是否为目录
    echo "❌ 构建目录不存在: $BUILD_DIR"
    echo "请先运行: npm run build 或 yarn build"
    exit 1  # 退出脚本,返回错误码1,表示执行失败
fi

# ==================== 第二步:停止Nginx服务 ====================
# 停止服务是为了避免文件部署过程中的访问冲突
# 在文件复制过程中,如果用户访问网站可能会看到不完整的页面
echo "⏹️  停止Nginx..."
sudo systemctl stop nginx    # systemctl stop 停止指定的系统服务
# systemctl是systemd的服务管理器,用于控制systemd服务
# sudo 表示以管理员权限执行命令

# ==================== 第三步:备份当前版本 ====================
# 备份是为了在部署失败时能够快速回滚到上一个可用版本
# 这是生产环境部署的重要安全措施
if [ -d "$DEPLOY_DIR" ]; then
    # 检查部署目录是否存在,如果存在则进行备份
    echo "💾 备份当前版本..."
    sudo mkdir -p $BACKUP_DIR    # mkdir -p 创建目录,-p表示如果父目录不存在则创建
    # 使用时间戳命名备份文件,确保文件名唯一,避免覆盖
    sudo cp -r $DEPLOY_DIR $BACKUP_DIR/${APP_NAME}.$(date +%Y%m%d_%H%M%S)
    # cp -r 递归复制目录及其内容
    # date +%Y%m%d_%H%M%S 生成格式为年月日_时分秒的时间戳
    # 例如:20241201_143052 表示2024年12月1日14时30分52秒
fi

# ==================== 第四步:部署新版本 ====================
echo "📦 部署新版本..."
sudo mkdir -p $DEPLOY_DIR    # 确保部署目录存在,如果不存在则创建
sudo cp -r $BUILD_DIR/* $DEPLOY_DIR/    # 复制构建文件到部署目录
# * 表示复制目录下的所有文件和子目录

# 设置文件所有者为www-data(Nginx默认用户)
sudo chown -R www-data:www-data $DEPLOY_DIR
# chown -R 递归更改文件所有者和组
# www-data是Nginx的默认运行用户,确保Nginx有权限访问文件
# 格式:chown 所有者:组 文件路径

# 设置文件权限为755(所有者可读写执行,组和其他用户可读执行)
sudo chmod -R 755 $DEPLOY_DIR
# chmod -R 递归设置文件权限
# 权限说明:
# 7 = 4+2+1 = rwx (所有者:读+写+执行)
# 5 = 4+0+1 = r-x (组:读+执行)
# 5 = 4+0+1 = r-x (其他用户:读+执行)

# ==================== 第五步:配置Nginx ====================
echo "⚙️  配置Nginx..."
sudo cp $NGINX_CONF $NGINX_ENABLED    # 复制配置文件到启用目录
# sites-enabled目录中的配置文件会被Nginx自动加载
# 这是Ubuntu/Debian系统的Nginx配置管理方式

# ==================== 第六步:启动Nginx服务 ====================
echo "▶️  启动Nginx..."
sudo systemctl start nginx    # 启动Nginx服务
sudo systemctl enable nginx   # 设置Nginx开机自启动
# enable命令创建符号链接,使服务在系统启动时自动启动

# ==================== 第七步:检查服务状态 ====================
# 验证Nginx是否成功启动,这是部署成功的关键指标
if sudo systemctl is-active --quiet nginx; then
    # is-active --quiet 检查服务是否活跃,--quiet表示不输出状态信息
    # 如果服务正在运行,返回true,否则返回false
    echo "✅ 部署成功!"
    echo "应用地址: http://localhost"
    echo "部署目录: $DEPLOY_DIR"
else
    echo "❌ 部署失败,请检查Nginx配置"
    sudo systemctl status nginx    # 显示Nginx服务的详细状态信息
    # 包括服务状态、进程ID、最近的日志等
fi

🔧 环境准备

1. Node.js安装与配置

🎯 推荐方式:使用NVM(Node Version Manager)

# ==================== 安装NVM ====================
# NVM是一个Node.js版本管理工具,可以轻松切换不同版本的Node.js
# 这对于项目兼容性和团队协作非常重要

# 下载并执行NVM安装脚本
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bash
# curl -o- 下载文件并输出到标准输出,| bash 将输出作为bash脚本执行
# 这个命令会下载NVM安装脚本并立即执行

# 重新加载bash配置文件,使NVM命令立即可用
source ~/.bashrc
# source命令读取并执行指定的文件,~/.bashrc是用户的bash配置文件

# ==================== 查看可用版本 ====================
# 查看所有可用的Node.js版本
nvm list-remote
# 这会显示所有可用的Node.js版本,包括LTS(长期支持)版本

# ==================== 安装Node.js版本 ====================
# 安装指定版本的Node.js(推荐使用LTS版本,稳定性更好)
nvm install 18.17.0    # 安装Node.js 18.17.0版本
nvm install 20.5.0     # 安装Node.js 20.5.0版本
# nvm install 命令会下载、编译并安装指定版本的Node.js

# ==================== 设置默认版本 ====================
# 设置当前使用的版本
nvm use 18.17.0
# 切换到Node.js 18.17.0版本

# 设置默认版本(每次打开新终端时自动使用此版本)
nvm alias default 18.17.0
# 这会在~/.bashrc中添加自动切换命令

# ==================== 验证安装 ====================
# 检查Node.js版本
node --version    # 显示当前使用的Node.js版本
npm --version     # 显示当前使用的npm版本
# 确保版本号与安装的版本一致

🔧 手动安装方式

# ==================== 下载Node.js ====================
# 手动下载并安装Node.js,适用于无法使用NVM的环境

# 下载Node.js二进制包(Linux x64版本)
wget https://nodejs.org/dist/v18.17.0/node-v18.17.0-linux-x64.tar.xz
# wget是Linux下的下载工具,支持断点续传
# tar.xz是压缩格式,比tar.gz压缩率更高

# ==================== 解压安装 ====================
# 解压到指定目录
sudo tar -xJf node-v18.17.0-linux-x64.tar.xz -C /opt/
# tar -xJf 解压tar.xz文件
# -x 表示解压,-J 表示使用xz解压,-f 指定文件名,-C 指定解压目录

# ==================== 配置环境变量 ====================
# 将Node.js的bin目录添加到PATH环境变量中
echo 'export PATH=/opt/node-v18.17.0-linux-x64/bin:$PATH' >> ~/.bashrc
# >> 表示追加到文件末尾,$PATH 表示原有的PATH变量
# 重新加载配置文件
source ~/.bashrc

# ==================== 验证配置 ====================
# 检查环境变量是否正确设置
echo $PATH    # 显示PATH环境变量,应该包含Node.js的bin目录
node --version    # 验证Node.js是否可用
npm --version     # 验证npm是否可用

2. 包管理器配置

🎯 使用npm镜像源(国内用户推荐)

# ==================== 设置淘宝镜像源 ====================
# 国内用户访问npm官方源速度较慢,使用淘宝镜像可以显著提升下载速度

# 设置npm镜像源为淘宝镜像
npm config set registry https://registry.npmmirror.com
# npm config set 用于设置npm配置项
# registry 指定包的下载源

# 设置二进制文件下载源
npm config set disturl https://npmmirror.com/dist
# disturl 指定二进制文件的下载地址

# 或者使用cnpm(淘宝的npm客户端)
npm install -g cnpm --registry=https://registry.npmmirror.com
# 安装cnpm工具,它是npm的淘宝镜像版本

🔧 使用yarn包管理器

# ==================== 安装yarn ====================
# yarn是Facebook开发的包管理器,比npm更快更稳定

# 通过npm全局安装yarn
npm install -g yarn
# -g 表示全局安装,所有项目都可以使用

# ==================== 配置yarn镜像源 ====================
# 设置yarn镜像源为淘宝镜像
yarn config set registry https://registry.npmmirror.com
# yarn config set 用于设置yarn配置项

# 设置二进制文件下载源
yarn config set disturl https://npmmirror.com/dist

🚀 使用pnpm(推荐)

# ==================== 安装pnpm ====================
# pnpm是新一代包管理器,具有更快的安装速度和更少的磁盘占用

# 通过npm全局安装pnpm
npm install -g pnpm
# pnpm使用硬链接和符号链接,节省磁盘空间

# ==================== 配置pnpm镜像源 ====================
# 设置pnpm镜像源为淘宝镜像
pnpm config set registry https://registry.npmmirror.com
pnpm config set disturl https://npmmirror.com/dist

# ==================== pnpm的优势 ====================
# 1. 安装速度快:并行下载和安装
# 2. 磁盘占用少:使用硬链接共享依赖
# 3. 安全性高:严格的依赖管理
# 4. 支持monorepo:多包项目管理

3. Nginx安装与配置

🎯 Ubuntu/Debian安装

# ==================== 更新包列表 ====================
# 确保系统包列表是最新的,避免安装旧版本
sudo apt update
# apt update 更新本地包数据库,不会安装或升级任何包

# ==================== 安装Nginx ====================
# 安装Nginx Web服务器
sudo apt install nginx
# apt install 安装指定的包及其依赖

# ==================== 启动Nginx服务 ====================
# 启动Nginx服务
sudo systemctl start nginx
# systemctl start 启动指定的系统服务

# 设置Nginx开机自启动
sudo systemctl enable nginx
# systemctl enable 启用服务,使其在系统启动时自动启动

# ==================== 检查服务状态 ====================
# 查看Nginx服务状态
sudo systemctl status nginx
# 显示服务的运行状态、进程ID、最近的日志等信息

🔧 CentOS/RHEL安装

# ==================== 安装EPEL仓库 ====================
# EPEL(Extra Packages for Enterprise Linux)提供额外的软件包
sudo yum install epel-release
# yum install 安装指定的包

# ==================== 安装Nginx ====================
# 安装Nginx Web服务器
sudo yum install nginx
# CentOS/RHEL系统使用yum包管理器

# ==================== 启动Nginx服务 ====================
# 启动Nginx服务
sudo systemctl start nginx
sudo systemctl enable nginx

# ==================== 检查服务状态 ====================
sudo systemctl status nginx

🔧 编译安装(最新版本)

# ==================== 安装编译依赖 ====================
# 安装编译Nginx所需的开发工具和库
sudo apt install build-essential libpcre3-dev libssl-dev zlib1g-dev
# build-essential 包含基本的编译工具(gcc, make等)
# libpcre3-dev 提供正则表达式支持
# libssl-dev 提供SSL/TLS支持
# zlib1g-dev 提供压缩支持

# ==================== 下载Nginx源码 ====================
# 下载Nginx源码包
wget http://nginx.org/download/nginx-1.24.0.tar.gz
# 解压源码包
tar -xzf nginx-1.24.0.tar.gz
cd nginx-1.24.0

# ==================== 配置编译选项 ====================
# 配置Nginx的编译选项
./configure \
    --prefix=/usr/local/nginx \           # 安装目录
    --with-http_ssl_module \              # 启用SSL模块
    --with-http_v2_module \               # 启用HTTP/2模块
    --with-http_realip_module \           # 启用真实IP模块
    --with-http_stub_status_module \      # 启用状态监控模块
    --with-http_gzip_static_module \      # 启用静态gzip模块
    --with-http_secure_link_module \      # 启用安全链接模块
    --with-pcre \                         # 启用PCRE支持
    --with-file-aio \                     # 启用异步文件I/O
    --with-http_mp4_module                # 启用MP4模块

# ==================== 编译安装 ====================
# 编译Nginx
make
# 安装Nginx
sudo make install

# ==================== 创建systemd服务 ====================
# 创建systemd服务文件,使Nginx可以通过systemctl管理
sudo vim /etc/systemd/system/nginx.service
[Unit]
Description=The nginx HTTP and reverse proxy server
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStartPre=/usr/local/nginx/sbin/nginx -t
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/bin/kill -s HUP $MAINPID
KillMode=process
KillSignal=SIGQUIT
TimeoutStopSec=5
PrivateTmp=true

[Install]
WantedBy=multi-user.target

4. 系统要求检查

# ==================== 检查内存使用情况 ====================
# 检查系统内存使用情况(推荐至少2GB可用内存)
free -h
# free 显示内存使用情况,-h 表示以人类可读的格式显示(GB, MB等)

# ==================== 检查磁盘空间 ====================
# 检查磁盘空间使用情况(推荐至少5GB可用空间)
df -h
# df 显示磁盘空间使用情况,-h 表示以人类可读的格式显示

# ==================== 检查系统版本 ====================
# 查看操作系统版本信息
cat /etc/os-release
# cat 显示文件内容,/etc/os-release 包含系统版本信息

# ==================== 检查防火墙状态 ====================
# 检查防火墙是否运行
sudo ufw status          # Ubuntu默认防火墙
sudo firewall-cmd --state # CentOS/RHEL防火墙

# ==================== 检查端口占用 ====================
# 检查80端口(HTTP)和443端口(HTTPS)是否被占用
sudo netstat -tlnp | grep :80
sudo netstat -tlnp | grep :443
# netstat -tlnp 显示TCP监听端口,grep过滤特定端口
# -t 显示TCP连接,-l 显示监听端口,-n 显示端口号,-p 显示进程信息

📦 项目构建

1. 项目打包

🎯 Vue.js项目

# ==================== 安装项目依赖 ====================
# 安装项目所需的所有依赖包
npm install
# 或者使用yarn
yarn install
# 或者使用pnpm(推荐,速度更快)
pnpm install

# ==================== 构建生产版本 ====================
# 构建项目,生成生产环境的静态文件
npm run build
# 或者使用yarn
yarn build
# 或者使用pnpm
pnpm build

# ==================== 检查构建结果 ====================
# 查看构建输出目录的内容
ls -la dist/
# ls -la 显示目录内容,-l 显示详细信息,-a 显示隐藏文件
# dist/ 是Vue.js项目的默认构建输出目录

🔧 React项目

# ==================== 安装项目依赖 ====================
npm install

# ==================== 构建生产版本 ====================
npm run build

# ==================== 检查构建结果 ====================
ls -la build/
# React项目默认输出到build/目录

🚀 Angular项目

# ==================== 安装项目依赖 ====================
npm install

# ==================== 构建生产版本 ====================
ng build --prod
# ng 是Angular CLI命令
# --prod 表示生产环境构建,会进行代码压缩和优化

# ==================== 检查构建结果 ====================
ls -la dist/
# Angular项目默认输出到dist/目录

2. 构建配置优化

🎯 Vue.js (vite.config.js)

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

export default defineConfig({
  plugins: [vue()],
  build: {
    outDir: 'dist',                    // 构建输出目录
    assetsDir: 'assets',               // 静态资源目录
    sourcemap: false,                  // 不生成sourcemap文件(生产环境)
    minify: 'terser',                  // 使用terser进行代码压缩
    rollupOptions: {
      output: {
        // 代码分割配置,将第三方库单独打包
        manualChunks: {
          vendor: ['vue', 'vue-router', 'vuex'],    // Vue相关库
          utils: ['axios', 'lodash']                // 工具库
        }
      }
    },
    terserOptions: {
      compress: {
        drop_console: true,            // 移除console.log
        drop_debugger: true            // 移除debugger语句
      }
    }
  },
  resolve: {
    alias: {
      '@': resolve(__dirname, 'src')   // 路径别名,@指向src目录
    }
  }
})

🔧 React (package.json)

{
  "scripts": {
    "build": "GENERATE_SOURCEMAP=false react-scripts build",
    "build:analyze": "source-map-explorer 'build/static/js/*.js'"
  },
  "browserslist": {
    "production": [
      ">0.2%",                        // 支持市场份额大于0.2%的浏览器
      "not dead",                     // 不支持已停止维护的浏览器
      "not op_mini all"              // 不支持Opera Mini
    ]
  }
}

🚀 环境变量配置

# .env.production - 生产环境配置
NODE_ENV=production                    # 环境标识
VITE_API_BASE_URL=https://api.example.com    # API基础URL
VITE_APP_TITLE=My App                 # 应用标题
VITE_APP_VERSION=1.0.0                # 应用版本

# .env.staging - 预发布环境配置
NODE_ENV=staging                      # 环境标识
VITE_API_BASE_URL=https://staging-api.example.com    # 预发布API地址
VITE_APP_TITLE=My App (Staging)       # 预发布环境应用标题

🌐 Nginx配置

1. 基础配置

🎯 主配置文件

# /etc/nginx/nginx.conf - Nginx主配置文件
user www-data;                         # Nginx运行用户
worker_processes auto;                 # 工作进程数,auto表示自动检测CPU核心数
pid /run/nginx.pid;                    # 进程ID文件路径
include /etc/nginx/modules-enabled/*.conf;    # 包含启用的模块配置

# 事件模块配置
events {
    worker_connections 1024;           # 每个工作进程的最大连接数
    use epoll;                         # 使用epoll事件模型(Linux系统)
    multi_accept on;                   # 一次接受所有新连接
}

# HTTP模块配置
http {
    # ==================== 基础设置 ====================
    sendfile on;                       # 启用sendfile,提高文件传输效率
    tcp_nopush on;                     # 启用TCP_NOPUSH,优化网络传输
    tcp_nodelay on;                    # 禁用Nagle算法,减少延迟
    keepalive_timeout 65;              # 保持连接超时时间(秒)
    types_hash_max_size 2048;          # MIME类型哈希表大小
    client_max_body_size 100M;         # 客户端请求体最大大小
    
    # ==================== MIME类型 ====================
    include /etc/nginx/mime.types;     # 包含MIME类型定义
    default_type application/octet-stream;    # 默认MIME类型
    
    # ==================== 日志格式 ====================
    # 定义访问日志格式
    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';
    # $remote_addr: 客户端IP地址
    # $remote_user: 客户端用户名(HTTP认证)
    # $time_local: 本地时间
    # $request: 请求行
    # $status: HTTP状态码
    # $body_bytes_sent: 发送给客户端的字节数
    # $http_referer: 引用页面
    # $http_user_agent: 用户代理(浏览器信息)
    # $http_x_forwarded_for: 代理转发的客户端IP
    
    # 设置日志文件路径
    access_log /var/log/nginx/access.log main;    # 访问日志
    error_log /var/log/nginx/error.log warn;      # 错误日志,级别为warn
    
    # ==================== Gzip压缩 ====================
    gzip on;                           # 启用gzip压缩
    gzip_vary on;                      # 添加Vary头,支持缓存
    gzip_min_length 1024;              # 最小压缩文件大小(字节)
    gzip_proxied any;                  # 对所有代理请求启用压缩
    gzip_comp_level 6;                 # 压缩级别(1-9,9为最高)
    gzip_types                         # 指定压缩的文件类型
        text/plain                     # 纯文本
        text/css                       # CSS文件
        text/xml                       # XML文件
        text/javascript                # JavaScript文件
        application/json               # JSON文件
        application/javascript         # JavaScript应用
        application/xml+rss            # XML RSS
        application/atom+xml           # Atom XML
        image/svg+xml;                 # SVG图像
    
    # ==================== 包含站点配置 ====================
    include /etc/nginx/sites-enabled/*;    # 包含启用的站点配置
}

🔧 站点配置

# /etc/nginx/sites-available/myapp - 站点配置文件
server {
    listen 80;                         # 监听80端口(HTTP)
    server_name localhost;             # 服务器名称
    root /var/www/myapp;               # 网站根目录
    index index.html index.htm;        # 默认首页文件
    
    # ==================== 安全头配置 ====================
    # 防止网站被嵌入框架中(防点击劫持)
    add_header X-Frame-Options "SAMEORIGIN" always;
    # 启用XSS保护
    add_header X-XSS-Protection "1; mode=block" always;
    # 防止MIME类型嗅探
    add_header X-Content-Type-Options "nosniff" always;
    # 引用策略
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    # 内容安全策略
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
    
    # ==================== 静态资源缓存 ====================
    # 对静态资源设置长期缓存
    location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
        expires 1y;                    # 缓存1年
        add_header Cache-Control "public, immutable";    # 公共缓存,不可变
        access_log off;                 # 不记录访问日志
    }
    
    # ==================== HTML文件不缓存 ====================
    # HTML文件不缓存,确保用户能看到最新内容
    location ~* \.html$ {
        expires -1;                     # 不缓存
        add_header Cache-Control "no-cache, no-store, must-revalidate";    # 不缓存策略
        add_header Pragma "no-cache";   # HTTP/1.0兼容
    }
    
    # ==================== API代理配置 ====================
    # 将API请求代理到后端服务
    location /api/ {
        proxy_pass http://localhost:8080/;    # 代理到后端服务
        proxy_set_header Host $host;          # 设置Host头
        proxy_set_header X-Real-IP $remote_addr;    # 设置真实IP
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;    # 设置转发IP
        proxy_set_header X-Forwarded-Proto $scheme;    # 设置协议
    }
    
    # ==================== 前端路由支持 ====================
    # 支持SPA应用的前端路由
    location / {
        try_files $uri $uri/ /index.html;    # 尝试文件,目录,最后回退到index.html
    }
    
    # ==================== 错误页面 ====================
    error_page 404 /404.html;          # 404错误页面
    error_page 500 502 503 504 /50x.html;    # 5xx错误页面
    
    # ==================== 日志配置 ====================
    access_log /var/log/nginx/myapp_access.log;    # 访问日志
    error_log /var/log/nginx/myapp_error.log;      # 错误日志
}