操作记录 + 可复用教程本次域名切换已完成

账单应用域名与 HTTPS 配置教程

把现有账单应用接入新域名,让浏览器通过 HTTPS 直接访问,并让证书自动续期。

https://bill.lzlee.xyz/
原访问地址:http://lzlee.xyz:3000/
Ubuntu 22.04Node / Express + PM2Nginx + Let's Encrypt
这次实际做了什么你在阿里云控制台添加 DNS 解析和安全组规则;我在服务器备份配置、增加 Nginx 站点、补充应用来源、申请 HTTPS 证书,并完成外网与浏览器检查。应用代码、前端构建和账单数据库未替换。
1. DNS 找到服务器bill.lzlee.xyz→ 8.163.117.252
2. 安全组允许访问公网 TCP 80 / 443HTTP / HTTPS
3. Nginx 接收请求按域名匹配站点处理 HTTPS 与转发
4. 原应用处理业务127.0.0.1:3000PM2:bills-app

DNS 不保存网页端口。浏览器省略端口时,HTTP 使用 80、HTTPS 使用 443,再由 Nginx 转发到应用的 3000 端口。

参数本次使用的值
主域名 / 子域名lzlee.xyz / bill.lzlee.xyz
ECS 公网 IP / 地域8.163.117.252 / 广州(cn-guangzhou)
应用目录 / 进程名/opt/bills / bills-app
后端配置 / 数据/opt/bills/backend/.env
/opt/bills/backend/data/db.json
Nginx 新站点/etc/nginx/sites-available/bill.lzlee.xyz
本次备份目录/opt/bills-backups/domain-bill-20261015-122600/
当前网站已经配好,无需重新执行下列步骤用于以后复现或维护。若在同一台服务器重复操作,先检查已有配置;尤其不要用第 04 步的初始 HTTP 配置覆盖已经启用 HTTPS 的站点。
STEP 01 / 服务器

连接服务器,检查服务并备份

打开 Windows PowerShell,使用本机已有密钥连接。本次使用的是 bills_ecs.pem;换电脑时应改成你自己的密钥路径。

Windows PowerShell · 连接服务器
ssh -i "C:\Users\Lee\.ssh\bills_ecs.pem" root@8.163.117.252

登录后执行以下检查。后文标为“服务器”的命令都在这个 SSH 窗口中运行。

Ubuntu 服务器 · root
pm2 status
curl -fsS http://127.0.0.1:3000/api/health
nginx -t
ss -lntp | grep -E ':(80|443|3000)\b'

确认 bills-app 为 online,健康接口返回 "status":"ok"。本机 Nginx 已安装;新服务器如果没有 Nginx,需先安装并启动,再继续配置。

先备份,再修改配置

Ubuntu 服务器 · root · 新建本次备份
BACKUP_DIR="/opt/bills-backups/domain-bill-$(date +%Y%m%d-%H%M%S)"
install -d -m 700 "$BACKUP_DIR"
cp -p /opt/bills/backend/.env "$BACKUP_DIR/backend.env"
cp -p /opt/bills/backend/data/db.json "$BACKUP_DIR/db.json"
tar -czf "$BACKUP_DIR/nginx-before.tar.gz" -C /etc nginx
sha256sum /opt/bills/backend/data/db.json "$BACKUP_DIR/db.json"
printf '备份目录:%s\n' "$BACKUP_DIR"

两份数据库的校验值应一致;记下输出的备份路径。配置过程中暂停写入新账单,可避免复制文件时数据仍在变化。数据库备份仅作保障,域名切换不需要导入或覆盖数据库。

本次已有的备份/opt/bills-backups/domain-bill-20261015-122600/ 内保存了 db.json、backend.env、nginx-before.tar.gz,以及申请证书前的 nginx-before-https.conf。环境配置备份可能含密码,应保留在受限目录。
STEP 02 / 阿里云控制台

