【问题标题】:How to control docker compose containers from within container?如何从容器内控制 docker compose 容器?
【发布时间】:2022-01-04 22:03:13
【问题描述】:

我有一个 docker compose 文件的最小可重现示例,我希望能够从 docker 容器 (docker-in-docker) 中控制所有 docker compose 服务。

docker-compose.yml 示例:

version: '3'

services:
  redis:
    image: redis

  node:
    image: node

首先我开始:docker compose -f docker-compose.yml up -d

当我在 docker 主机上运行 docker compose ps 时,我得到了正确的输出:

NAME      COMMAND                  SERVICE             STATUS              PORTS
node-1    "docker-entrypoint.s…"   node                exited (0)          
redis-1   "docker-entrypoint.s…"   redis               running             6379/tcp

在绑定了 docker 套接字的容器中运行相同的命令

docker run -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /current_directory/:/tmp/ \
  docker/compose -f /tmp/docker-compose.yml ps

没有列出容器:

Name   Command   State   Ports
------------------------------

我知道 docker/compose 在 docker compose 版本 1.26.2 上运行,但即使使用 docker compose v2.1.1 构建我自己的容器并运行相同的(采用的)命令也会产生一个空列表。我还尝试了 approach described here 设置套接字文件的所有者,但结果与以前相同。

设置有问题吗?如何从容器内控制 docker compose 容器?


Docker 主机信息:

Docker Compose version v2.1.1
Client:
 Cloud integration: v1.0.20
 Version:           20.10.10
 API version:       1.41
 Go version:        go1.16.9
 Git commit:        b485636
 Built:             Mon Oct 25 07:43:15 2021
 OS/Arch:           darwin/amd64
 Context:           default
 Experimental:      true

Server: Docker Engine - Community
 Engine:
  Version:          20.10.10
  API version:      1.41 (minimum version 1.12)
  Go version:       go1.16.9
  Git commit:       e2f740d
  Built:            Mon Oct 25 07:41:30 2021
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.4.11
  GitCommit:        5b46e404f6b9f661a205e28d59c982d3634148f8
 runc:
  Version:          1.0.2
  GitCommit:        v1.0.2-0-g52b36a2
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0

【问题讨论】:

  • 当前目录名为significant to Compose。添加环境变量docker run -e COMPOSE_PROJECT_NAME=$(basename $(pwd)) 有帮助吗?
  • (我不考虑这种 Docker-in-Docker——你没有运行嵌套的 Docker 守护进程——这种方法存在相当大的安全问题;你可能会考虑是否可以实现你的更高级别的目标,无需直接调用 Docker 命令或其 API。)
  • 确实不同的COMPOSE_PROJECT_NAME 环境变量是原因。谢谢@David!

标签: docker docker-compose docker-in-docker


【解决方案1】:

Compose 具有项目名称的概念。 Compose 在它创建的带有项目名称的容器上设置一个标签,并在以后使用它来查找容器。更明显的是,项目名称也是默认容器、网络和卷名称的一部分;如果您 docker network ls 并看到 somename_default,则嵌入了项目名称。

默认项目名称是当前目录的基本名称,但您可以设置COMPOSE_PROJECT_NAME environment variable 来覆盖它。在您的示例中,您正在运行 /tmp/docker-compose.yml,因此默认项目名称为 tmp,但这与您从主机运行的名称不匹配。您可以在启动容器时手动设置此环境变量:

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /current_directory/:/tmp/ \
  -e COMPOSE_PROJECT_NAME=$(basename $(pwd)) \  # <-- add this
  docker/compose -f /tmp/docker-compose.yml ps

同样有一个docker-compose -p 选项,但您需要始终记住在每次调用时都使用它。

docker run --rm -it \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /current_directory/:/tmp/ \
  docker/compose \
  -f /tmp/docker-compose.yml \
  -p $(basename $(pwd)) \       # <-- instead of -e COMPOSE_PROJECT_NAME
  ps

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-13
    • 2021-06-16
    • 1970-01-01
    • 1970-01-01
    • 2021-03-04
    • 2021-12-08
    • 2020-03-23
    相关资源
    最近更新 更多