Codex实战:APP远程升级服务搭建(二)阿里云ECS部署Node升级服务_Ubuntu_systemd_Nginx

阿里云 ECS 部署 Node 升级服务实战:Ubuntu + systemd + Nginx

摘要

上一篇已经把 APP(QGC/地面站)远程升级服务的核心接口跑起来了,这一篇把它部署到阿里云 ECS 的 Ubuntu 服务器上。

目标是让外网手机可以访问:

text 复制代码
http://203.0.113.10:8080/fra/check/update
http://203.0.113.10:8080/updates/GCS-Demo-1.03.08.apk

其中 203.0.113.10 是示例 IP,实际发布时换成自己的公网 IP 或域名。

适用场景

  • 本地 Node 服务已经调通,需要部署到公网服务器。
  • App 端不能再依赖局域网地址。
  • 需要 systemd 守护进程,服务器重启后自动恢复。
  • 后续可能用 Nginx 把 80 端口转发到 8080。

本文效果

完成后可以做到:

  • Ubuntu 服务器上运行 Node 升级服务。
  • systemctl status guardsky-upgrade 显示服务在线。
  • 公网访问 /health 返回 {"ok":true}
  • App 可以请求公网升级接口并下载 APK。
  • 可选使用 Nginx 让 App 不再带 :8080

背景

远程升级最容易在部署阶段踩坑:

  • 本地 localhost 能访问,手机访问不了。
  • 云服务器程序启动了,但阿里云安全组没放行端口。
  • 服务手动 npm start 可以跑,断开 SSH 就停了。
  • APK 上传到服务器后,服务端返回的还是局域网地址。

所以正式上线要把几个点串起来:

text 复制代码
代码上传 -> npm install -> 环境变量 -> systemd -> 安全组 -> 公网验证 -> App 验证

部署流程图

