如何在 certbot 更新后从内部 docker 重新启动主机 nginx

How to restart host nginx from inside docker after certbot renew

如果你有一个 docker 容器 运行 certbot,但是一个 nginx 实例在主机上使用这些证书 运行,你如何从 docker容器?

这是运行容器

certbot:
    image: certbot/dns-ovh
    container_name: certbot
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt
      - /var/lib/letsencrypt:/var/lib/letsencrypt
      - /root/.secrets/certbot-ovh.ini:/root/.secrets/ovh-creds.ini
    entrypoint: /bin/sh -c 'trap exit  TERM; while :; do certbot renew sleep 12h & wait $${!}; done;'

renew 命令需要添加--post-hook,使用ssh 向主机发送nginx reload 命令

为此,容器需要 运行 和 network_mode: "host"

那么当 starting/recreating 容器时,您需要安装 sshpassopenssh。这是完成的 apk add openssh sshpass

然后在 post-hook 中,您需要通过 ssh 进入主机并重新加载 nginx

sshpass -p 'your password' ssh -o 'StrictHostKeyChecking no' root@localhost 'systemctl reload nginx'

假设您有 root 权限。这使用 sshpass 在 ssh 中输入密码,跳过 "do you want to add the fingerprint" 消息并将 relaod 命令发送到 localhost

将这些全部放入 docker-compose 文件如下所示:

  certbot:
    image: certbot/dns-ovh
    container_name: certbot
    network_mode: "host"
    volumes:
      - /etc/letsencrypt/:/etc/letsencrypt
      - /var/lib/letsencrypt:/var/lib/letsencrypt
      - /root/.secrets/certbot-ovh.ini:/root/.secrets/ovh-creds.ini
    entrypoint: >
      /bin/sh -c 
      'apk add openssh sshpass &&
      trap exit  TERM; while :;
      do certbot renew --post-hook 
      "sshpass -p '"'"'your password'"'"' ssh -o '"'"'StrictHostKeyChecking no'"'"' root@localhost '"'"'systemctl reload nginx'"'"'";
      sleep 12h & wait $${!}; done;'

这里的 > 允许写任意多的缩进行,而不需要添加另一个转义层。它还会在稍后将这些行合并为一行。

这里使用的'"'"'用于转义--post-hook引号里面的单引号',它关闭第一个单引号,打开一个新的双引号包含单引号,然后再次打开单引号。