使用Docker Compose的交互式Shell


271

有什么方法可以仅使用Docker Compose在容器中启动交互式shell?我已经在docker-compose.yml中尝试过类似的操作:

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

当我使用docker-compose up启动此容器时,它立即退出。我可以添加到entrypoint命令或myapp的附加选项作为交互式shell启动吗?

我知道有本地的docker命令选项可以实现此目的,只是想知道是否也可以仅使用Docker Compose。


这不应该工作。例如,如果您/bin/sh在撰写文件中有多个带有入口点的图像,该怎么办?
熊炳进

2
嗯,为什么不只启动多个shell?例如,将一个外壳放入mysql容器以与mysql cli一起使用,将一个外壳放入一个备份容器以运行备份命令?
drubb

1
那又如何docker-compose run myapp呢?
伊沃巴州

1
@ibova的问题是docker-compose run myapp它不会公开端口。因此,您必须使用它,docker-compose run --service-ports myapp但仍然不是很方便。
愚人节

entrypoint: /bin/sh应该是entrypoint: "/bin/sh"
codentary

Answers:


341

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

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

第一个对应于-idocker run,第二个对应于中-t


3
stdin_open是缺少的链接,用于在我附加到已经运行外壳程序的一个容器时,仅向我提供预期的行为。
Charney Kaye

9
@TheFool,即使我也遇到同样的问题。最好运行docker-compose run <service_name>
Aswath K,

4
究竟在哪里添加?里面的服务?
问题人员

这似乎是OP问题的最佳答案。因为问题在于容器会立即退出,因此在其上使用shell docker exec不会起作用。
RoyM

这在Windows上给了我一个错误:colorama\win32.py, line 152, in SetConsoleTitle: ctypes.ArgumentError: ‘ValueError’: embedded null character
cowlinator

210

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

您可以设置stdin_open: true, tty: true,但是实际上并不能为您提供合适的外壳up,因为正在从所有容器中流式传输日志。

您也可以使用

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

在正在运行的容器上安装外壳。


16
请注意,--service-ports如果您公开任何端口(例如,用于Web服务器),则需要添加
epelc

9
我已经更新了答案,以提供更多信息并添加--rm标志,以便删除容器。@ lynx0123的答案不正确。如果运行,将不会获得交互式Shell docker-compose up
dnephin

2
为了使其能够在Windows上使用Docker,我需要docker-compose v。1.9.0(请参阅Github 问题PR)。从16/19/16起,此功能仅与Windows版Docker的beta版本一起提供。然后docker-compose run工作。您还将想要添加command: /bin/bash到docker-compose.yml。
Joseph238 '16

5
这应该是最佳答案。这就是我来这里时要寻找的东西。
mkasberg

8
docker-compose up -d && docker attach <container_name>
Aaron McMillin

58

在官方的入门示例(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 


23

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

然后,执行起来很简单 docker exec -ti xyz123 /bin/bash

瞧,交互式外壳。


1
不知道为什么不赞成这样做-这是在发生任何错误时进行调试的好方法,并且在阅读此解决方案的一分钟之内,我就成功地使用了该方法。
ericmjl

4
@ericmjl因为这是一个两步过程,所以该问题专门询问了有关使用docker-compose功能的问题,并且在其他答案中已经提到过
OneCricketeer

19

如果将来有人在这里徘徊:

docker-compose exec container_name sh

要么

docker-compose exec container_name bash

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

docker-compose exec container_name php -v

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


2

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

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

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


2

这个问题对我来说非常有趣,因为我遇到了问题,当我在执行完成后运行容器时立即退出,并使用-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容器中运行一个前端(在例子中反应)。


0

如果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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.