Acme.sh 是一款非常流行的自动 SSL 证书申请和部署工具。我在之前的博客中也多次提到用它做申请证书。然而,之前我只是直接在 VPS 中安装 acme.sh 后申请证书,然后手动拷贝证书到其他地方,仍然有些复杂。
全 Docker 化是指服务全部跑在 Docker 容器里面,对运维非常友好。但 acme.sh 似乎成了 Docker 化中的最后一环,始终没有打通。近期发现 acme.sh 已经支持在 docker-compose 中管理其他容器的证书,鉴于官方文档的简略,我替其解释一二。
首先说明,本篇博客基于 deploy to docker containers · acmesh-official/acme.sh Wiki (github.com)的第二部分,即 在 Docker 容器中的 acme.sh 为其他容器中的应用申请和部署证书。
编写
docker-compose.yaml
文件如下:version: "3" services: nginx: image: nginx:alpine container_name: nginx restart: always ports: - 443:443 - 80:80 volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./nginx/www:/var/www - ./nginx/cert:/etc/nginx/ssl labels: - sh.acme.autoload.domain=example.com networks: - dockernet acme.sh: image: neilpang/acme.sh container_name: acme.sh command: daemon volumes: - ./acmeout:/acme.sh - /var/run/docker.sock:/var/run/docker.sock environment: - DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=example.com - DEPLOY_DOCKER_CONTAINER_KEY_FILE="/etc/nginx/ssl/example.com/key.pem" - DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/example.com/cert.pem" - DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/example.com/ca.pem" - DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/example.com/full.pem" - DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="service nginx force-reload" networks: - dockernet networks: dockernet:
实际操作时需要替换
example.com
为你的域名。并且按照你的需求调整 Nginx 的相关配置。- 创建文件夹用于存放证书和配置文件。按照 1. 中配置的
volumes
部分,在宿主机上新建文件夹,即:./nginx/conf.d
,./nginx/www
,./nginx/cert
和./acmeout
。 选择申请证书的方式,个人推荐 DNS 方式,例如使用 CloudFlare:
docker exec \ -e [email protected] \ -e CF_Key=xxxxxxxxxx \ acme.sh --issue -d example.com --dns dns_cf
部署证书:
docker exec acme.sh --deploy -d example.com --deploy-hook docker
检查 Nginx 状态:
docker logs -f nginx
如果 Nginx 还在反复重启,那还是检查日志对症解决。基本到这里,证书就部署完成了。