如何从 CertBot 挂载证书以在 Docker 容器内使用

NoM*_*Mad 5 mount container docker letsencrypt certbot

官方certbot( https://certbot.eff.org ) 颁发和更新证书的工具Let's Encrypt将当前有效的证书保存到${prefix}/archive/${domain}/certN.pem,其中N是任意数字。用于访问当前有效证书和密钥的路径是 中的相对符号链接${prefix}/live/${domain}/cert.pem

root@skprov2:${prefix}/live/${domain}# ls
total 12K
4.0K drwxr-xr-x 2 root root 4.0K Jul 24 16:08 ./
4.0K drwx------ 9 root root 4.0K Aug 24 10:57 ../
   0 lrwxrwxrwx 1 root root   39 Jul 24 16:08 cert.pem -> ../../archive/${domain}/cert2.pem
   0 lrwxrwxrwx 1 root root   40 Jul 24 16:08 chain.pem -> ../../archive/${domain}/chain2.pem
   0 lrwxrwxrwx 1 root root   44 Jul 24 16:08 fullchain.pem -> ../../archive/${domain}/fullchain2.pem
   0 lrwxrwxrwx 1 root root   42 Jul 24 16:08 privkey.pem -> ../../archive/${domain}/privkey2.pem
4.0K -rw-r--r-- 1 root root  682 Jul 23 09:40 README
Run Code Online (Sandbox Code Playgroud)

当仅挂载live目录时,由于相关符号链接,在 docker 容器内运行的程序将无法加载所需的证书数据。

如何certbot在 Docker 容器中使用最新(有效)的证书数据?

NoM*_*Mad 4

相对符号链接被映射到上 2 层(从domain文件夹到live文件夹、从live文件夹到root文件夹),然后进入archive文件夹,最后进入domain其中的子文件夹。

为了避免挂载所有域子目录、提供对所有证书数据的访问权限,我们必须使用 2 个挂载。

Docker 主机目录结构

我们假设 certbot 在 Docker 主机上创建了以下目录结构:

/certbot/
    |-live/
    |  |-domain.com
    |  |  |-cert.pem
    |  |  |-privkey.pem
    |  |-domain2.com
    |     |-cert.pem
    |     |-privkey.pem
    |
    |-archive/
       |-domain.com
       |  |-cert.pem
       |  |-privkey.pem
       |-domain2.com
          |-cert.pem
          |-privkey.pem
Run Code Online (Sandbox Code Playgroud)

挂载子目录

在 Docker 中,我们只希望将目标域的子目录安装在容器内。

docker run \
  -v /certbot/live/domain.com:/cert/live/domain.com:ro \
  -v /certbot/archive/domain.com:/cert/archive/domain.com:ro \
  myimage:tag
Run Code Online (Sandbox Code Playgroud)

这样,容器内的程序可以成功解析文件夹的相对路径archive,同时它们的配置指向文件夹内的符号链接live( /cert/live/domain.com/cert.pem)。