添加 bill 子域名解析

  1. 登录阿里云控制台,打开“云解析 DNS”,进入 lzlee.xyz 的解析设置。
  2. 选择“添加记录”,按照下表填写,再点击“确定”。
  3. 新增后检查记录状态为启用,主机记录确实为 bill。
填写项填写内容作用
记录类型A指向 IPv4 地址
主机记录bill组合成 bill.lzlee.xyz
解析请求来源默认 / 默认使用默认解析线路
记录值8.163.117.252本次 ECS 公网 IP
TTL默认,本次为 600 秒解析缓存时间
状态启用让记录生效
截图中最容易填错的一项@ 代表根域名 lzlee.xyz,不会生成 bill.lzlee.xyz。应新增主机记录 bill,无需为了添加子域名去修改原来的 @ 记录;记录值也不要填写 http:// 或 :3000。
Windows PowerShell · 检查解析
Resolve-DnsName bill.lzlee.xyz -Type A
Resolve-DnsName bill.lzlee.xyz -Type A -Server dns29.hichina.com

应看到地址 8.163.117.252。第二条直接查询本域名的阿里云权威 DNS,适合区分“记录填错”和“本地缓存尚未更新”。换域名时应使用该域名自己的权威 DNS。TTL 600 秒不代表所有网络一定恰好十分钟更新完毕。

字段解释参考:阿里云 DNS 记录参数说明。

STEP 03 / 阿里云控制台

在 ECS 安全组放行 80 和 443

打开“云服务器 ECS”,切换到广州,找到公网 IP 为 8.163.117.252 的实例。进入该实例实际关联的安全组,在入方向添加规则。

填写项本次正确设置
授权策略 / 优先级允许 / 1
协议类型自定义 TCP
访问来源IPv4:0.0.0.0/0(公开网站允许任意来源访问)
访问目的端口HTTP(80) 与 HTTPS(443)

如果界面一次只能添加一个端口,就分别添加两条允许规则。你提供的下面这张图填写正确,点击“确定”保存即可。

本次阿里云安全组截图:入方向允许 TCP,来源 0.0.0.0/0,目的端口 80 与 443
本次实际填写截图。安全组 ID 以目标 ECS 实例的关联关系为准。

本次服务器的 UFW 为未启用状态,没有改动系统防火墙。以后遇到服务器已启用 UFW 时,先检查状态,再按需允许这两个端口;不需要关闭防火墙。

Ubuntu 服务器 · 检查系统防火墙
ufw status
仅当 UFW 已启用且未允许网页端口时执行
Ubuntu 服务器 · root
ufw allow 80/tcp
ufw allow 443/tcp

保留已有 SSH 管理规则,避免影响后续登录。

控制台路径与端口说明:阿里云:使用安全组。本次新入口需要 80 / 443,未调整原有 3000 端口的开放情况。

STEP 04 / 服务器

新增 Nginx 站点,转发到原应用

为新域名单独创建一个站点文件,保留服务器原有站点。以下是申请证书前的 HTTP 初始配置。

Ubuntu 服务器 · 打开新站点配置
nano /etc/nginx/sites-available/bill.lzlee.xyz

将下方内容粘贴进编辑器,按 Ctrl+O、回车保存,再按 Ctrl+X 退出。

Nginx 配置内容 · 仅用于首次启用 HTTP
server {
    listen 80;
    server_name bill.lzlee.xyz;

    client_max_body_size 50m;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
        proxy_read_timeout 310s;
        proxy_send_timeout 310s;
    }
}

server_name 对应新域名,proxy_pass 对应应用实际监听地址。本项目由后端一并提供前端页面和 /api 接口,因此整个站点转发到 3000 即可。

Ubuntu 服务器 · 首次启用站点
ln -s /etc/nginx/sites-available/bill.lzlee.xyz /etc/nginx/sites-enabled/bill.lzlee.xyz
nginx -t && systemctl reload nginx
curl -fsS -H "Host: bill.lzlee.xyz" http://127.0.0.1/api/health

如果提示符号链接已存在,先用 ls -l /etc/nginx/sites-enabled/bill.lzlee.xyz 确认它指向正确文件,不必重复创建。nginx -t 必须成功后才能重载;不要把备份文件放在 sites-enabled 目录,以免被当作有效站点重复加载。

