【问题标题】:Interactive shell using Docker Compose使用 Docker Compose 的交互式 shell
【发布时间】:2016-07-14 23:15:02
【问题描述】:

有没有办法只使用 Docker Compose 在容器中启动交互式 shell?我在 docker-compose.yml 中尝试过这样的事情:

myapp:
  image: alpine:latest
  entrypoint: /bin/sh

当我使用 docker-compose up 启动这个容器时,它会立即退出。是否有任何标志可以添加到entrypoint 命令,或者作为myapp 的附加选项来启动交互式shell?

我知道有本地 docker 命令选项可以实现这一点,只是好奇是否也可以仅使用 Docker Compose。

【问题讨论】:

  • 这不应该工作。例如,如果您的 compose 文件中有多个带有 /bin/sh 入口点的图像,该怎么办?
  • 嗯,为什么不直接启动多个 shell?例如,将 shell 放入 mysql 容器以使用 mysql cli,将 shell 放入备份容器以运行备份命令?
  • docker-compose run myapp 呢?
  • @ibova docker-compose run myapp 的问题在于它不会暴露端口。所以你必须使用docker-compose run --service-ports myapp,但仍然不是很方便。
  • @codentary 这只是 YAML,所以在这种特殊情况下引号是可选的。

标签: shell docker interactive docker-compose


【解决方案1】:

您需要在 docker-compose.yml 中包含以下几行:

version: "3"
services:
  app:
    image: app:1.2.3
    stdin_open: true # docker run -i
    tty: true        # docker run -t

第一个对应docker run中的-i,第二个对应-t

【讨论】:

  • stdin_open 是缺少的链接,用于在我附加到已经运行 shell 的容器之一时为我提供预期的行为。
  • @TheFool,即使我也遇到了同样的问题。最好运行docker-compose run <service_name>
  • 这到底是在哪里添加的?在服务内部?
  • 这似乎是对 OP 问题的最佳答案.. 因为问题是容器会立即退出,否则使用 docker exec 获取外壳是行不通的。跨度>
  • 这在 Windows 上给我一个错误:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
【解决方案2】:

使用 docker-compose 获取交互式 shell 的规范方法是使用:

docker-compose run --rm myapp

(服务名称 myapp 取自您的示例。更一般地说:它必须是 docker-compose 文件中的现有服务名称,myapp 不仅仅是您选择的命令。示例: bash 代替 myapp 在这里不起作用。)

您可以设置stdin_open: true, tty: true,但这实际上不会为您提供带有up 的适当外壳,因为日志是从所有容器流式传输的。

你也可以使用

docker exec -ti <container name> /bin/bash

在正在运行的容器上获取​​ shell。

【讨论】:

  • 请注意,如果您公开任何端口(即用于 Web 服务器),则需要添加 --service-ports
  • 我已更新我的答案以提供更多信息并添加 --rm 标志以便删除容器。 @lynx0123 的回答不正确。如果您运行docker-compose up,您将不会获得交互式shell。
  • 为了使用 Docker for Windows 来实现这一点,我需要 docker-compose v. 1.9.0(参见 Github issuePR)。截至 2016 年 12 月 19 日,这仅随 Windows 的 Docker 测试版一起提供。然后docker-compose run 工作。您还需要将 command: /bin/bash 添加到 docker-compose.yml。
  • 这应该是最佳答案。这就是我来这里时一直在寻找的东西。
  • docker-compose up -d && docker attach
【解决方案3】:

