ZeroTool Workbench

Docker Run 转 Compose

即时将 docker run 命令转换为 docker-compose.yml。支持端口映射、卷挂载、环境变量、网络、重启策略等。

100% 浏览器端运行 数据不离开你的设备 免费 · 无需注册
docker run Command
docker-compose.yml

使用方法

  1. 将 docker run 命令粘贴到左侧面板(或点击示例)。
  2. 点击转换。
  3. 在右侧面板查看生成的 docker-compose.yml。
  4. 点击复制,将内容保存为项目中的 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 rundocker-compose.yml
-p, --publishports:
-v, --volumevolumes:; named volumes also in the top-level volumes:
-e, --env, --env-fileenvironment:, env_file:
--networknetworks: plus a top-level external: true network; host, none, bridge, container:… become network_mode:
--entrypointentrypoint: (one-item list)
-u, -w, -h, --domainnameuser:, working_dir:, hostname:, domainname:
--restart, --pull, --platformrestart:, pull_policy:, platform:
-l, --label, --annotationlabels:, annotations:
--add-host, --dns, --dns-option, --dns-search, --link, --exposeextra_hosts:, dns:, dns_opt:, dns_search:, links:, expose:
--cap-add, --cap-drop, --privileged, --security-opt, --devicecap_add:, cap_drop:, privileged:, security_opt:, devices:
--init, --read-only, -i, -tinit:, read_only:, stdin_open:, tty:
--tmpfs, --volumes-from, --shm-size, --sysctltmpfs:, volumes_from:, shm_size:, sysctls:
--memory, -m, --cpusdeploy.resources.limits
--memory-reservation, --memory-swap, --cpu-shares, --cpuset-cpus, --pids-limitmem_reservation:, memswap_limit:, cpu_shares:, cpuset:, pids_limit:
--pid, --ipc, --uts, --userns, --cgroupns, --stop-signalpid:, ipc:, uts:, userns_mode:, cgroup:, stop_signal:
--nameservice key
-d, --rm, -q, --detach-keysdropped
image and the arguments after itimage: and command: (JSON array)

选项可以写成 --flag value、--flag=value、-p 80:80、-p80:80,也可以合写(-dit、-dp 80:80),与 Docker CLI 相同。

需要手动补的选项

以下选项会被读取但不转换,因为 Compose 字段的结构不同(services 参考):

docker runCompose key
--health-cmd "curl -f http://localhost/" and the other --health-*healthcheck: { test: ["CMD-SHELL", "curl -f http://localhost/"] }
--log-driver, --log-optlogging: { driver: …, options: { … } }
--network-alias api, --ipnetworks: { app-net: { aliases: [api], ipv4_address: … } }
--mountthe long syntax of volumes: (type, source, target)
--gpusdeploy.resources.reservations.devices
--ulimit nofile=1024:2048ulimits: { nofile: { soft: 1024, hard: 2048 } }
--stop-timeout 30stop_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:。以 /、.、~ 开头的是绑定挂载,不声明。