备案期用 ECS + Nginx 部署静态站

2026-06-11 · 运维

2026-06-22 更新:Emo 已迁至 emo.icemelt.funwww.icemelt.fun/emo/ 现 301 跳转。完整迁移步骤见 备案后 Emo 从 /emo/ 子路径迁到子域名。 下文保留备案期子路径方案作历史记录。

上一篇写了 OSS 静态站 的坑。备案材料要求「域名能打开网站首页」,但 CDN 加速域名也要备案 — 审核前往往外网 403,形成「打不开 → 审不过」的死循环。

我买了一台阿里云 ECS,在备案完成前用 Nginx 直接托管静态文件,DNS 用 A 记录指到公网 IP。博客和 Emo 应用都跑起来了,HTTPS 用 Let's Encrypt 免费证书。下文是实操记录,供同类场景参考。

整体架构

访问地址 服务器目录 项目
https://www.icemelt.fun /var/www/icemelt-blog 备案首页 / 本博客
https://www.icemelt.fun/emo/ /var/www/emo-world-map(与博客同级) Emo 世界地图 Web 版

系统:Alibaba Cloud Linux 3.2104(类 CentOS,用 dnf 装软件)。 备案通过后仍可继续用 ECS,也可以再迁回 OSS+CDN。

为什么不用 CDN 等备案

OSS 文件可以照常上传当备份,但对外解析在审核期应指 ECS,不要 CNAME 到未备案的 CDN。 审核员要能打开你填的首页 URL(我填的是 https://www.icemelt.fun/)。

安全组入方向放行:22(SSH)、80443

DNS:A 记录,不是 CNAME

子域名 emo.icemelt.fun未备案时会被阿里云拦截(外网 403,页面标题 Non-compliance ICP Filing),Let's Encrypt 也无法验证。所以 Emo 先挂在 www.icemelt.fun/emo/,共用主域名的备案与 HTTPS 证书。

服务器装 Nginx(Workbench 可复制)

SSH 可用阿里云 Workbench,不必强求本机 ssh。在服务器上执行:

dnf -y update
dnf -y install nginx rsync || {
  tee /etc/yum.repos.d/nginx.repo <<'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/8/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
  dnf -y install nginx rsync
}
mkdir -p /var/www/icemelt-blog /var/www/emo-world-map
chown -R nginx:nginx /var/www/icemelt-blog /var/www/emo-world-map
mv /etc/nginx/conf.d/default.conf /etc/nginx/conf.d/default.conf.bak 2>/dev/null || true
systemctl enable --now nginx

ACL 的配置目录是 /etc/nginx/conf.d/*.conf,不是 Ubuntu 的 sites-enabled。站点配置里给博客根目录加一段 location /emo/ 做 SPA 回退 /emo/index.html

本机上传:Mac 用 rsync,别在服务器上 scp 自己

常见误会:已经 Workbench 登录进服务器(提示符像 root@iZbp**********,你的实例主机名),却在服务器里执行

scp ~/Projects/icemelt-blog/... root@公网IP:/root/

服务器上没有 Mac 的项目路径,且 SSH 连自己还要密钥,会 Permission denied (publickey)上传应在 Mac 终端做,或在 Workbench 里直接粘贴安装命令 / 上传文件。

Mac 首次连接需在 ECS 绑定 SSH 公钥,或 Workbench 里把 id_rsa.pub 写入 ~/.ssh/authorized_keys

# 博客
cd ~/Projects/icemelt-blog
export DEPLOY_HOST=你的ECS公网IP
./deploy/server-sync.sh

# Emo(构建时带 baseUrl /emo/)
cd ~/Projects/emo-world-map
./deploy/server-deploy.sh

免费 HTTPS:certbot

备案首页能打开后,在服务器上:

dnf -y install certbot python3-certbot-nginx
certbot --nginx -d www.icemelt.fun -d icemelt.fun

按提示选强制跳转 HTTPS。证书自动续期可用 certbot renew --dry-run 检查。

emo.icemelt.fun 的子域证书要等该域名入备案后再申请;备案期用 /emo/ 子路径即可,高德 Web Key 白名单填 www.icemelt.fun

Expo Web 挂子路径 /emo/

子路径部署要在构建时设 EXPO_PUBLIC_BASE_PATH=/emo(或 app.config.jsexperiments.baseUrl),否则 JS 仍请求 /_expo/... 会 404。 构建产物上传到 /var/www/emo-world-map/(与博客同级),Nginx 用 alias/emo/ 指过去;不要把 Emo 文件放进博客目录里

和 OSS 方案如何衔接

  1. 审核中:DNS → ECS,Nginx 提供页面,备案材料填该 URL。
  2. 审核通过:可继续 ECS;若迁 OSS+CDN,把 A 记录改成 CNAME,并刷新 CDN 缓存。
  3. 构建产物:仍可 ossutil 上传到桶作备份或多地发布。

踩坑小结

仓库里保留了 deploy/server-sync.shserver-bootstrap-acl3.shnginx-icemelt.fun.conf,换机器可复用。更完整的命令清单见项目内 deploy/SERVER.md

← 全部文章