acme.sh部署证书到Nginx自动重载配置
要让 acme.sh 签发的证书在续期后自动生效,关键是把证书路径写进 Nginx 配置,并让 acme.sh 在续期成功后自动执行 nginx -s reload。
下面从零开始,按准备、操作、避坑、验证的顺序走一遍。
开始前的环境检查和准备
先确认服务器上已经装好 Nginx,并且域名已经解析到这台机器。
用下面命令检查 Nginx 状态和版本:
nginx -v
systemctl status nginx
如果 Nginx 没安装,先用系统包管理器装好。
另外,确保 80 或 443 端口没有被其他程序占用,证书验证需要用到。
安装 acme.sh 只需要一条命令,它会自动下载脚本并创建定时任务:
curl https://get.acme.sh | sh -s email=你的邮箱@example.com
安装完成后重新加载一下 shell 环境,或者直接关闭终端再登录。
acme.sh 默认会安装到 ~/.acme.sh/ 目录,并注册一个 cron 任务用于自动续期。
用 acme.sh 签发证书
acme.sh 支持多种验证方式,最常用的是 --webroot 和 --standalone。
如果 Nginx 正在运行且能通过 80 端口访问,推荐用 webroot 模式,不需要停 Nginx。
假设网站根目录是 /var/www/html,执行:
~/.acme.sh/acme.sh --issue -d example.com -d www.example.com --webroot /var/www/html
如果你没有网站目录,或者 Nginx 暂时没跑,可以用 standalone 模式,它会临时启动一个 80 端口监听:
~/.acme.sh/acme.sh --issue -d example.com --standalone
签发成功后,证书文件会存放在 ~/.acme.sh/example.com/ 下。
但不要直接把 Nginx 配置指向这个目录,因为 acme.sh 内部目录结构可能变化,正确做法是用 --install-cert 把证书复制到固定位置。
把证书部署到 Nginx 并配置自动重载
这一步是核心。
用 --install-cert 命令把证书安装到指定路径,同时指定重载命令。
这样每次 acme.sh 自动续期后,都会触发 Nginx 重载。
先创建存放证书的目录,例如 /etc/nginx/ssl/example.com/:
mkdir -p /etc/nginx/ssl/example.com
然后执行安装命令:
~/.acme.sh/acme.sh --install-cert -d example.com \
--key-file /etc/nginx/ssl/example.com/example.com.key \
--fullchain-file /etc/nginx/ssl/example.com/fullchain.cer \
--reloadcmd "nginx -s reload"
注意 --reloadcmd 里的命令会在每次证书更新后执行。
如果 Nginx 是通过 systemd 管理的,也可以写成 systemctl reload nginx,但需要确保 acme.sh 运行用户有权限执行。
下一步修改 Nginx 站点配置,让 443 端口使用这些证书。
打开对应的配置文件,通常位于 /etc/nginx/conf.d/ 或 /etc/nginx/sites-available/,加入或修改如下内容:
server {
listen 443 ssl;
server_name example.com www.example.com;
ssl_certificate /etc/nginx/ssl/example.com/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/example.com/example.com.key;
# 其他配置...
}
保存后先手动测试配置并重载一次,确认没有语法错误:
nginx -t && nginx -s reload
容易踩坑的几个地方
权限问题:acme.sh 默认以当前用户运行,如果它没有权限写入 /etc/nginx/ssl/ 或执行 nginx -s reload,自动重载会失败。
可以提前把目录权限设置好,或者用 root 用户执行安装命令。
路径写错:Nginx 配置里必须指向 --install-cert 复制后的固定路径,不要直接写 ~/.acme.sh/ 下的文件,否则 acme.sh 目录变动后证书会失效。
reloadcmd 没生效:如果续期后 Nginx 没有自动加载新证书,检查 acme.sh 的日志,确认 reload 命令是否执行成功。
可以用 ~/.acme.sh/acme.sh --list 查看已管理的证书,再用 --info -d example.com 查看详情。
80 端口被占用:webroot 模式需要 80 端口可访问,如果被其他服务占用,验证会失败。
可以临时改用 standalone 模式,或者调整 Nginx 配置让验证路径可访问。
验证自动续期和重载是否生效
acme.sh 安装后会自动添加 cron 任务,通常每天检查一次证书是否需要续期。
可以手动模拟续期来测试整个流程:
~/.acme.sh/acme.sh --renew -d example.com --force
执行后观察输出,如果看到 Reload success 之类的提示,说明重载命令执行成功。
然后打开浏览器访问 https://example.com,查看证书有效期是否更新。
也可以用命令行检查 Nginx 当前加载的证书信息:
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates
如果显示的日期是新的,说明证书已经生效。
另外,确认 cron 任务存在:
crontab -l | grep acme.sh
一般会看到类似 0 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null 的行。
常见疑问
acme.sh 续期后 Nginx 没自动重载怎么办?
先检查 --reloadcmd 是否在 --install-cert 时正确指定,可以用 ~/.acme.sh/acme.sh --info -d example.com 查看已配置的重载命令。如果命令路径不对或权限不足,重新执行一次 --install-cert 并带上正确的 --reloadcmd。
可以同时给多个域名部署证书吗?
可以。在 --issue 时用多个 -d 参数指定域名,然后在 --install-cert 时同样指定主域名,证书文件会包含所有域名。Nginx 配置中 server_name 也要写全。
自动续期失败会有通知吗?
acme.sh 本身不发送通知,但可以通过配置邮件或 webhook 来接收续期结果。如果不想额外配置,建议定期手动执行 --cron 并查看日志,或者用监控工具检查证书到期时间。
按上面步骤走完,acme.sh 部署证书到 Nginx 并自动重载配置就算完成了。
后续只要 cron 任务正常运行,证书到期前会自动续期并触发 Nginx 重载,不需要每次手动干预。