此时先验证 HTTPDNS 和安全组生效后,访问 http://bill.lzlee.xyz/api/health 应返回正常状态。先打通 HTTP,再进入第 06 步申请证书。

配置语法参考:Nginx 官方反向代理文档。

STEP 05 / 服务器

补充本项目的允许来源

本项目通过后端 .env 中的 FRONTEND_URL 维护允许来源列表。编辑该文件,在原值末尾补充新地址,使用英文逗号分隔,不要覆盖文件内其他设置。

Ubuntu 服务器 · 编辑后端配置
nano /opt/bills/backend/.env

下面是本次最终保留的完整来源值。其中包含此前已有的历史地址;以后部署其他应用时,保留该应用自己的原值,再添加新域名的 HTTP / HTTPS 来源即可。

.env 中对应的一行 · 本次配置快照
FRONTEND_URL=http://localhost:5173,http://8.163.128.126:3000,http://bill.lzlee.xyz,https://bill.lzlee.xyz,http://bill.lzlee.xyz:3000,http://lzlee.xyz:3000
Ubuntu 服务器 · 让进程加载更新后的环境
pm2 restart bills-app --update-env
pm2 status

本次前端接口地址使用相对路径 /api,无需重新构建前端。如果其他项目把旧 IP 或域名写死在前端配置里,则需要同时修改接口地址并重新构建。FRONTEND_URL 是本项目的变量名,不是所有程序都通用。

同源访问通常不依赖跨域放行,但本次仍同步补全项目的来源配置,以保持跨域调用的响应一致;允许来源不代替账号登录验证。

STEP 06 / 服务器

申请 HTTPS 证书并自动跳转

开始前确认新域名已经指向本服务器,公网 80 端口可达,Nginx 的 server_name 正确。这里使用 Certbot 的 Nginx 插件完成证书验证和站点配置。

Ubuntu 服务器 · 先保存 HTTP 配置
cp -p /etc/nginx/sites-available/bill.lzlee.xyz "$BACKUP_DIR/nginx-before-https.conf"

BACKUP_DIR 由第 01 步创建。若重新打开了 SSH 窗口,先将它重新设为当次实际备份目录。

Ubuntu 服务器 · 安装 Certbot 及 Nginx 插件
apt-get update
apt-get install -y --no-install-recommends certbot python3-certbot-nginx

以后自行配置时,建议用交互方式申请;按提示填写你自己的联系邮箱、同意服务条款。

Ubuntu 服务器 · 首次申请证书
certbot --nginx --cert-name bill.lzlee.xyz -d bill.lzlee.xyz --redirect

--redirect 会启用 HTTP 到 HTTPS 的跳转。成功后 Certbot 会修改已有站点,添加 443 监听及证书路径,保留到 127.0.0.1:3000 的转发配置。

查看这次实际使用的非交互申请命令

这次没有配置联系邮箱,使用了下面的命令;下次自行配置推荐使用上面的交互方式。

本次操作记录 · 无邮箱注册
certbot --nginx --cert-name bill.lzlee.xyz -d bill.lzlee.xyz --non-interactive --agree-tos --register-unsafely-without-email --redirect
生成内容本次路径
证书链/etc/letsencrypt/live/bill.lzlee.xyz/fullchain.pem
证书私钥/etc/letsencrypt/live/bill.lzlee.xyz/privkey.pem
续期配置/etc/letsencrypt/renewal/bill.lzlee.xyz.conf
申请成功后不要再覆盖为初始 HTTP 配置第 04 步是申请证书前的起始模板。后续维护应编辑已经包含 443 和证书路径的现有文件;证书私钥无需下载或发给别人。

申请、Nginx 插件与续期说明:Certbot 官方使用文档。

STEP 07 / 验收

从公网和浏览器确认结果

回到 Windows PowerShell,依次检查跳转、证书与接口。这里使用 curl.exe,避免 Windows 中同名命令别名带来的差异。

