有没有办法仅使用 Docker Compose 在容器中启动交互式 shell?我在 docker-compose.yml 中尝试过类似的方法:
myapp:
image: alpine:latest
entrypoint: /bin/sh
当我使用 docker-compose up 启动这个容器时,它会立即退出。是否有任何标志可以添加到 entrypoint
命令或作为 myapp
的附加选项来启动交互式 shell?
我知道有本地 docker 命令选项可以实现这一点,只是好奇是否也可以仅使用 Docker Compose。
/bin/sh
入口点的图像,它应该怎么做?
docker-compose run myapp
呢?
docker-compose run myapp
的问题在于它不会公开端口。所以你必须使用 docker-compose run --service-ports myapp
但它仍然不是很方便。
您需要在 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
。
使用 docker-compose 获取交互式 shell 的规范方法是使用:
docker-compose run --rm myapp
(服务名称 myapp
取自您的示例。更一般地说:它必须是 docker-compose 文件中的现有服务名称,myapp
不仅仅是您选择的命令。示例:bash
而不是 myapp
在这里不起作用。)
您可以设置 stdin_open: true, tty: true
,但是这实际上不会为您提供带有 up
的正确 shell,因为日志是从所有容器流式传输的。
你也可以使用
docker exec -ti <container name> /bin/bash
在正在运行的容器上获取外壳。
--service-ports
--rm
标志,以便删除容器。 @lynx0123 的回答不正确。如果您运行 docker-compose up
,您将不会获得交互式 shell。
docker-compose run
起作用。您还需要将 command: /bin/bash
添加到 docker-compose.yml。
官方入门示例 (https://docs.docker.com/compose/gettingstarted/) 使用以下 docker-compose.yml
:
version: "3.9"
services:
web:
build: .
ports:
- "8000:5000"
redis:
image: "redis:alpine"
使用 docker-compose up
启动此操作后,您可以使用以下命令将外壳放入您的 redis
容器或 web
容器:
docker-compose exec redis sh
docker-compose exec web sh
docker-compose run myapp sh
应该做交易。
up
/run
存在一些混淆,但 docker-compose run
文档有很好的解释:https://docs.docker.com/compose/reference/run
docker-compose run <service-name> sh
来验证服务的环境是否正确。
docker-compose.yml
中配置的 entrypoint
,我必须使用:docker-compose run --entrypoint /bin/bash myapp
如果未来的任何人也在这里徘徊:
docker-compose exec service_name sh
或者
docker-compose exec service_name bash
或者您可以运行单行,例如
docker-compose exec service_name php -v
那是在您已经启动并运行容器之后。
service_name
在您的 docker-compose.yml
文件中定义
docker-compose exec <service_name>
,而不是 docker-compose exec <container_name>
。
使用 docker-compose,我发现最简单的方法是执行 docker ps -a
(在使用 docker-compose up
启动我的容器之后)并获取我想要在其中包含交互式 shell 的容器的 ID(我们称之为 xyz123 )。
那么执行docker exec -ti xyz123 /bin/bash
就很简单了
瞧,一个交互式外壳。
这个问题对我来说很有趣,因为我有问题,当我在执行完成后运行容器时立即退出并用 -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 容器中运行前端(在例子中反应)。
如果 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
我更喜欢
docker-compose exec my_container_name bash
对这个老问题的补充,因为我上次只有这种情况。 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
您可以在命令行上执行 docker-compose exec SERVICE_NAME sh
。 SERVICE_NAME
在您的 docker-compose.yml
中定义。例如,
services:
zookeeper:
image: wurstmeister/zookeeper
ports:
- "2181:2181"
SERVICE_NAME
将是“动物园管理员”。
根据文档-> https://docs.docker.com/compose/reference/run/
您可以使用此docker-compose run --rm app bash
[app] 是您在 docker-compose.yml 中的服务名称
不定期副业成功案例分享
stdin_open
是缺少的链接,它只是为我提供了当我附加到一个已经在运行 shell 的容器时的预期行为。docker-compose run <service_name>
docker exec
获取外壳是行不通的。docker-compose up
和入口点["/bin/sh"]
,这仍然不起作用。虽然容器不会立即存在。输入是否附加到入口点?