在 yml 文件中通过环境变量指定备份页面上的运行容器

提议的插件:discourse-container-names.git

您希望完成什么工作?

我希望开发一个简单的插件,在备份页面显示容器名称,效果如下(示例):

容器名称应来自 yml 文件中的环境变量,如下所示:

应用说明:

  1. 容器名称必须来自上述图片中所示的环境变量(例如,不能通过 docker ps 获取)。

  2. 如果存在数据容器和应用容器,最好也能显示数据容器的名称:

  • Container: app # 基本独立容器名称示例
  • Containers: socket-only, data # 基本双容器设置示例
  1. 这样做的原因是,我们运行多个应用容器,我希望在查看管理页面(尤其是备份页面,如第一张图所示)时,始终能知道是哪个容器正在运行。

您希望何时完成?

随时都可以,不着急。这对 Discourse 插件专家来说似乎是一个非常简单的插件。这只是一个管理备份页面的“锦上添花”功能,我自己没有动力去编写,所以很乐意支付合理的费用请人完成!

您能为此任务提供的预算是多少(美元)?

欢迎私信我。

该插件应免费向整个 Discourse 社区开放,以便其他运行多个容器的 Discourse 系统管理员,或任何希望在管理面板备份页面查看当前运行容器名称(即使是独立模式)的用户使用。

好主意,要不要把实际的容器 ID 也加上?

可以从容器内部通过以下方式查询:
cat /proc/self/cgroup|grep "systemd:/docker"| awk -F/ '{print $3}'|cut -c1-12

谢谢,但在插件中使用依赖平台的命令行工具来获取信息对我来说行不通(无法满足要求):(从以下命令获取 Docker ID 在我们的 Ubuntu 18.04 环境中无效):

# cat /proc/self/cgroup|grep "systemd:/docker"| awk -F/ '{print $3}'|cut -c1-12

#. (无结果)

甚至这条命令也毫无成效:

# cat /proc/self/cgroup|grep "systemd:/docker"

#  (无结果)

供参考(来自 docker ps):

CONTAINER ID        IMAGE                           COMMAND                  CREATED             STATUS                  PORTS                               NAMES
63c52bc571b5        local_discourse/socket-only     "/sbin/boot"             28 minutes ago      Up 28 minutes                                               socket-only
631fbabedda9        local_discourse/socket-only2    "/sbin/boot"             26 hours ago        Up 26 hours                                                 socket-only2
123743e12208        mysql/mysql-server              "/entrypoint.sh mysq…"   2 days ago          Up 20 hours (healthy)   33060/tcp, 0.0.0.0:6603->3306/tcp   mysql-man
7a145366268c        registry.unix.com/unix:condor   "/run.sh"                6 days ago          Up 20 hours             3306/tcp, 0.0.0.0:8999->80/tcp      unix
3cc0c90c3e3a        registry:2                      "/entrypoint.sh /etc…"   7 days ago          Up 7 days               0.0.0.0:5000->5000/tcp              hubby
ca7b55fc5a0c        local_discourse/data            "/sbin/boot"             2 weeks ago         Up 8 days                                                   data

这意味着相关信息(指定运行中容器名称的字符串)必须从 yml 文件中的环境变量派生,以确保信息具有平台无关性,并能在多个容器同时运行时正常工作。

例如,我们同时运行多个 Discourse 应用及其他容器,因此使用 docker-cli 命令无法提供我们所需的精确信息(即“当时”通过反向代理配置确定的 Web 上正在运行的容器名称,而非由 Docker 决定)。

我们通过更改反向代理配置中的 Unix 套接字名称(或暴露的容器端口)来选择要显示的容器,从而在不到一秒的时间内实现容器切换且零停机。这意味着容器名称必须(务必)来自 yml 文件中的环境变量,以确保 100% 可靠和准确。

因此,我要求该字符串(容器名称、容器 ID 等)只能从 yml 文件中的环境变量获取。

对于偏好使用容器 ID 的用户,可以将其添加到环境变量中,例如:

DISCOURSE_APP_CONTAINER_NAME = 'socket-only (63c52bc571b5)'

或者:

DISCOURSE_APP_CONTAINER_NAME = '63c52bc571b5'
DISCOURSE_DATA_CONTAINER_NAME = 'ca7b55fc5a0c'

以及按照我最初帖子的方式(我们期望的使用方式):

DISCOURSE_APP_CONTAINER_NAME = 'socket-only'
DISCOURSE_DATA_CONTAINER_NAME = 'data'

具体使用哪种字符串标识符(名称、容器 ID 或两者)将取决于系统管理员(或业务)的需求。

这就是为什么我特别强调,相关信息必须作为环境变量硬编码到主应用 yml 文件中,而不能来自类似 docker ps 的 CLI 命令或其他依赖操作系统(平台)的命令。

希望这能让我的需求更加清晰。

我希望实现平台无关且配置无关,不依赖 CLI 命令或系统命令。我们在服务器上为许多其他应用(包括 Discourse、Docker 化 LAMP 应用、Docker 私有仓库等)运行 Docker,正如上面 docker ps 输出所示。

您完全正确!

您好 @RGJ

仅补充一点后续想法:

在 Docker Swarm 或 Kubernetes(例如)等场景中,将容器标识符(无论是容器 ID、名称还是两者)硬编码为 YAML 环境变量可能会失效。这是因为当容器根据负载和/或故障情况动态调整时,在 YAML 中硬编码环境变量将无法奏效(我如此推测,但尚未亲自实践,因此不敢妄下断言)。不过,我目前愿意先采用“简单方案”(即在 YAML 中使用环境变量)。

无论如何,我尚未在 Swarm 或 Kubernetes 环境中部署 Discourse,因此我的计划是届时再应对该问题 :slight_smile:

我已对此进行了充分思考,因此决定当前最佳方案是将 Discourse 的环境变量硬编码到 YAML 文件(或文件组)中。

将这些环境变量作为站点设置,并在管理员备份页面中显示它们,应该是一项相对简单的任务,如下面我的简易示意图所示: