针对Node.js环境开发的应用如何进行发布、部署，本文一文讲清楚，如何开发Node app 在本文就不再赘述，可以参考我以前发布的文章。本文主要讲述如何将开发的Node app 打包，并在运行nginx的环境中部署。

## 一、生成发布包
npm run build

生成后的目录结构如下图所示：
项目结构：
    ```
    服务器上的目录/
    ├── dist/          ← 前端静态文件（刚才 build 生成的）
    ├── uploads/       ← 上传文件存储目录
    ├── file-db.json   ← 上传记录数据库
    ├── server.js      ← Node.js 后端
    └── package.json ← 应用包的描述，包含应用依赖的模块
    ```
## 二、部署方案
nginx 托管前端 + 反向代理后端

### 第一步：把文件传到服务器
    
    ```bash
    # 在你的开发机上，压缩项目
    cd /Users/liquancun/.hermes/my-hermes-vite-app
    
    # 1. 前端 build 产物：dist/
    # 2. 后端运行文件：
    #    - server.js
    #    - package.json (含 busboy, express, uuid, cors 等依赖)
    #    - 项目根目录下
    
    # 上传到服务器（示例 IP 为 1.2.3.4）
    scp -r dist/ root@1.2.3.4:/usr/share/nginx/html/hermes-admin/
    scp server.js package.json root@1.2.3.4:/usr/share/nginx/html/hermes-admin/
    ```
    
    ### 第二步：服务器上安装后端依赖并启动
    
    ```bash
    # SSH 到服务器
    ssh root@1.2.3.4
    
    cd /usr/share/nginx/html/hermes-admin
    
    # 安装依赖
    npm install --production
    
    # 创建上传目录
    mkdir -p uploads
    
    # 用 PM2 （比用node直接启动应用更可靠，更好管理应用）守护进程运行后端（推荐）
    npm install -g pm2
    pm2 start server.js --name hermes-backend
    pm2 save
    pm2 startup    # 开机自启
    
    # 后端运行在 localhost:3001
    ```
    
    ### 第三步：配置 nginx
    
    **Nginx 配置文件** `/etc/nginx/nginx.conf` 有的nginx的配置文件在/etc/nginx/sites-available/default， 此时可以在该目录下增加一个配置文件如hermes-admin：
    
    ```nginx
    server {
        listen 8096;
        server_name www.heyanper.top;  # 改成你的域名或 IP
        root /usr/share/nginx/html/hermes-admin/dist;
    
        # 1. 前端静态文件
        location / {
            try_files $uri $uri/ /index.html;
        }
    
        # 2. 上传文件的静态访问（用户已上传的文件）
        location /uploads/ {
            alias /usr/share/nginx/html/hermes-admin/uploads/;
        }
    
        # 3. 后端 API —— 反向代理到 Node.js
        location /api/ {
            proxy_pass http://127.0.0.1:3001;
            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;
    
            # 大文件上传需要
            client_max_body_size 10G;
            proxy_request_buffering off;
            proxy_buffering off;
        }
    }
    ```
    
    启用配置：
    
    ```bash
    
    # 检查配置语法
    nginx -t
    
    # 重载 nginx
    systemctl reload nginx
    ```
    
    ### 关键配置说明
    
    | 配置项 | 作用 |
    |--------|------|
    | `try_files $uri $uri/ /index.html` | React SPA 路由支持，刷新页面不 404 |
    | 代理 `/api/` 到 `localhost:3001` | 前端所有 API 请求通过同域转发，避免 CORS |
    | `client_max_body_size 10G` | 大文件上传不限制大小 |
    | `proxy_request_buffering off` | 分片上传流式传输，不缓冲到磁盘 |
    
    ### 可选：HTTPS 配置
    
    部署完后用 Certbot 一键配置：
    
    ```bash
    # 安装 certbot
    apt install certbot python3-certbot-nginx
    
    # 自动配置 HTTPS
    certbot --nginx -d your-domain.com
    ```
    
    ### 前端 API 地址调整
    
    你当前的前端代码中（FileUpload.jsx）有一处硬编码的 `http://localhost:3001`，部署到 nginx 后需要改为空字符串或相对路径，这样请求会走 nginx 的反向代理：

## 三、测试
在浏览器中输入 http://www.heyanper.top:8096, 此时nginx就会通过反向代理的方式将http://27.0.0.1:3001的内容反馈给用户。

本人把nginx.conf配置文件增加反向代理后的详细配置如下：
    ```bash
user  root;
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;
    #tcp_nopush     on;
    keepalive_timeout  120;
    client_max_body_size 20m;
    client_body_timeout 60s;
    #gzip  on;
    server {
        listen       80;
        server_name  www.heyanper.top;
        root /usr/share/nginx/html;
        index index.php index.html index.htm;

        # 强制跳转到 HTTPS
        # return 301 https://$server_name$request_uri;

        location ~ \.php$ {
                root            /usr/share/nginx/html;
                fastcgi_pass    unix:/run/php/php8.1-fpm.sock;
                fastcgi_index   index.php;
                fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
                include         fastcgi_params;

        }

        location ~* \.txt$ {
                 add_header Content-Type "text/plain; charset=utf-8";
        }

        location /nginx_status {
                stub_status on;
                access_log off;
                #allow 127.0.0.1;允许哪个ip可以访问
        }
    }

    #增加一个端口号为8096的块,用于作为node.js应用的反向代理
    server {
        listen 8096;
        server_name www.heyanper.top;  # 改成你的域名或 IP
        root /usr/share/nginx/html/hermes-admin/dist;

        # 1. 前端静态文件
        location / {
            try_files $uri $uri/ /index.html;
        }

        # 2. 上传文件的静态访问（用户已上传的文件）
        location /uploads/ {
            alias /usr/share/nginx/html/hermes-admin/uploads/;
        }

        # 3. 后端 API —— 反向代理到 Node.js
        location /api/ {
            proxy_pass http://127.0.0.1:3001;
            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;

            # 大文件上传需要
            client_max_body_size 10G;
            proxy_request_buffering off;
            proxy_buffering off;
        }
    }
}
    ```