docker run 转 docker-compose:参数对照表与那些转不过去的坑

· 约 3 分钟 🐳 docker run ↔ compose

调试时随手敲的一长串 docker run,验证可用后总想固化成 docker-compose.yml——可版本化、可复现、还能编排多个服务。大部分参数能机械对应,但有几类”转不过去”的,得手动处理。这篇把对照表和坑一次讲清。

为什么从 run 迁到 compose

维度docker rundocker-compose
复现命令散落各处,易漏一份 YAML,提交进仓库
版本化跟代码一起 diff/回滚
多服务各起各的、手动连网络一条 up 拉起整套
可读性长命令难读字段结构化、自解释

单容器临时跑用 run 很方便;只要涉及”长期维护”或”多个服务”,就该落到 compose。

常用参数映射对照

docker rundocker-compose
-p 8080:80ports: ["8080:80"]
-v /data:/app:rovolumes: ["/data:/app:ro"]
-e KEY=VALenvironment: ["KEY=VAL"]
--env-file .envenv_file: [.env]
--name webcontainer_name: web
--restart unless-stoppedrestart: unless-stopped
--network mynetnetworks: [mynet]
-w /appworking_dir: /app
-u 1000:1000user: "1000:1000"
--entrypoint /initentrypoint: /init
--health-cmd "curl -f localhost"healthcheck.test
镜像后的参数command:

规整的命令基本能逐项机械转换。

转不过去的几类,要手动处理

这些在 run 和 compose 之间没有一一对应,转换工具会把它们单列在”需注意”里:

  • --rm:run 退出即删容器;compose 不会自动删。一次性任务用 docker compose run --rm,长期服务则需自己管理生命周期。
  • --gpus all:compose 要写成 deploy.resources.reservations.devices,结构完全不同。
  • -P(大写):发布所有暴露端口;compose 没有一键等价写法,得把端口逐个列进 ports
  • --mount:比 -v 结构复杂,要拆成 volumes 的长语法(type/source/target)。
  • --link:已废弃,用 networks 让容器同网互通替代。

反向:compose 转 run 的限制

把 compose 拆回 docker run 时,有两个字段天生转不了:

  • build:docker run 不能构建镜像,只能用 image 占位,提示你先 docker build
  • depends_on::表达启动顺序与健康依赖,run 没有等价物,需你手动先起依赖服务

多服务的 compose 可以为每个服务各生成一条 run,但它们之间的网络、依赖、启动顺序要你自己串——这恰恰说明多服务本就该留在 compose 里。

迁移后检查清单

转换结果大多能直接用,落库前过一眼这几项:

  1. “需注意”里列出的无等价参数,逐条手动补全;
  2. 卷的宿主机路径、网络名是否和目标环境一致;
  3. 重启策略:单机 restart 与编排模式 deploy.restart_policy 不是一回事;
  4. Compose 版本差异:mem_limitdeploy.resources.limits 等字段在不同版本行为略有不同,在目标环境验证一次。

把一行命令变成结构化 YAML 的同时,顺手把这些”转不过去”的点确认掉,迁移就稳了。

❓ 常见问题

为什么要把 docker run 迁成 docker-compose?

一行长命令调试方便,但难复现、难版本化、难协作。compose 把端口、卷、环境变量、网络、重启策略写成 YAML,可以提交进仓库、随项目演进、一条 docker compose up 拉起整套服务。多容器(应用+数据库+缓存)场景更是只能靠 compose 编排,run 命令各起各的既啰嗦又容易漏配。

常用 docker run 参数怎么映射到 compose?

主要的都有对应:-p 8080:80 → ports;-v /data:/app → volumes;-e KEY=VAL → environment;--name → container_name;--restart → restart;--network → networks;-w → working_dir;-u → user;--entrypoint → entrypoint;镜像后面的内容 → command;--health-cmd 等 → healthcheck。规整的命令基本能机械转换。

哪些参数没有直接等价物,要特别注意?

几类典型:--rm(compose 不会自动删容器,需手动管理或用 --rm 跑一次性任务);--gpus(要写成 deploy.resources.reservations.devices);-P 大写(发布所有暴露端口,compose 没有等价的一键写法,需逐个列出);--mount(结构比 -v 复杂,要拆成 volumes 的长语法);--link(已废弃,用 networks 替代)。转换工具会把这些列在"需注意"里提醒你手动确认。

compose 转回 docker run 有什么限制?

docker run 不能构建镜像,所以遇到 build: 字段只能用 image 占位、提示你先 build;depends_on 表达的是启动顺序与健康依赖,run 没有等价物,需你手动保证先起依赖服务;多服务的网络互通也要自己用 --network 串起来。其余字段尽量逐项还原成 run 参数。

多服务的 compose 能一次性转成 run 吗?

能转,但要清醒:工具会为 services 下每个服务各生成一条独立的 docker run,但它们之间的网络、依赖、启动顺序不会自动处理。你需要先 docker network create 一个网络、按依赖顺序逐个 run、并用 --network 接到同一网络。这也正说明多服务场景本就更适合留在 compose。

--restart 和 compose 的重启策略一样吗?

基本一致:no、on-failure、always、unless-stopped 四种取值在 docker run 的 --restart 和 compose 的 restart 字段里通用。但在 Swarm/部署模式下,重启行为由 deploy.restart_policy 接管,和单机 restart 字段不是一回事,迁移到编排环境时要注意区分。

转换结果可以直接复制执行/落库吗?

大多数常见场景可以,但建议过一眼两处:一是"需注意"里列出的无等价参数,二是核对卷的宿主机路径、网络名等与你的环境是否一致。另外不同 Compose 版本对某些字段(如 mem_limit 与 deploy.resources.limits)的处理略有差异,落库前最好在目标环境验证一次。

🐳 打开 docker run ↔ compose docker run 命令与 docker-compose.yml 双向互转·端口/卷/环境变量/网络/健康检查·本地运行