[acmesh-official/acme.sh]重构 Dockerfile, 并添加在 acme.sh 容器内重启其它容器的功能

2024-02-22 338 views
8

主要是为了 SSL 证书更新后,便于在其它容器内重载证书。

使用方法:

  1. 给 acme.sh 容器自身添加一个 label, 为了让 DEPLOY_DOCKER_CONTAINER_RELOAD_CMD 在本容器执行
  2. 映射 /var/run/docker.sock 给 acme.sh 容器
  3. DEPLOY_DOCKER_CONTAINER_RELOAD_CMD 命令为 restart-container.sh <容器名称> (容器名称可以填多个,以空格分隔)

完整 docker-compose.yml 配置示例如下:

version: '3.9'

services:
  acme.sh:
    image: neilpang/acme.sh:3.0.4
    container_name: acme.sh
    restart: unless-stopped
    network_mode: host
    environment:
      TZ: Asia/Taipei
      HE_Username: username
      HE_Password: password
      DEPLOY_DOCKER_CONTAINER_LABEL: "com.example.container.name=acme.sh"
      DEPLOY_DOCKER_CONTAINER_RELOAD_CMD: "restart-container.sh nginx_1 nginx_2 nginx_3"
    volumes:
      - ./acme.sh-data:/acme.sh
      - /var/run/docker.sock:/var/run/docker.sock:ro
    labels:
      - "com.example.container.name=acme.sh"
    command: daemon

回答

8

@Neilpang 这个文档我看过了,如果目标容器不提供重载证书功能(如: nginx -s reload),是无法重新加载证书的。 所以我在 acme.sh 容器添加了一个 restart-container.sh 脚本,它可以通过 Docker 的 API 直接重启其它容器。

5

如果对方容器没有提供 graceful 的 reload 方式, 就不能从外部强行去重启. 这不安全,会造成数据损坏.

3

对于某些程序,强行重启是没有任何影响的。例如:使用了 v2ray 插件的 shadowsocks-rust, 而且此脚本也仅添加了一个功能,是对于没办法进行 graceful reload 的一个补充,至于是否使用,取决于用户本身。

另附上相关 issue: https://github.com/shadowsocks/shadowsocks-rust/issues/748

2

@Neilpang 但是 docker.sh 似乎不支持在多个容器中执行命令,改起来可能比较复杂。

例如我有一个证书被 shadowsocks-rust 的 v2ray 和 xray 容器使用(一个证书被多个容器使用),而 docker.sh 只支持单个容器。这种情况下似乎用 restart-container.sh 来重启多个容器的方式更好。

6

有两个解决方案:

  1. 把证书文件都 -v 到主机上,同一个位置. 然后再主机上运行 acme.sh 申请证书. 然后 用 --install-cert --reload-cmd "docker restart A && docker restart B"

  2. 或者修改 docker.sh, 让 DEPLOY_DOCKER_CONTAINER_LABEL 支持逗号分隔多个container 即可.

6

对于有系统洁癖的用户来说,方案 2 会更好。 我会想办法修改 docker.sh 看看如何实现,但是对不怎么熟悉 linux shell 的我来说有些困难,可能无法实现,可能还需大佬的支持? @Neilpang

1

很多地方都是支持逗号分隔的. 所以基本工具都是有的. 找到跟着用就好了. 我不想在多增加任何文件了. 有些文件还要进一步删除.