docker compose run 命令(一文讲透)

什么是 Docker Compose?为什么你需要它?

在现代软件开发中,我们经常需要同时运行多个服务,比如前端应用、后端 API、数据库、缓存系统等等。如果每个服务都手动启动、配置环境变量、管理端口映射,那工作量会非常大,而且容易出错。

这时候,Docker Compose 就派上用场了。它是一个工具,允许你用一个 YAML 文件(通常是 docker-compose.yml)来定义多个容器的运行方式,然后通过一条命令启动整个应用栈。

想象一下,你家的厨房里有冰箱、烤箱、微波炉、洗碗机,每个都独立工作,但你要做一顿饭时,需要按顺序打开它们,设置温度、时间,还要注意安全。Docker Compose 就像一个厨房智能控制系统,你只需要按下“开始烹饪”按钮,所有设备就会按预设流程协同工作。

docker compose run 命令,正是这个系统中一个非常灵活的“临时执行”工具。它不启动整个服务栈,而是让你在已有服务的基础上,临时运行一个容器实例,特别适合调试、运行一次性任务。


docker compose run 命令的核心作用

docker compose run 命令最核心的功能是:在不改变服务定义的前提下,临时运行一个容器实例

这个命令的典型场景包括:

  • 在开发环境中运行数据库迁移脚本
  • 执行一次性的数据导入任务
  • 进入某个服务的 shell 环境进行调试
  • 测试某个服务的启动逻辑

它和 docker compose up 的区别在于:up 是启动整个服务栈,而 run 只是“跑一次”某个服务,不会持久化运行。

举个例子,你有一个 Python 后端服务,需要每天凌晨执行一次数据清理脚本。你可以用 docker compose run 在 CI/CD 流程中调用这个脚本,而不需要一直运行整个服务。


基础语法与参数说明

docker compose run 的基础语法如下:

docker compose run [options] SERVICE [COMMAND] [ARGS...]
  • SERVICE:你 docker-compose.yml 中定义的服务名称
  • COMMAND:要运行的命令(可选,默认使用服务定义的 command
  • ARGS:传递给命令的参数(可选)

常用选项说明

选项 说明
-d 后台运行容器(不推荐用于调试)
--rm 容器退出后自动删除(默认行为)
--name 自定义容器名称
--entrypoint 覆盖服务的 entrypoint
--workdir 设置工作目录
--env-file 指定环境变量文件

📌 提示:--rm 是默认行为,意味着容器运行结束后会自动清理,避免占用磁盘空间。


实际案例:使用 docker compose run 运行数据库迁移

我们来创建一个典型的 Web 应用项目结构,包含一个 Flask 后端服务和一个 PostgreSQL 数据库。

1. 创建 docker-compose.yml 文件

version: '3.8'

services:
  web:
    build: .
    ports:
      - "5000:5000"
    depends_on:
      - db
    environment:
      - FLASK_ENV=development
      - DATABASE_URL=postgresql://user:password@db:5432/myapp

  db:
    image: postgres:15
    environment:
      POSTGRES_DB: myapp
      POSTGRES_USER: user
      POSTGRES_PASSWORD: password
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

这个文件定义了两个服务:web(Flask 应用)和 db(PostgreSQL 数据库)。


2. 创建 Flask 应用代码

在项目根目录创建 app.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://user:password@db:5432/myapp'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

db = SQLAlchemy(app)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)

    def __repr__(self):
        return f'<User {self.name}>'

@app.route('/')
def index():
    return "Hello, World! Database is ready."

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

再创建 requirements.txt

Flask==2.3.3
Flask-SQLAlchemy==3.0.5
psycopg2-binary==2.9.7

3. 构建镜像并运行数据库迁移

现在我们想在首次部署时运行数据库迁移。先创建一个 migrate.py 脚本:

from app import db, User

db.create_all()

test_user = User(name="Alice")
db.session.add(test_user)
db.session.commit()

print("✅ 数据库迁移完成,测试用户已创建。")

然后运行 docker compose run 命令执行迁移:

docker compose run --rm web python migrate.py

✅ 解释:

  • --rm:运行结束后自动删除容器
  • web:服务名称,对应 Flask 应用
  • python migrate.py:在容器中运行的命令

这条命令会在 web 服务的容器中执行迁移脚本,不启动整个应用,非常轻量。


高级用法:进入容器调试与执行命令

有时你发现应用启动失败,想进入容器检查日志、查看文件或执行命令。

使用 docker compose run 进入交互式 shell

docker compose run --rm -it web bash
  • -i:保持标准输入打开(交互模式)
  • -t:分配伪终端(TTY)
  • bash:进入 shell 环境

执行后,你会看到类似:

root@abc12345678:/app# ls -la
total 12
drwxr-xr-x 1 root root 4096 Apr  5 10:00 .
drwxr-xr-x 1 root root 4096 Apr  5 10:00 ..
-rw-r--r-- 1 root root  234 Apr  5 10:00 app.py
-rw-r--r-- 1 root root  102 Apr  5 10:00 requirements.txt

现在你可以在容器内执行任意命令,比如:

ping db

printenv

flask run --host=0.0.0.0 --port=5000

⚠️ 注意:--rm 是关键,避免调试后留下未清理的容器。


与 docker-compose up 的对比分析

特性 docker compose run docker compose up
是否启动服务栈 ❌ 否 ✅ 是
是否持久运行 ❌ 仅一次 ✅ 持续运行
是否依赖其他服务 ✅ 可以访问依赖服务 ✅ 启动所有服务
适用场景 调试、一次性任务、脚本执行 开发、测试、生产部署
资源占用

举个比喻:
docker compose up 就像“启动整套厨房系统”,所有设备都运行着;
docker compose run 则像“临时借用烤箱烘一个蛋糕”,用完就关掉。


最佳实践与注意事项

  1. 始终使用 --rm:避免容器堆积,节省磁盘空间。
  2. 使用 --workdir 指定工作目录:避免路径错误。
  3. 避免在 run 中运行长时间任务:如果任务需要长期运行,应考虑用 up 启动服务。
  4. 环境变量优先级--env 参数可以覆盖 docker-compose.yml 中的定义。
  5. 测试脚本时建议先用 --rm + --entrypoint:确保不会影响主服务。

示例:覆盖 entrypoint 执行测试脚本

docker compose run --rm --entrypoint /bin/sh web -c "pytest tests/"

这会临时替换 web 服务的启动命令,运行测试,然后退出。


总结:掌握 docker compose run 命令的三大价值

  1. 灵活执行一次性任务:如数据库迁移、数据导入、脚本测试,无需启动完整服务。
  2. 高效调试工具:进入容器检查文件、网络、权限问题,快速定位 Bug。
  3. 资源友好:自动清理容器,避免资源浪费。

docker compose run 命令虽然看似简单,却是开发流程中不可或缺的一环。它让你在不破坏服务状态的前提下,完成各种“临时操作”,是 DevOps 实践中真正的“瑞士军刀”。

当你在项目中遇到“我想跑个脚本,但不想启动整个应用”时,别忘了这个命令。它能让开发更高效,部署更可控,代码更整洁。

如果你还在手动执行脚本、反复重启服务,那一定是时候把 docker compose run 加入你的工具箱了。