docker run 转 docker-compose 完全指南:为什么转、怎么转、参数对照表
为什么值得把 docker run 迁到 compose
一条 docker run -d --name web -p 8080:80 -v ... 跑起来的服务,本质是配置只存在于你敲过的命令和记忆里。换台机器、半年后重建、同事接手,都得靠翻 shell history 还原。compose 把这一切变成一个可版本管理的 YAML 文件:
| 裸 docker run | docker compose |
|---|---|
| 配置在 shell history 里 | 配置在 docker-compose.yml 里,进 git |
| 多容器要手写依赖顺序 | depends_on 声明依赖 |
| 重建 = 删旧容器再拼长命令 | docker compose up -d 幂等 |
| 停一半的服务靠记忆清理 | docker compose down 一次清干净 |
| 端口/卷散落各处 | 一个文件看全貌 |
三十秒完成转换
直接把 docker run 命令粘进 docker run 转 compose 在线转换器,得到 compose 文件后保存运行:
docker compose up -d
转换全程在你的浏览器本地完成——包含密码、内网地址的命令不会发到任何服务器。
参数逐项对照表
| docker run | docker-compose.yml | 说明 |
|---|---|---|
| nginx:1.25 | image: nginx:1.25 | 镜像 |
| --name web | container_name: web(或省略用 service 名) | 建议省略,让 compose 用 service 名管理 |
| -p 8080:80 | ports: ["8080:80"] | 端口映射,注意 YAML 里要加引号 |
| -v ./site:/usr/share/nginx/html | volumes: ["./site:/usr/share/nginx/html"] | 绑定挂载 |
| -v cache:/var/cache | volumes: ["cache:/var/cache"] | 具名卷(还要在顶层 volumes 声明) |
| -e TZ=Asia/Shanghai | environment: ["TZ=Asia/Shanghai"] | 环境变量 |
| --env-file .env | env_file: [.env] | 环境变量文件 |
| --restart always | restart: always | 重启策略 |
| --network mynet | networks: [mynet] + 顶层声明 | 网络 |
| --network host | network_mode: host | 特殊网络用 network_mode |
| -u 1000:1000 | user: "1000:1000" | 运行用户 |
| -w /app | working_dir: /app | 工作目录 |
| --entrypoint "sh -c ..." | entrypoint: ... | 入口点 |
| -m 512m | mem_limit: 512m | 内存限制 |
| --cpus 1.5 | cpus: "1.5" | CPU 限制 |
| 镜像后的命令 | command: ... | 容器命令 |
转换时的三个经典坑
1. 裸 -e 透传没法转
docker run -e DEBUG nginx # 引用宿主机的 DEBUG 变量
compose 文件是静态的,表达不了「引用宿主机变量」。改写成完整形式 -e DEBUG=value,或统一走 env_file。
2. 匿名卷没有等价物
docker run -v /var/log nginx(只有容器路径)创建的是匿名卷,compose 需要具名卷或绑定路径。转换器会把它列进警告区——给它起个名字(logdata:/var/log)并在顶层声明 volumes。
3. --rm 的语义变了
裸 run 的 --rm 是「退出即删容器」;compose 的生命周期由 down 管理,不需要也不支持 --rm。这不是丢失功能,是模型不同。
多容器场景:转换后顺手做依赖编排
把每条 docker run 各转成一个 service 后,加依赖关系:
services:
app:
image: myapp:2.0
depends_on:
db:
condition: service_healthy
db:
image: postgres:16
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 5s
retries: 10
service_healthy 条件(compose v2.20+ 支持)解决「数据库没就绪应用先启动」的经典时序问题——这是裸 run 时代只能靠 sleep 脚本解决的痛点。
常见问题
Q:转出来的文件需要 version 字段吗? 不需要。现代 docker compose(v2 CLI)中 version 已废弃,写了反而有 warning。转换器输出的就是无 version 的现代格式。
Q:compose 文件名必须是 docker-compose.yml 吗?
默认识别 compose.yaml / docker-compose.yml;用 -f 可以指定任意文件:docker compose -f prod.yml up -d。
Q:已有容器在跑,直接 up 会冲突吗?
会——同名容器冲突(container name already in use,排查见这篇)。先 docker stop/rm 旧容器,或给 service 换名过渡。端口占用冲突的处理见端口占用排查。
本文由 ToolVault 工具匣 提供。相关工具:docker run 转 compose 转换器、Dockerfile 生成器、Linux 命令速查。相关阅读:容器名冲突排查、端口占用排查。访问 首页 查看更多开发者工具。
相关工具
相关文章
Permission denied (publickey) 怎么解决?Git 推送失败的 6 种原因与修复
git clone/push 报 Permission denied (publickey) fatal: Could not read from remote repository?覆盖公钥没生成、没加载进 agent、没添加到 GitHub/Gitee、多账号配错密钥、deploy key 权限、remote URL 写错六种根因,附 ssh -v 诊断方法。
npm ERR! ERESOLVE:peer dependency 冲突的四种解决策略
npm install 报 ERESOLVE unable to resolve dependency tree 怎么办?理解 peer dependency 的设计意图,掌握四种解决策略(版本修复 / legacy-peer-deps / overrides / dedupe)及其适用场景与风险。
error:0308010C digital envelope routines::unsupported 怎么解决?Node 17+ 跑老项目的三种修法
Node 17+ 启动 webpack 4 老项目报 error:0308010C:digital envelope routines::unsupported?根因是 OpenSSL 3.0 移除了 MD4 哈希。本文给出 --openssl-legacy-provider 临时方案、升级 webpack 5 根治方案和锁定 Node 16 的取舍。