#mermaid-svg-TQEJPqdZUGjrSFoZ{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-TQEJPqdZUGjrSFoZ .error-icon{fill:#552222;}#mermaid-svg-TQEJPqdZUGjrSFoZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-TQEJPqdZUGjrSFoZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .marker.cross{stroke:#333333;}#mermaid-svg-TQEJPqdZUGjrSFoZ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-TQEJPqdZUGjrSFoZ p{margin:0;}#mermaid-svg-TQEJPqdZUGjrSFoZ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster-label text{fill:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster-label span{color:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster-label span p{background-color:transparent;}#mermaid-svg-TQEJPqdZUGjrSFoZ .label text,#mermaid-svg-TQEJPqdZUGjrSFoZ span{fill:#333;color:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .node rect,#mermaid-svg-TQEJPqdZUGjrSFoZ .node circle,#mermaid-svg-TQEJPqdZUGjrSFoZ .node ellipse,#mermaid-svg-TQEJPqdZUGjrSFoZ .node polygon,#mermaid-svg-TQEJPqdZUGjrSFoZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .rough-node .label text,#mermaid-svg-TQEJPqdZUGjrSFoZ .node .label text,#mermaid-svg-TQEJPqdZUGjrSFoZ .image-shape .label,#mermaid-svg-TQEJPqdZUGjrSFoZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-TQEJPqdZUGjrSFoZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .rough-node .label,#mermaid-svg-TQEJPqdZUGjrSFoZ .node .label,#mermaid-svg-TQEJPqdZUGjrSFoZ .image-shape .label,#mermaid-svg-TQEJPqdZUGjrSFoZ .icon-shape .label{text-align:center;}#mermaid-svg-TQEJPqdZUGjrSFoZ .node.clickable{cursor:pointer;}#mermaid-svg-TQEJPqdZUGjrSFoZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .arrowheadPath{fill:#333333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TQEJPqdZUGjrSFoZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-TQEJPqdZUGjrSFoZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TQEJPqdZUGjrSFoZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster text{fill:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ .cluster span{color:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-TQEJPqdZUGjrSFoZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-TQEJPqdZUGjrSFoZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-TQEJPqdZUGjrSFoZ .icon-shape,#mermaid-svg-TQEJPqdZUGjrSFoZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-TQEJPqdZUGjrSFoZ .icon-shape p,#mermaid-svg-TQEJPqdZUGjrSFoZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-TQEJPqdZUGjrSFoZ .icon-shape .label rect,#mermaid-svg-TQEJPqdZUGjrSFoZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-TQEJPqdZUGjrSFoZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-TQEJPqdZUGjrSFoZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-TQEJPqdZUGjrSFoZ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 本地 server 项目
上传到 ECS /opt/gcs-update-server/server
npm install 安装依赖
配置 guardsky-upgrade.env
安装 systemd service
放行 8080/tcp 安全组
curl /health 验证
App 请求 /fra/check/update
下载 /updates/*.apk

如果 Mermaid 在 CSDN 不能直接显示,可以截图后作为流程图插入。

1. 上传项目到服务器

本地目录示例:

text 复制代码
D:\your_workspace\server

服务器目标目录示例:

text 复制代码
/opt/gcs-update-server/server

首次部署可以整体上传:

powershell 复制代码
scp -r D:\your_workspace\server root@203.0.113.10:/opt/gcs-update-server/

如果上传后目录变成了:

text 复制代码
/opt/gcs-update-server/server/server/server.js

说明多套了一层,需要整理成:

text 复制代码
/opt/gcs-update-server/server/server.js
/opt/gcs-update-server/server/package.json
/opt/gcs-update-server/server/public/updates/GCS-Demo-1.03.08.apk

后续更新代码时,不建议每次整包覆盖。线上这几个位置通常属于数据文件:

text 复制代码
/opt/gcs-update-server/server/deploy/guardsky-upgrade.env
/opt/gcs-update-server/server/update-config.json
/opt/gcs-update-server/server/public/updates/

如果只是更新服务代码,优先同步:

powershell 复制代码
scp D:\your_workspace\server\server.js root@203.0.113.10:/opt/gcs-update-server/server/
scp -r D:\your_workspace\server\public\admin root@203.0.113.10:/opt/gcs-update-server/server/public/

2. 安装依赖

登录服务器:

bash 复制代码
ssh root@203.0.113.10

进入项目目录:

bash 复制代码
cd /opt/gcs-update-server/server
npm install

项目依赖很少:

json 复制代码
{
  "scripts": {
    "start": "node server.js"
  },
  "dependencies": {
    "cookie-parser": "^1.4.7",
    "express": "^4.19.2",
    "multer": "^2.1.1"
  }
}

Node 建议使用 18 或更高版本。

3. 配置环境变量

项目里准备了一个示例配置:

bash 复制代码
cd /opt/gcs-update-server/server
cp deploy/guardsky-upgrade.env.example deploy/guardsky-upgrade.env
nano deploy/guardsky-upgrade.env

配置内容:

text 复制代码
PORT=8080
PUBLIC_BASE_URL=http://203.0.113.10:8080
ADMIN_PASSWORD=CHANGE_ME_TO_A_STRONG_PASSWORD

说明:

  • PORT:Node 服务监听端口。
  • PUBLIC_BASE_URL:返回给 App 的公网基础地址。
  • ADMIN_PASSWORD:后台登录口令,真实环境必须改强密码,不要提交到 Git。

仓库中的示例文件内容如下:

text 复制代码
# Copy this file to guardsky-upgrade.env on the cloud server.
# Keep guardsky-upgrade.env out of source control because it contains the admin password.
PORT=8080
PUBLIC_BASE_URL=http://203.0.113.10:8080
ADMIN_PASSWORD=CHANGE_ME_TO_A_STRONG_PASSWORD

4. 安装 systemd 服务

systemd 配置文件:

ini 复制代码
[Unit]
Description=Guardsky Upgrade Server
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
WorkingDirectory=/opt/gcs-update-server/server
EnvironmentFile=/opt/gcs-update-server/server/deploy/guardsky-upgrade.env
ExecStart=/usr/bin/npm start
Restart=always
RestartSec=3
User=root

[Install]
WantedBy=multi-user.target

安装:

bash 复制代码
cp /opt/gcs-update-server/server/deploy/guardsky-upgrade.service /etc/systemd/system/guardsky-upgrade.service
systemctl daemon-reload
systemctl enable guardsky-upgrade
systemctl restart guardsky-upgrade
systemctl status guardsky-upgrade

期望看到:

text 复制代码
Active: active (running)

查看实时日志:

bash 复制代码
journalctl -u guardsky-upgrade -f

常用命令:

bash 复制代码
systemctl stop guardsky-upgrade
systemctl start guardsky-upgrade
systemctl restart guardsky-upgrade
systemctl status guardsky-upgrade

5. 放行端口

Ubuntu 系统防火墙如果启用了 ufw

bash 复制代码
ufw allow 8080/tcp
ufw status

如果提示 inactive,说明系统防火墙没启用,这一步可以跳过。

但是阿里云 ECS 还必须检查安全组:

text 复制代码
方向:入方向
协议:TCP
端口:8080
来源:0.0.0.0/0

如果你准备使用 Nginx 的 80 端口,还要放行:

text 复制代码
TCP 80

6. 服务器本机验证

在 ECS 上执行:

bash 复制代码
curl http://127.0.0.1:8080/health

期望返回:

json 复制代码
{"ok":true}

如果本机都不通,先看:

bash 复制代码
systemctl status guardsky-upgrade
journalctl -u guardsky-upgrade -n 100

常见原因:

  • deploy/guardsky-upgrade.env 不存在。
  • ADMIN_PASSWORD 没配置。
  • Node 没装或 /usr/bin/npm 路径不对。
  • 8080 端口被别的程序占用。
  • npm install 没执行成功。

7. 公网验证

在本地电脑浏览器打开:

text 复制代码
http://203.0.113.10:8080/health

期望:

json 复制代码
{"ok":true}

再验证升级接口:

powershell 复制代码
Invoke-RestMethod -Method Post `
  -Uri http://203.0.113.10:8080/fra/check/update `
  -ContentType 'application/x-www-form-urlencoded' `
  -Body '&app_ids=com.example.gcs&app_code=10307&app_flavor=release'

如果服务端有更高版本,期望返回:

json 复制代码
{
  "code": 2000,
  "msg": "new version available",
  "data": {
    "versionCode": 10308,
    "versionName": "1.03.08",
    "fileUrl": "http://203.0.113.10:8080/updates/GCS-Demo-1.03.08.apk"
  }
}

APK 下载地址也要能打开:

text 复制代码
http://203.0.113.10:8080/updates/GCS-Demo-1.03.08.apk

8. 可选:Nginx 80 端口转发

如果不想让 App 地址带 :8080,可以让 Nginx 监听 80,再反向代理到本机 8080。

Nginx 配置:

nginx 复制代码
server {
    listen 80;
    server_name 203.0.113.10;

    client_max_body_size 1200m;

    location / {
        proxy_pass http://127.0.0.1:8080;
        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;
    }
}

安装并启用:

bash 复制代码
apt install -y nginx
cp /opt/gcs-update-server/server/deploy/nginx-ip-http.conf /etc/nginx/sites-available/gcs-upgrade
ln -sf /etc/nginx/sites-available/gcs-upgrade /etc/nginx/sites-enabled/gcs-upgrade
nginx -t
systemctl reload nginx

然后把环境变量改成:

text 复制代码
PUBLIC_BASE_URL=http://203.0.113.10

App 地址也改成:

cpp 复制代码
#define STGC_HTTP_ADDRESS "http://203.0.113.10/fra/"

如果后续加域名和 HTTPS,则改为:

cpp 复制代码
#define STGC_HTTP_ADDRESS "https://upgrade.example.com/fra/"

9. 上线更新注意事项

线上不要随便覆盖这些文件:

text 复制代码
deploy/guardsky-upgrade.env
update-config.json
public/updates/

原因:

  • guardsky-upgrade.env 里有线上密码和公网地址。
  • update-config.json 是后台维护的版本库。
  • public/updates/ 里是已上传的 APK。

推荐的更新流程:
#mermaid-svg-ErdfTP6PB4sfwHAf{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-ErdfTP6PB4sfwHAf .error-icon{fill:#552222;}#mermaid-svg-ErdfTP6PB4sfwHAf .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ErdfTP6PB4sfwHAf .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ErdfTP6PB4sfwHAf .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ErdfTP6PB4sfwHAf .marker.cross{stroke:#333333;}#mermaid-svg-ErdfTP6PB4sfwHAf svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ErdfTP6PB4sfwHAf p{margin:0;}#mermaid-svg-ErdfTP6PB4sfwHAf .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster-label text{fill:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster-label span{color:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster-label span p{background-color:transparent;}#mermaid-svg-ErdfTP6PB4sfwHAf .label text,#mermaid-svg-ErdfTP6PB4sfwHAf span{fill:#333;color:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf .node rect,#mermaid-svg-ErdfTP6PB4sfwHAf .node circle,#mermaid-svg-ErdfTP6PB4sfwHAf .node ellipse,#mermaid-svg-ErdfTP6PB4sfwHAf .node polygon,#mermaid-svg-ErdfTP6PB4sfwHAf .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ErdfTP6PB4sfwHAf .rough-node .label text,#mermaid-svg-ErdfTP6PB4sfwHAf .node .label text,#mermaid-svg-ErdfTP6PB4sfwHAf .image-shape .label,#mermaid-svg-ErdfTP6PB4sfwHAf .icon-shape .label{text-anchor:middle;}#mermaid-svg-ErdfTP6PB4sfwHAf .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-ErdfTP6PB4sfwHAf .rough-node .label,#mermaid-svg-ErdfTP6PB4sfwHAf .node .label,#mermaid-svg-ErdfTP6PB4sfwHAf .image-shape .label,#mermaid-svg-ErdfTP6PB4sfwHAf .icon-shape .label{text-align:center;}#mermaid-svg-ErdfTP6PB4sfwHAf .node.clickable{cursor:pointer;}#mermaid-svg-ErdfTP6PB4sfwHAf .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-ErdfTP6PB4sfwHAf .arrowheadPath{fill:#333333;}#mermaid-svg-ErdfTP6PB4sfwHAf .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ErdfTP6PB4sfwHAf .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ErdfTP6PB4sfwHAf .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ErdfTP6PB4sfwHAf .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-ErdfTP6PB4sfwHAf .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ErdfTP6PB4sfwHAf .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster text{fill:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf .cluster span{color:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ErdfTP6PB4sfwHAf .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-ErdfTP6PB4sfwHAf rect.text{fill:none;stroke-width:0;}#mermaid-svg-ErdfTP6PB4sfwHAf .icon-shape,#mermaid-svg-ErdfTP6PB4sfwHAf .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-ErdfTP6PB4sfwHAf .icon-shape p,#mermaid-svg-ErdfTP6PB4sfwHAf .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-ErdfTP6PB4sfwHAf .icon-shape .label rect,#mermaid-svg-ErdfTP6PB4sfwHAf .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-ErdfTP6PB4sfwHAf .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-ErdfTP6PB4sfwHAf .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-ErdfTP6PB4sfwHAf :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 本地修改 server.js / admin
本地 npm start 验证
scp 指定文件到 ECS
systemctl restart guardsky-upgrade
curl /health
调用 /fra/check/update
App 真机验证

常见问题

1. ECS 上 curl 127.0.0.1 可以,公网不通

优先检查:

  • 阿里云安全组是否放行 8080。
  • Ubuntu ufw 是否放行。
  • 服务是否监听在 0.0.0.0,不要只监听 127.0.0.1

2. App 能检查到更新,但 APK 下载失败

看接口返回的 fileUrl。如果里面是:

text 复制代码
http://localhost:8080/updates/xxx.apk

那手机一定下载不了。应该配置:

text 复制代码
PUBLIC_BASE_URL=http://203.0.113.10:8080

3. 后台上传大 APK 失败

如果走 Nginx,需要设置:

nginx 复制代码
client_max_body_size 1200m;

否则大包可能被 Nginx 拦掉。

小结

这篇把 Node 升级服务从本地搬到了阿里云 ECS。核心不是命令多复杂,而是要把链路验证完整:

text 复制代码
systemd 在线 -> 本机 health -> 公网 health -> 升级接口 -> APK 下载 -> App 真机

下一篇继续写后台管理页面,看看怎么通过 Web 页面维护多应用版本、上传 APK,并自动选择当前生效版本。

相关推荐
難釋懷2 小时前
Nginx-UpStream工作流程
运维·nginx
難釋懷2 小时前
Nginx-AB安装
运维·nginx
承渊政道2 小时前
【MySQL数据库学习】(MySQL内置函数)
数据库·学习·mysql·ubuntu·bash·数据库开发·数据库系统
回忆2012初秋11 小时前
【Nginx】原理、配置与运维实战(2)
运维·nginx·策略模式
2601_9618454216 小时前
法考真题及答案解析|历年真题|资料已整理
linux·windows·ubuntu·macos·centos·gnu
阿豪啊16 小时前
记一次 Nginx 跨域配置踩坑与优化:从嵌套 If 报错到 Map 指令最佳实践
nginx
2601_9618752418 小时前
法考资料全套2026|客观题|主观题|资料已整理
阿里云·云计算·腾讯云·azure·七牛云存储·csdn开发云·火山引擎
愛~杦辷个訾1 天前
Java Springboot使用阿里云oss对图片进行等质量压缩,转换成webp格式的压缩图。
java·spring boot·阿里云·oss
成为你的宁宁1 天前
【Prometheus Operator监控K8S Nginx】
nginx·kubernetes·prometheus