根据传入的 HTTP 请求启动 docker 容器

Abh*_*bey 9 docker docker-compose traefik

我有一台服务器在单独的 docker 容器内运行多个 Web 应用程序。我使用Traefik作为反向代理。因此,每当容器空闲(例如 15 分钟)时,我就会从内部停止容器(结束导致容器停止的正在运行的进程)。如何按需重新启动容器,即当有已停止容器的传入请求时?

正如所问,我没有使用任何集群管理器或类似的东西。基本上,我有一个 API 服务器,它使用docker-py库来创建图像和容器。Traefik 会监听 docker 事件并在创建容器时生成配置,以将 URL 路由到各个容器。

我尝试了 systemd 套接字激活。这是套接字和服务文件。

应用程序套接字

[Unit]
Description=App Socket

[Socket]
ListenStream=3000
Accept=yes

[Install]
WantedBy=sockets.target
Run Code Online (Sandbox Code Playgroud)

应用程序@.service

[Unit]
Description=App Service
Requires=app.socket

[Service]
Type=simple
ExecStart=/usr/bin/npm start --prefix /path/to/dir
StandardInput=socket
StandardError=journal
TimeoutStopSec=5

[Install]
WantedBy=multi-user.target
Run Code Online (Sandbox Code Playgroud)

这是我目前的做法。我的容器正在运行节点应用程序。因此,我结束了容器内的节点进程。在结束节点进程时,我将启用并启动app.socket。当端口 3000 上有传入流量时,我的应用程序将通过套接字激活启动。

但是当我尝试访问该端口时没有任何反应。我已经确认套接字激活正常工作。当我执行命令时date | netcat 127.0.0.1 3000,应用程序似乎启动,然后立即停止,没有任何错误。

也许套接字激活无法按照我的预期工作。启用app.socketinit后,我​​可以看到带有 PID 的进程1正在端口 3000 上运行。一旦流量到达端口 3000,我想在容器内启动我的节点应用程序。但是,如果该端口上已经有进程在运行,应用程序如何在 3000 上启动呢?

也许有某种方法可以使用Traefik来做到这一点,因为它是我正在使用的反向代理。是否有一些功能可以让我在 404 发生时执行命令或脚本?

小智 1

如果您能知道如何管理 docker 容器(k8 或 swarm 或其他任何容器),那将会更有帮助。但根据您的初始输入,我猜您正在寻找 Inetd 或 systemd 套接字激活。这篇文章可能会有所帮助https://www.reddit.com/r/docker/comments/72sdyf/startrun_a_container_when_incoming_traffic/