资讯详情

如何用 docker compose run 执行一次性命令并用 --service-ports 控制端口暴露?

📅 2026/9/10 18:36:28 | 华诺云谱 👁 阅读
如何用 docker compose run 执行一次性命令并用 --service-ports 控制端口暴露?
如何用 docker compose run 执行一次性命令并用 --service-ports 控制端口暴露【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/composedocker compose run用于对 Compose 文件中的某个服务执行一次性命令它用该服务的配置镜像、卷、依赖等创建一个新容器并在其中执行你在命令行传入的命令。执行完成后一次性容器进入exited状态同时你可以决定是把服务声明的端口暴露到宿主机--service-ports还是只做临时的按需映射--publish或者干脆不暴露任何端口默认行为。本文基于仓库文档 compose run 参考 和仓库自身的 e2e 测试 compose_run_test.go给出一条可以直接照做并验证的操作路径。准备一个声明了端口的服务端口行为只有在服务配置了ports时才有意义。下面这份示例直接取自仓库 e2e 测试的夹具文件 TestComposeRunPorts/compose.yamlservices: back: image: alpine ports: - 8082:80把这份内容保存为你自己目录下的compose.yaml后续命令都在该目录执行。8082:80声明了“宿主机 8082 端口映射到容器 80 端口”这正是后文用--service-ports验证时应当看到的映射。执行一次性命令run的基本形式是run [OPTIONS] SERVICE [COMMAND] [ARGS...]。参考文档给出的例子$ docker compose run web bash它有两个与docker compose up启动服务的本质区别见 docs/reference/compose_run.md命令行传入的COMMAND会覆盖服务配置中定义的command默认不会创建服务配置中声明的任何端口原因文档明确写出是为了避免与宿主机已占用的端口冲突。要观察端口暴露情况容器需要在检查期间保持运行。仓库 e2e 测试使用的做法是-d后台运行并打印容器 ID加一个 30 秒的 sleep 命令$ docker compose run -d back /bin/sh -c sleep 30这条命令执行后一次性容器不暴露back服务声明的8082:80映射对应docker ps中该容器的 PORTS 列为空。几个与本场景直接相关的常用选项完整选项表见 docs/reference/compose_run.md选项用途-d,--detach后台运行容器并打印容器 ID--rm命令结束后自动删除容器即使服务配置了 restart policy--no-deps不启动该服务的依赖/链接服务--name指定容器名称关于依赖如果服务配置了链接依赖服务run会先检查这些服务是否在运行未运行则先启动它们再执行你传入的命令。例如文档中的例子$ docker compose run db psql -h db -U docker若你不想让run启动这些关联容器加上--no-deps$ docker compose run --no-deps web python manage.py shell用 --service-ports 暴露服务声明的端口要让一次性容器按服务配置创建端口并映射到宿主机加上--service-ports短选项-P其文档描述为“Run command with all services ports enabled and mapped to the host”$ docker compose run --service-ports -d back /bin/sh -c sleep 30验证方式来自仓库 e2e 测试 compose_run_test.go 中的TestComposeRunPorts按项目标签过滤容器检查 PORTS 列$ docker ps --filter labelcom.docker.compose.project项目名其中项目名替换为你这个 Compose 项目的实际项目名。e2e 测试对该命令的输出断言是包含8082-80/tcp。也就是说只要你能在输出里看到8082-80/tcp这条映射对应夹具中声明的8082:80就说明--service-ports生效了。用 --publish 只暴露指定端口如果不想暴露服务声明的全部端口可以像docker run一样用--publish/-p做临时映射$ docker compose run --publish 8081:80 -d back /bin/sh -c sleep 30e2e 测试对这条命令的断言是docker ps过滤输出包含8081-80/tcp且不包含8082-80/tcp——即--publish只会创建你显式请求的映射不会把 compose 文件里声明的8082:80带出来。参考文档中还给出了多端口映射的写法$ docker compose run --publish 8080:80 -p 2022:22 -p 127.0.0.1:2021:21 web python manage.py shell注意--service-ports与--publish不能同时使用同时给出时命令直接报错错误信息为--service-ports and --publish are incompatible见 cmd/compose/run.go 中的参数校验。结果验证与容器清理命令结束后可以用下面两点确认运行结果一次性容器状态e2e 测试用OneOffState(back, exited)断言 run 的容器在命令执行完进入exited状态端口映射--service-ports时docker ps应包含文件声明的映射如8082-80/tcp--publish时应只包含你请求的映射。清理方面加--rm可让容器在退出后自动删除文档明确指出它会覆盖服务配置中的 restart policy$ docker compose run --rm web python manage.py db upgrade不加--rm时之前的 run 容器会保留下来e2e 测试描述为“run --rm leaves the earlier one-offs alone and removes its own container”重复执行 run 时可能看到孤儿orphan相关提示设置环境变量COMPOSE_IGNORE_ORPHANSTrue可消除该提示同样出自 compose_run_test.go。限制与报错--service-ports和--publish互斥同时使用会失败二者只能选其一见上文错误信息在脚本中以管道方式给run提供 stdin 时compose 会自动禁用 TTY 分配此时若显式要求 TTY--tty或--no-ttyfalse命令会以退出码 1 失败错误信息为cannot attach stdin to a TTY-enabled container because stdin is not a terminal见 pkg/e2e/compose_run_test.go 的TestComposeRunPipedInput。脚本场景下用-T--no-tty显式关闭伪终端即可端口默认不暴露是run的设计行为而非故障排查“端口没暴露”时先确认是否遗漏了--service-ports或-p。【免费下载链接】composeDefine and run multi-container applications with Docker项目地址: https://gitcode.com/GitHub_Trending/compose/compose创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。