如何用 docker-compose 启动交互式 Shell?

一次性调试用 docker compose run;运行中的服务用 docker compose exec 服务名 sh。若以 shell 为主进程,可配 tty/stdin_open,up -d 后再 attach;up 本身不等于进入交互 shell。

最佳实践
如何用 docker-compose 启动交互式 Shell?封面

两种路径:①容器还没跑——yml 里给服务配 tty: true、stdin_open: true、command: sh,用 up -d 启动后再 attach 连接主进程;一次性调试更适合 compose run --rm;②服务已在跑——docker compose exec 服务名 sh 直接在运行容器里开 shell(更常用)。

方式一:启动即进入 shell

services:
  myservice:
    image: python:3.12
    tty: true          # 分配伪终端(等价 docker run -t)
    stdin_open: true   # 保持标准输入(等价 docker run -i)
    command: sh
docker compose run --rm --no-deps --entrypoint sh myservice
# 或先后台启动,再接入服务主进程
docker compose up -d && docker compose attach myservice

up 主要负责启动与聚合输出,不等于自动连接交互 shell。command 仍受镜像 ENTRYPOINT 影响,必要时像上例显式覆盖。

适合:一次性调试环境、工具容器(装好了 CLI 的镜像,进去敲命令)。

方式二:exec 进运行中的服务(日常首选)

docker compose exec web sh          # 有 bash 用 bash 体验更好
docker compose exec web python manage.py shell   # 直接执行特定命令

服务是长驻进程(Web 服务等)时用这个——不打断主进程,exit 只退你的 shell。

两者对比

up + tty/stdin_open exec
适用 专门的工具/调试容器 运行中的服务容器
主进程 shell 就是主进程 不受影响
退出后 容器停止 容器继续跑

常见报错

  • the input device is not a TTY:在非交互环境可对 compose exec/run 使用 -T;多副本 exec 还应以 --index 指定目标
  • 服务起不来立刻退出:command 是 sh 但忘了配 tty: true + stdin_open: true,sh 没输入源立即退出

常见问题(FAQ)

Q:docker compose run 和 exec 有什么区别?
A:run 新起一个容器,默认不发布服务端口、可能启动依赖,可用 --service-ports/--no-deps 控制;它仍可能共享配置中的卷和外部状态。适合一次性命令(如 docker compose run web python manage.py migrate);exec 进已运行的容器。

Q:attach 和 exec 进 shell 选哪个?
A:exec。attach 接主进程,Ctrl+C 可能将信号传给主进程并停止服务。

Q:容器里没有 sh?
A:distroless 类镜像没 shell,换 debug 变体镜像或拷文件排查。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台