如何用 docker-compose 启动交互式 Shell?
两种方式:yml 里配 tty: true + stdin_open: true + command: sh 然后 docker compose up;或对运行中的服务用 docker compose exec 服务名 sh。本文说明适用场景与参数含义。
两种路径:①容器还没跑——yml 里给服务配 tty: true、stdin_open: true、command: sh,docker compose up 启动即进入交互 shell;②服务已在跑——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 up # 前台启动,直接进 shell
# 或后台启动后再接入
docker compose up -d && docker compose attach myservice
适合:一次性调试环境、工具容器(装好了 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:在非交互环境(CI、某些 SSH)里用了 -it/tty,去掉终端参数- 服务起不来立刻退出:command 是 sh 但忘了配
tty: true+stdin_open: true,sh 没输入源立即退出
观测云对照
调试容器也纳入视野。 调试/工具容器跑过什么命令、产生什么输出,经 DataKit 采集后与正式服务日志同平台可查,临时排查也留痕。
常见问题(FAQ)
Q:docker compose run 和 exec 有什么区别?
A:run 新起一个容器跑一次性命令(如 docker compose run web python manage.py migrate);exec 进已运行的容器。
Q:attach 和 exec 进 shell 选哪个?
A:exec。attach 接主进程,误按 Ctrl+C 会停服务。
Q:容器里没有 sh?
A:distroless 类镜像没 shell,换 debug 变体镜像或拷文件排查。