exec 与 run 的区别
compose exec 在已经运行的容器里执行命令,改配置、连数据库客户端、看进程都靠它;compose run 则新建一个一次性容器跑任务,适合数据库迁移与批处理。一个作用在现有容器上,一个另起容器,混用会攒下一堆临时容器。
基本信息
| exec | docker compose exec db mysql -uroot -p,作用于运行中的容器 |
|---|---|
| run | docker compose run --rm migrate,新建一次性容器 |
| run 特性 | 默认不发布端口、不覆盖重启策略、会先拉起依赖服务 |
| 清理 | run 创建的容器默认保留,任务类操作要加 --rm |
| 选择 | 调试进现有容器用 exec,一次性任务用 run |
| 参数传递 | 两者都可用双横线把参数传给容器内命令 |
exec 与 run 对比
| 维度 | exec | run |
|---|---|---|
| 作用对象 | 已运行的容器 | 新建的一次性容器 |
| 端口发布 | 沿用现有映射 | 默认不发布端口 |
| 依赖服务 | 不处理 | 会先拉起依赖服务 |
| 数据卷 | 使用同一套卷 | 同样使用同一套卷 |
| 典型用途 | 调试、看进程、连客户端 | 迁移、批处理、一次性脚本 |
使用示例
使用示例
docker compose exec web sh # 进运行中的容器
docker compose exec db mysql -uroot -p"$MYSQL_ROOT_PASSWORD" # 连数据库客户端
docker compose run --rm web npm run migrate # 一次性迁移任务
docker compose run --rm --no-deps web npm run seed # 跳过依赖拉起典型使用场景
- 进入运行中的容器排查问题或临时改配置
- 用数据库客户端连上容器里的数据库做查询
- 执行数据库迁移与初始化脚本,跑完即清理
- 跑一次性批处理任务,不污染常驻服务
run 创建的容器与常驻服务共享卷与网络:迁移脚本写错库名同样会毁数据,生产操作前先备份。
run 默认会把依赖服务一并拉起,只想跑单个服务时用 --no-deps,避免意外启动后端组件。
对已经停止的容器用 exec 会报服务未运行,需要先启动服务,或者改用 run 新建容器执行。
两种方式都会沿用服务的镜像与环境变量,区别只在生命周期:exec 依赖目标容器处于运行状态,run 随时可用但每次都新建并启动一套容器。