Docker Compose中用Certbot为多域名分别生成Let's Encrypt证书遇问题
问题描述
我拥有两个域名:
- domain1.com
- domain2.com
需要为每个域名分别生成包含www子域名的Let's Encrypt证书:
- 证书1:domain1.com, www.domain1.com
- 证书2:domain2.com, www.domain2.com
编写的docker-compose.yml配置如下:
version: '3' services: webserver: image: domain1-com-webserver build: dockerfile: Dockerfile.webserver container_name: webserver restart: unless-stopped ports: - "80:80" - "443:443" volumes: - web-root:/var/www/html - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt networks: - app-network certbot-domain1-com: image: certbot/certbot container_name: certbot-domain1-com volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - web-root:/var/www/html depends_on: - webserver profiles: ["with-le"] command: certonly --webroot --webroot-path=/var/www/html --email info@domain1.com --agree-tos --no-eff-email --dry-run -d domain1.com -d www.domain1.com certbot-domain2-com: image: certbot/certbot container_name: certbot-domain2-com volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - web-root:/var/www/html depends_on: - webserver profiles: ["with-le"] command: certonly --webroot --webroot-path=/var/www/html --email info@domain2.com --agree-tos --no-eff-email --dry-run --force-renewal -d domain2.com -d www.domain2.com volumes: certbot-etc: certbot-var: web-root: networks: app-network: driver: bridge
执行命令:
$ docker-compose --profile with-le up -d
得到日志:
$ docker logs certbot-domain1-com Saving debug log to /var/log/letsencrypt/letsencrypt.log Account registered. Simulating a certificate request for domain1.com and www.domain1.com The dry run was successful.
$ docker logs certbot-domain2-com Saving debug log to /var/log/letsencrypt/letsencrypt.log Another instance of Certbot is already running. Ask for help or search for solutions at https://community.letsencrypt.org. See the logfile /var/log/letsencrypt/letsencrypt.log or re-run Certbot with -v for more details.
第一个域名的Dry-Run成功,但第二个失败,提示已有Certbot实例在运行。
解决方案
方法1:合并为单个Certbot服务顺序生成两个证书
将两个域名的证书请求合并到同一个Certbot容器,通过shell脚本顺序执行,避免并发抢占锁文件:
certbot: image: certbot/certbot container_name: certbot volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - web-root:/var/www/html depends_on: - webserver profiles: ["with-le"] command: > sh -c " certonly --webroot --webroot-path=/var/www/html --email info@domain1.com --agree-tos --no-eff-email --dry-run -d domain1.com -d www.domain1.com && certonly --webroot --webroot-path=/var/www/html --email info@domain2.com --agree-tos --no-eff-email --dry-run --force-renewal -d domain2.com -d www.domain2.com "
方法2:给第二个容器添加启动延迟
通过sleep命令让第二个Certbot容器等待第一个完成后再执行,同时依赖第一个容器保证启动顺序:
certbot-domain2-com: image: certbot/certbot container_name: certbot-domain2-com volumes: - certbot-etc:/etc/letsencrypt - certbot-var:/var/lib/letsencrypt - web-root:/var/www/html depends_on: - webserver - certbot-domain1-com profiles: ["with-le"] command: > sh -c " sleep 30 && certonly --webroot --webroot-path=/var/www/html --email info@domain2.com --agree-tos --no-eff-email --dry-run --force-renewal -d domain2.com -d www.domain2.com "
方法3:分两次单独启动Certbot容器
放弃同时启动,分两次执行命令,完全避免冲突:
先执行第一个域名:
docker-compose --profile with-le up -d certbot-domain1-com
等待日志显示执行完成后,再执行第二个域名:
docker-compose --profile with-le up -d certbot-domain2-com
内容的提问来源于stack exchange,提问作者davidesp
相关产品推荐
相关产品推荐