在官方入门示例 (https://docs.docker.com/compose/gettingstarted/) 中使用以下docker-compose.yml

version: '3'
services:
  web:
    build: .
    ports:
     - "5000:5000"
  redis:
    image: "redis:alpine"

使用docker-compose up 开始此操作后,您可以轻松地使用以下命令进入redis 容器或web 容器:

docker-compose exec redis sh
docker-compose exec web sh 

【讨论】:

【解决方案4】:

docker-compose run myapp sh 应该做这笔交易。

up/run 存在一些混淆,但docker-compose run 文档有很好的解释:https://docs.docker.com/compose/reference/run

【讨论】:

  • 非常感谢。只需添加一点以澄清。 docker-compose run [your-service-name-defined-in-docker-compose.yml] [sh 或 bash]。
  • 我认为这是最直接的答案。我需要按照建议通过docker-compose run &lt;service-name&gt; sh 验证服务的环境是否正确。
  • 要覆盖在docker-compose.yml 中配置的entrypoint,我必须使用:docker-compose run --entrypoint /bin/bash myapp
  • 在使用 docker-compose 时,这确实成功了!!
【解决方案5】:

如果未来的任何人也在这里徘徊:

docker-compose exec container_name sh

docker-compose exec container_name bash

或者你可以像这样运行单行

docker-compose exec container_name php -v

这是在您已经启动并运行容器之后

【讨论】:

  • 这是不正确的,它是:docker-compose exec &lt;service_name&gt;,而不是 docker-compose exec &lt;container_name&gt;
  • 为什么用其他图片我做不到,我只是在这里问stackoverflow.com/questions/66638731/…
【解决方案6】:

使用 docker-compose,我发现最简单的方法是执行 docker ps -a(在使用 docker-compose up 启动我的容器之后)并获取我想要在其中包含交互式 shell 的容器的 ID(让我们称之为xyz123)。

那么执行起来就很简单了 docker exec -ti xyz123 /bin/bash

瞧,一个交互式外壳。

【讨论】:

  • 不知道为什么这被否决了 - 这是一个很好的调试方法,以防出现任何问题,我成功地使用了这种方法,例如,在阅读此解决方案的一分钟内。跨度>
  • @ericmjl 因为这是一个两步过程,其中专门询问了有关使用 docker-compose 功能的问题,并且已在其他答案中说明
【解决方案7】:

这个问题对我来说很有趣,因为我有问题,当我在执行完成后运行容器时立即退出并用 -it 修复:

docker run -it -p 3000:3000 -v /app/node_modules -v $(pwd):/app <your_container_id>

当我必须使用 docker compose 自动化时:

version: '3'
services:
    frontend:
        stdin_open: true
        tty: true
        build: 
            context: .
            dockerfile: Dockerfile.dev
        ports: 
            - "3000:3000"
        volumes: 
            - /app/node_modules
            - .:/app

这就是诀窍:stdin_open: true, tty: true

这是一个使用 create-react-app 生成的项目

Dockerfile.dev 看起来是这样的:

FROM node:alpine

WORKDIR '/app'

COPY package.json .
RUN npm install

COPY . . 

CMD ["npm", "run", "start"]

希望这个示例能帮助其他人在 docker 容器中运行前端(示例中的反应)。

【讨论】:

  • 嘿@Carnaru你能告诉我在音量部分下使用“- /app/node_modules”命令的原因
  • @aashirkhan 它与使用卷和让容器使用容器中的 node_modules 而不是本地文件有关
【解决方案8】:

如果yml 被称为docker-compose.yml,则可以使用简单的$ docker-compose up 启动它。一个终端对应的附件可以很简单(考虑yml指定了一个叫myservice的服务):

$ docker-compose exec myservice sh

但是,如果您使用不同的yml 文件名,例如docker-compose-mycompose.yml,则应使用$ docker-compose -f docker-compose-mycompose.yml up 启动它。要附加交互式终端,您还必须指定 yml 文件,就像:

$ docker-compose -f docker-compose-mycompose.yml exec myservice sh

【讨论】:

    【解决方案9】:

    我更喜欢

    docker-compose exec my_container_name bash
    

    【讨论】:

      【解决方案10】:

      对这个老问题的补充,因为我上次只遇到过这种情况。 sh 和 bash 的区别。因此,对于某些 bash 不起作用而只有 sh 起作用的情况可能会发生。

      所以你可以: docker-compose exec CONTAINER_NAME sh

      在大多数情况下:docker-compose exec CONTAINER_NAME bash

      使用。

      如果你有时间。这里很好地解释了 sh 和 bash 之间的区别: https://www.baeldung.com/linux/sh-vs-bash

      【讨论】:

        【解决方案11】:

        您可以在命令行上执行docker-compose exec SERVICE_NAME shSERVICE_NAME 在您的 docker-compose.yml 中定义。例如,

        services:
            zookeeper:
                image: wurstmeister/zookeeper
                ports:
                  - "2181:2181"
        

        SERVICE_NAME 将是“动物园管理员”。

        【讨论】:

          【解决方案12】:

          根据文档 -> https://docs.docker.com/compose/reference/run/

          你可以使用这个docker-compose run --rm app bash

          [app] 是您在 docker-compose.yml 中的服务名称

          【讨论】:

            猜你喜欢
            • 2011-08-13
            • 1970-01-01
            • 2013-03-23
            • 2013-04-16
            • 1970-01-01
            • 1970-01-01
            • 2014-02-12
            • 2017-07-15
            相关资源
            最近更新 更多