ZeroTool Workbench
Docker Run 转 Compose
即时将 docker run 命令转换为 docker-compose.yml。支持端口映射、卷挂载、环境变量、网络、重启策略等。
使用方法
- 将 docker run 命令粘贴到左侧面板(或点击示例)。
- 点击转换。
- 在右侧面板查看生成的 docker-compose.yml。
- 点击复制,将内容保存为项目中的
docker-compose.yml。
常见使用场景
- 迁移:将一次性 docker run 命令转换为可复现的 compose 配置。
- 文档化:将 README 或文档中的 run 命令转换为 compose 格式供团队使用。
- 多服务部署:分别生成各服务块,合并为完整的 compose 文件。
- CI/CD:用声明式 compose 文件替代脆弱的 docker run shell 脚本。
示例:PostgreSQL 容器
输入:
docker run -d \
--name postgres \
-e POSTGRES_DB=myapp \
-e POSTGRES_USER=admin \
-e POSTGRES_PASSWORD=secret \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql/data \
--restart unless-stopped \
postgres:16-alpine
输出:
services:
postgres:
image: "postgres:16-alpine"
ports:
- "5432:5432"
volumes:
- "pgdata:/var/lib/postgresql/data"
environment:
- "POSTGRES_DB=myapp"
- "POSTGRES_USER=admin"
- "POSTGRES_PASSWORD=secret"
restart: unless-stopped
volumes:
pgdata:
pgdata 是具名卷,所以写进顶层 volumes:。少了这一段 Compose 会拒绝文件:docker compose config 报 service "postgres" refers to undefined volume pgdata。-d 被省略,后台运行用 docker compose up -d。--name 成为服务名;脚本依赖确切容器名时请自行加 container_name:。
示例:端口、资源限制与已有网络
docker run --rm -it --network app-net -p 127.0.0.1:8080:80/tcp \
--restart on-failure:3 --memory 512m --cpus 1.5 --cap-add NET_ADMIN \
ghcr.io/acme/web:1.2 npm start
services:
acme_web:
image: "ghcr.io/acme/web:1.2"
ports:
- "127.0.0.1:8080:80/tcp"
networks:
- app-net
restart: "on-failure:3"
cap_add:
- NET_ADMIN
stdin_open: true
tty: true
deploy:
resources:
limits:
memory: 512m
cpus: "1.5"
command: ["npm", "start"]
networks:
app-net:
external: true
没有 --name 时服务名取自镜像(ghcr.io/acme/web:1.2 → acme_web)。-it 是短选项 -i 与 -t 的组合,分别转为 stdin_open 与 tty;--rm 被省略。--network 转为外部网络,须事先存在(docker network create app-net)。--network host、none、bridge、container:名称 则转为 network_mode:。
示例:没有对应 Compose 字段的选项
docker run -d --name web --env-file .env --entrypoint /bin/sh -u 1000:1000 -w /app --gpus all nginx:1.27 -c "nginx -g 'daemon off;'"
# Not converted: --gpus all
services:
web:
image: "nginx:1.27"
entrypoint: ["/bin/sh"]
env_file:
- .env
user: "1000:1000"
working_dir: /app
command: ["-c", "nginx -g 'daemon off;'"]
docker run 的 --entrypoint 只接受一个可执行文件,所以转为只有一项的列表;镜像之后的参数是 command。--gpus 没有单一的 Compose 字段(GPU 写在 deploy.resources.reservations.devices),转换器读取它的值、保证镜像名正确,并在第一行注释与状态栏列出。
以上输出都通过 docker compose config(Docker Compose 5.1);工具的测试会对每个示例运行这项检查。
参数对照
| docker run | docker-compose.yml |
|---|---|
-p, --publish | ports: |
-v, --volume | volumes:; named volumes also in the top-level volumes: |
-e, --env, --env-file | environment:, env_file: |
--network | networks: plus a top-level external: true network; host, none, bridge, container:… become network_mode: |
--entrypoint | entrypoint: (one-item list) |
-u, -w, -h, --domainname | user:, working_dir:, hostname:, domainname: |
--restart, --pull, --platform | restart:, pull_policy:, platform: |
-l, --label, --annotation | labels:, annotations: |
--add-host, --dns, --dns-option, --dns-search, --link, --expose | extra_hosts:, dns:, dns_opt:, dns_search:, links:, expose: |
--cap-add, --cap-drop, --privileged, --security-opt, --device | cap_add:, cap_drop:, privileged:, security_opt:, devices: |
--init, --read-only, -i, -t | init:, read_only:, stdin_open:, tty: |
--tmpfs, --volumes-from, --shm-size, --sysctl | tmpfs:, volumes_from:, shm_size:, sysctls: |
--memory, -m, --cpus | deploy.resources.limits |
--memory-reservation, --memory-swap, --cpu-shares, --cpuset-cpus, --pids-limit | mem_reservation:, memswap_limit:, cpu_shares:, cpuset:, pids_limit: |
--pid, --ipc, --uts, --userns, --cgroupns, --stop-signal | pid:, ipc:, uts:, userns_mode:, cgroup:, stop_signal: |
--name | service key |
-d, --rm, -q, --detach-keys | dropped |
| image and the arguments after it | image: and command: (JSON array) |
选项可以写成 --flag value、--flag=value、-p 80:80、-p80:80,也可以合写(-dit、-dp 80:80),与 Docker CLI 相同。
需要手动补的选项
以下选项会被读取但不转换,因为 Compose 字段的结构不同(services 参考):
| docker run | Compose key |
|---|---|
--health-cmd "curl -f http://localhost/" and the other --health-* | healthcheck: { test: ["CMD-SHELL", "curl -f http://localhost/"] } |
--log-driver, --log-opt | logging: { driver: …, options: { … } } |
--network-alias api, --ip | networks: { app-net: { aliases: [api], ipv4_address: … } } |
--mount | the long syntax of volumes: (type, source, target) |
--gpus | deploy.resources.reservations.devices |
--ulimit nofile=1024:2048 | ulimits: { nofile: { soft: 1024, hard: 2048 } } |
--stop-timeout 30 | stop_grace_period: 30s |
限制
- 每次转换一条
docker run命令。多个容器请分别转换,再把服务块合并到同一个services:下。 - 识别
docker run与docker container run,不识别podman run。 $(...)、$VAR、&&等 shell 语法按原文保留。请先展开变量,或在结果里使用 Compose 的变量插值。./data这类相对绑定路径,在 Compose 里相对 compose 文件所在目录,在docker run里相对当前目录。
FAQ
支持哪些 docker run 参数?
读取 docker run 接受的全部选项(Docker CLI 29.4)。其中约 60 个有对应的 Compose 字段,会被转换:ports、volumes、environment、env_file、entrypoint、user、working_dir、networks、restart、labels、extra_hosts、cap_add、devices、tmpfs 等,见下方对照表。其余列为未转换。
生成的 Compose 文件版本是什么?
不写 version 字段。Compose 规范把顶层 version 视为过时字段,Docker Compose v2 遇到它只会打印警告。
服务名称如何确定?
如果 docker run 命令中使用了 --name,则以该值作为服务名(不会写 container_name)。否则,服务名从镜像名称派生:去除 registry 前缀和 tag,将斜杠替换为下划线。
支持多行 docker run 命令吗?
支持。粘贴使用反斜杠换行的命令,转换器会正确处理。
没有对应 Compose 字段的选项怎么处理?
照样读取它的值,镜像名不会被读错。这些选项列在状态栏和文件第一行的注释里(如 # Not converted: --gpus all),可据此手动补 Compose 设置。docker run 不认识的选项会报错,与 docker run 一致。
会声明具名卷吗?
会。-v 的来源是名字时(如 pgdata:/var/lib/postgresql/data),写入顶层 volumes:。以 /、.、~ 开头的是绑定挂载,不声明。