Windows PowerShell · 公网验证
curl.exe -I http://bill.lzlee.xyz/
curl.exe -I https://bill.lzlee.xyz/
curl.exe https://bill.lzlee.xyz/api/health
curl.exe -i -H "Origin: https://bill.lzlee.xyz" https://bill.lzlee.xyz/api/health
检查项正确结果
HTTP 首页301,Location 指向 HTTPS
HTTPS 首页正常响应,证书校验无报错;本项目页面可能进一步跳转到登录页
健康接口HTTP 200,JSON 含 "status":"ok"
来源响应Access-Control-Allow-Origin: https://bill.lzlee.xyz
浏览器页面最终进入 https://bill.lzlee.xyz/login,输入框、样式、按钮正常

本次已经完成的验证

桌面 1366 × 900 与手机 390 × 844 两种窗口都能进入登录页。证书校验、健康接口、来源响应正常,页面未出现 JavaScript 错误。

域名改变后,原网站的登录状态不会自动转移。使用原账号在新域名重新登录即可。

本次检查到登录页面和接口为止,没有使用真实账号提交登录,也没有新增或修改账单。右侧是迁移完成后的手机页面截图。

迁移完成后,在手机尺寸浏览器中显示的我的账单登录页面
新域名下的实际登录页。

你以后复现时的验收清单

STEP 08 / 后续维护

检查证书自动续期

本次已确认 certbot.timer 为启用且运行状态,续期配置使用 Nginx 插件。无需再额外添加一套重复的定时任务。

Ubuntu 服务器 · 查看状态
certbot certificates
systemctl is-enabled certbot.timer
systemctl is-active certbot.timer
systemctl list-timers --all certbot.timer

预期可看到证书信息、enabled、active 和下次触发时间。如果定时器尚未启用,再执行 systemctl enable --now certbot.timer。

以后可补做一次续期模拟

Ubuntu 服务器 · 建议后续执行,非本次已完成项
certbot renew --dry-run

这条命令用测试环境检查续期流程,不会替换当前正式证书。本次没有运行续期模拟;“定时器已启用”与“未来每一次续期都成功”是两个不同的检查结果。

本次证书快照2026 年 10 月 15 日签发时查到的到期日为 2027 年 1 月 13 日。续期后日期会改变,以 certbot certificates 的实时结果为准。维护时保留域名正确解析和公网 80 端口可达,便于当前验证方式继续工作。
Ubuntu 服务器 · 常用排查日志
journalctl -u certbot.service --since "7 days ago" --no-pager
tail -n 80 /var/log/letsencrypt/letsencrypt.log
tail -n 80 /var/log/nginx/error.log
pm2 logs bills-app --lines 60 --nostream
排查速查

打不开时,按现象定位

现象优先检查下一步
找不到域名 / IP 错误主机记录是否填成 @、记录是否启用、本地是否有缓存查询普通 DNS 和权威 DNS;必要时更新本机 DNS 缓存
连接一直超时正确实例的安全组、系统防火墙、80 / 443 是否监听云端规则和服务器本机检查结合判断,不只看 DNS
显示 Nginx 默认页server_name、启用链接、重复站点用带 Host 的本机请求验证,查看有效配置后重载
502 Bad Gateway3000 端口、PM2 状态、后端健康接口先让 127.0.0.1:3000 正常,再查代理
页面有但接口报错接口是否仍写死旧地址、来源配置、应用日志检查浏览器网络请求,区分跨域错误、404 和后端错误
证书验证失败域名是否指对 IP、80 是否可达、Nginx 是否命中正确站点先完成普通 HTTP 的外网验证,再申请证书
申请时 ACME 连接超时服务器访问签发机构的出站网络检查 ACME 接口连通后重试,避免连续重复签发
新域名要求重新登录域名更换后的正常登录状态隔离使用原账号登录,不要因此重建数据库

DNS 还没更新,先测服务器本身

