从零搭建微信小程序后端:域名、备案、HTTPS 证书与 Nginx(以 perfecttools.top 为例)
从零搭建微信小程序后端:域名、备案、HTTPS 证书与 Nginx(以 perfecttools.top 为例)
一、背景
微信小程序强制要求所有网络请求通过 HTTPS 协议,且服务器域名必须完成 ICP 备案。对于刚接触的开发者,从注册域名、DNS 解析、备案、申请 SSL 证书,到配置 Nginx 反向代理后端服务,最后在小程序后台设置合法域名,整个链路节点多且跨平台。
本文以华为云 Ubuntu 服务器 + 腾讯云注册的 perfecttools.top 域名为例,详细记录完整部署流程。特别使用 acme.sh 工具申请和管理 Let’s Encrypt 免费证书,并实现自动续期。同时,借助子域名划分不同功能模块(如 api.perfecttools.top、admin.perfecttools.top),让整体架构更清晰易维护。
二、发展
早期微信小程序对 HTTPS 的严格要求增加了部署门槛,但 Let’s Encrypt 等免费证书的出现大幅降低了成本。acme.sh 作为纯 Shell 实现的 ACME 客户端,安装零依赖、配置简单、自动续期稳定,成为很多运维人员的首选。Nginx 凭借其高性能和灵活的代理能力,一直是 SSL 终结和反向代理的事实标准。如今,这套组合已成为个人开发者和小型团队快速上线小程序的标配方案。
三、目的
本文将以一个微信小程序 demo 为主线,串联以下完整流程:
- 在腾讯云注册域名
perfecttools.top并划分子域名 - 配置 DNS 解析,将不同子域名指向华为云服务器
- 提交 ICP 备案
- 在华为云 ECS 上安装 Nginx 并部署后端服务
- 使用 acme.sh 申请免费 SSL 证书并配置自动续期
- 配置 Nginx 启用 HTTPS 并按子域名反向代理到对应后端模块
- 在小程序后台配置合法域名,并通过
wx.request进行接口调用 - 验证整条链路
四、核心概念与架构
4.1 核心术语
- 子域名:在主域名前添加前缀,用于划分不同服务模块,如
api.perfecttools.top提供 API,admin.perfecttools.top提供管理后台。 - A 记录:DNS 中将域名指向 IPv4 地址的记录。
- ICP 备案:中国大陆境内提供 Web 服务的网站必须完成工信部备案。
- ACME 协议:自动化证书管理环境协议,Let’s Encrypt 使用该协议验证域名所有权并签发证书。
- acme.sh:一款轻量 Shell 脚本,支持多种 DNS API 自动完成域名验证,实现证书自动申请和续期。
- Nginx 反向代理:将 HTTPS 请求解密后转发给后端应用,并将响应加密返回客户端。
- SSL 终结:在 Nginx 层面处理 SSL 加密和解密,后端服务只需处理 HTTP。
4.2 整体架构图
4.3 核心业务流程
Q&A
Q1:为什么小程序必须使用 HTTPS?
A:微信要求所有网络请求加密传输,防止中间人攻击和数据泄露,保护用户隐私。
Q2:acme.sh 与 Certbot 的主要区别?
A:acme.sh 无需 root 权限,零系统依赖,对 DNS API 的支持更丰富,配置更轻量,尤其适合自动化场景。
五、详细操作步骤
5.1 域名申请与子域名规划
在腾讯云注册 perfecttools.top,并规划以下子域名:
| 子域名 | 功能 | 后端端口 | 说明 |
|---|---|---|---|
api.perfecttools.top | API 接口 | 8080 | 小程序调用的主接口 |
admin.perfecttools.top | 管理后台 | 8081 | 内部管理界面 |
static.perfecttools.top | 静态资源 | - | 直接由 Nginx 返回 |
@(根域名) | 官网首页 | - | 静态页面 |
5.2 DNS 解析
在腾讯云 DNS 解析控制台添加 A 记录:
- 主机记录:
api,类型 A,值:华为云服务器公网 IP - 主机记录:
admin,类型 A,值:同上 - 主机记录:
static,类型 A,值:同上 - 主机记录:
@,类型 A,值:同上
待解析生效后,可通过 ping api.perfecttools.top 验证。
5.3 ICP 备案
在腾讯云备案系统提交备案信息,填写网站名称、用途等,上传身份证件。一般需 15~20 个工作日。备案通过后会获得备案号,需要在网站底部展示。
5.4 服务器环境搭建(华为云 Ubuntu 20.04)
# 更新系统
sudo apt update && sudo apt upgrade -y
# 安装 Nginx
sudo apt install nginx -y
# 开放防火墙端口
sudo ufw allow 'Nginx Full'
# 华为云安全组需同时放行 80 和 443 端口
# 启动 Nginx
sudo systemctl enable nginx
sudo systemctl start nginx
5.5 部署后端服务示例
假设我们有两个 Spring Boot 服务:
api-service.jar监听 8080admin-service.jar监听 8081
为每个服务创建 systemd 管理文件:
# /etc/systemd/system/api-service.service
[Unit]
Description=API Service
After=network.target
[Service]
ExecStart=/usr/bin/java -jar /opt/apps/api-service.jar
User=www-data
Restart=always
[Install]
WantedBy=multi-user.target
类似地创建 admin-service.service,然后启动:
sudo systemctl daemon-reload
sudo systemctl enable api-service admin-service
sudo systemctl start api-service admin-service
5.6 使用 acme.sh 申请 SSL 证书
安装 acme.sh
curl https://get.acme.sh | sh -s email=your-email@example.com
source ~/.bashrc
配置 DNS API(以腾讯云为例)
acme.sh 支持数百个 DNS 服务商的 API 自动验证。对于腾讯云,需要设置 DNSPod API Token(腾讯云 DNSPod 与腾讯云账户互通)。
export DP_Id="你的DNSPod ID"
export DP_Key="你的DNSPod Token"
申请泛域名证书(推荐一次申请覆盖所有子域名)
acme.sh --issue --dns dns_dp -d perfecttools.top -d '*.perfecttools.top'
dns_dp 是 acme.sh 内置的腾讯云 DNSPod 接口。完成后证书保存在 ~/.acme.sh/perfecttools.top_ecc/ 目录(默认使用 ECC 密钥)。
安装证书到 Nginx 使用的目录
sudo mkdir -p /etc/nginx/ssl/perfecttools.top
acme.sh --install-cert -d perfecttools.top -d '*.perfecttools.top' \
--key-file /etc/nginx/ssl/perfecttools.top/privkey.pem \
--fullchain-file /etc/nginx/ssl/perfecttools.top/fullchain.pem \
--reloadcmd "sudo systemctl reload nginx"
该命令将证书复制到 /etc/nginx/ssl/ 目录,并在证书更新时自动重载 Nginx。
自动续期
acme.sh 安装时已自动添加 cron 任务,每天检查证书有效期,到期前 60 天自动续期。可通过以下命令查看:
crontab -l | grep acme.sh
5.7 Nginx 配置 HTTPS 与反向代理
编辑 /etc/nginx/sites-available/perfecttools.top:
# HTTP 跳转到 HTTPS
server {
listen 80;
server_name perfecttools.top *.perfecttools.top;
return 301 https://$host$request_uri;
}
# API 子域名
server {
listen 443 ssl http2;
server_name api.perfecttools.top;
ssl_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/perfecttools.top/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8080;
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 https;
}
}
# Admin 管理后台
server {
listen 443 ssl http2;
server_name admin.perfecttools.top;
# 复用相同证书(因为泛域名证书已覆盖)
ssl_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/perfecttools.top/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
proxy_pass http://127.0.0.1:8081;
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 https;
}
}
# 根域名静态页面
server {
listen 443 ssl http2;
server_name perfecttools.top;
ssl_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/perfecttools.top/privkey.pem;
ssl_trusted_certificate /etc/nginx/ssl/perfecttools.top/fullchain.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
root /var/www/html;
index index.html;
}
启用站点并重载 Nginx:
sudo ln -s /etc/nginx/sites-available/perfecttools.top /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
5.8 微信小程序配置
小程序后台设置合法域名
登录微信公众平台 -> 开发 -> 开发管理 -> 服务器域名,在 request 合法域名 中添加:
https://api.perfecttools.top
(每月可修改 5 次,且必须为备案域名)
小程序端调用示例
// 在小程序的 app.js 或页面逻辑中
wx.request({
url: 'https://api.perfecttools.top/greeting',
method: 'GET',
success(res) {
console.log('服务器返回:', res.data);
},
fail(err) {
console.error('请求失败', err);
}
})
后端提供测试接口
@RestController
public class GreetingController {
@GetMapping("/greeting")
public String greeting() {
return "Hello from API service!";
}
}
使用微信开发者工具编译预览,即可看到请求成功返回数据。
5.9 验证全链路
- 浏览器直接访问
https://api.perfecttools.top/greeting,应显示 JSON 或字符串。 - 使用
curl -v https://api.perfecttools.top/greeting检查 SSL 握手是否成功。 - 检查
acme.sh状态:acme.sh --list列出所有证书和到期时间。 - 在微信开发者工具中查看 Network 面板,确认请求地址为合法域名且无证书错误。
六、高性能设计
6.1 HTTP/2 支持
Nginx 配置中已添加 http2,多路复用减少延迟。
6.2 Gzip 压缩
gzip on;
gzip_types text/plain application/json;
gzip_min_length 1000;
6.3 会话缓存与 OCSP 装订
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 114.114.114.114 valid=300s;
6.4 缓冲区调优
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
七、可靠性与安全性
7.1 acme.sh 自动续期保障
acme.sh 的 cron 任务默认每天 0 点检查,到期前自动续期并执行 --reloadcmd。若担心漏续,可监控证书到期时间(如通过 acme.sh --list 输出解析)。
7.2 强制 HTTPS 与 HSTS
在 SSL server 块中添加:
add_header Strict-Transport-Security "max-age=63072000" always;
7.3 权限控制
- SSL 私钥目录
ssl/权限设置为 700,文件 600。 - 后端应用与 Nginx 通过 127.0.0.1 通信,不暴露公网端口。
7.4 限制访问频率
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;
server {
location / {
limit_req zone=api_limit burst=50 nodelay;
# ...
}
}
八、进阶:多模块与扩展
8.1 增加新子域名的步骤
- DNS 添加对应 A 记录。
- 如果需要独立证书,可单独用 acme.sh 申请;但因为已有泛域名证书,直接复用即可。
- 在 Nginx 中新增
server块,配置代理或静态目录。 - 重载 Nginx。
8.2 动态路由与 Nacos 集成
若后端采用微服务框架,Nginx 可以仅作为 API 网关的统一入口,再通过 Spring Cloud Gateway 将请求路由到不同微服务,实现更精细的控制。
九、生产环境最佳实践
- 备份与恢复:定期备份
/etc/letsencrypt/或 acme.sh 的证书目录,以及 Nginx 配置文件。 - 日志集中管理:接入 ELK 或云日志服务,监控 Nginx 访问和错误日志。
- 自动化部署:使用 CI/CD 工具更新后端 jar 包后自动重启 systemd 服务。
- 监控告警:配置 UptimeRobot 探测 API 接口可用性,设置证书到期前 30 天邮件提醒(通过 acme.sh 的
--renew-hook脚本实现)。 - 安全更新:定期
sudo apt update && sudo apt upgrade更新系统及 Nginx 版本。
十、总结与推荐阅读
从域名注册、备案、DNS 解析,到 acme.sh 自动申请泛域名 SSL 证书,再到 Nginx 反向代理后端服务,最后在小程序后台完成域名绑定,整个过程虽然涉及多个平台,但每一步都有章可循。利用泛域名证书和 acme.sh 的自动续期,可以大大降低运维负担;通过子域名划分不同功能模块,让架构更清晰,也为未来扩展留足了空间。
【额外内容】
小程序备案、ICP备案等国家审批时候,同时只能有一个提交审批另一个会被立即打回。
推荐阅读:
更多推荐


所有评论(0)