Windows PowerShell · 请求指定 IP,仍携带正确域名
curl.exe --resolve bill.lzlee.xyz:80:8.163.117.252 -I http://bill.lzlee.xyz/
curl.exe --resolve bill.lzlee.xyz:443:8.163.117.252 https://bill.lzlee.xyz/api/health

第二条需要已经签发匹配域名的证书。--resolve 仅对本次请求指定 IP,不修改电脑的 DNS;证书仍照常校验。

服务器端进一步检查

Ubuntu 服务器 · 故障时按需执行
nginx -t
ls -l /etc/nginx/sites-enabled/
ss -lntp | grep -E ':(80|443|3000)\b'
curl -fsS http://127.0.0.1:3000/api/health
curl -I --connect-timeout 5 --max-time 10 https://acme-v02.api.letsencrypt.org/directory

本次申请证书曾出现一次 ACME 请求超时,后续重试成功;没有通过关闭证书校验来绕过问题。

需要撤销配置时

只回退相关配置,保留账单数据

本次采用独立站点文件,原有 Nginx 站点仍保留。若要撤销这次新增入口,可以停用新站点,再恢复本次备份的后端环境配置。

下面仅供确实需要回退时使用会让新域名入口停止工作。确认备份属于目标操作;如果之后又改过其他后端参数,应手动撤回来源列表的改动,避免整份旧环境文件覆盖后续设置。
Ubuntu 服务器 · root · 回退本次域名改动
BACKUP_DIR="/opt/bills-backups/domain-bill-20261015-122600"
test -f "$BACKUP_DIR/backend.env" && echo "环境配置备份存在"
ls -l /etc/nginx/sites-enabled/bill.lzlee.xyz

确认文件存在、上述链接指向本次新站点后,再按顺序执行:

Ubuntu 服务器 · 仅停用新站点并恢复原环境
unlink /etc/nginx/sites-enabled/bill.lzlee.xyz
cp -p "$BACKUP_DIR/backend.env" /opt/bills/backend/.env
pm2 restart bills-app --update-env
nginx -t && systemctl reload nginx

这不会删除证书、应用或数据库。若只是申请证书失败、准备继续使用普通 HTTP,可以在备份路径确认正确的前提下,将 nginx-before-https.conf 恢复到对应站点文件,再校验并重载 Nginx。

DNS 是控制台中的独立设置;是否恢复旧域名解析,要另外检查原记录。最终检查时 lzlee.xyz 根域名已没有返回 A 记录,因此不能假定旧网址此刻仍可直接访问。

不要把数据库回滚当作域名回退域名、代理或证书配置失败,不需要恢复 db.json。覆盖旧数据库可能丢失备份之后新增的账单。
下次复用

换一个域名,重点替换这些值

项目当前示例下次怎么改
完整域名bill.lzlee.xyz同步修改 DNS、server_name、允许来源、证书命令和验证地址
DNS 主机记录bill只填子域名前缀;主域名在对应解析区域中选择
服务器 IP8.163.117.252使用目标实例当前公网 IP;确认地域和安全组
应用端口3000改为程序实际监听端口,同时更新 proxy_pass 和本机检查
应用路径 / 进程名/opt/bills / bills-app使用实际目录、环境文件、数据文件和 PM2 进程
SSH 密钥 / 备份本机 pem / 当次时间戳目录使用自己的密钥,并为每次操作新建备份

推荐顺序:确认应用正常 → 备份 → 添加解析 → 放行 80 / 443 → 配置 HTTP 转发 → 更新应用来源 → 确认 HTTP 可达 → 申请 HTTPS → 验证页面与接口 → 检查自动续期。

如果只是给现有账单应用换一个入口,通常无需重装 Node、重新创建数据库或重新部署整个前端。若是另一套应用,应先完成它自己的部署,再套用域名入口配置。

官方参考

整理日期:2026-10-15(Asia/Shanghai)。实际配置和验证结果来自本次 bill.lzlee.xyz 域名切换;界面名称与后续证书日期可能变化。本文不包含 SSH 私钥、数据库内容或账号密码。
← 返回学习