资讯动态

Docker Compose 完整详解

发布时间:2026/10/14 12:10:50 来源:尧图企业网站定制
Docker Compose 完整详解一、什么是 Docker Compose二、核心概念1. service服务定义一个容器模板可以指定镜像、构建规则、环境变量、挂载、端口等。镜像、build 和 image 详解二选一build 和 image 不要同时乱用2. network网络默认自动创建项目网络所有服务默认加入该网络。也支持自定义网络实现服务分组隔离。3. volume数据卷Docker托管的持久化存储容器删除volume里的数据依然保留。4. bind mount绑定挂载常直接叫挂载把宿主机指定目录直接映射到容器内部开发常用。修改宿主机文件容器内文件同步变化。三、docker-compose.yml 完整配置示例四、.env 环境变量文件同目录新建 .env五、常用命令合集V2docker compose 空格版六、适用场景 局限性七、常见踩坑总结参考官方文档链接一、什么是 Docker ComposeDocker Compose是单机下用于定义、管理一组关联 Docker 容器的工具。版本区分Compose V1旧版本独立程序命令docker-compose横杠基于 Python已经停止维护需要单独安装。Compose V2新版作为 Docker CLI 内置插件命令docker compose空格Go语言实现Docker Desktop、新版Docker引擎自带推荐使用。核心作用项目通常由多个服务组成后端、数据库、Redis、MQ等不用反复手动执行docker run创建容器。通过编写 yaml 配置文件一次性描述所有服务、镜像、端口、挂载、网络等信息一条命令完成多容器的创建、启动、停止、删除。核心特点Compose 会自动创建独立项目网络同项目内容器可以直接使用服务名当作主机名互相访问不需要写IP。默认以 yml 文件所在文件夹名称作为项目名容器、网络、数据卷都会带上项目名前缀隔离不同项目资源可以用-p手动指定项目名称。新版规范叫Compose Specification不再强制要求写version字段旧配置里的version: 3.x仅用来兼容旧版Compose。二、核心概念1. service服务定义一个容器模板可以指定镜像、构建规则、环境变量、挂载、端口等。一句话service 不是容器是容器的模板描述。举例子services:web:image:nginxports:80:80这里的web就是一个 service。它只是写在 yml 里的一段配置本身不是正在运行的容器。执行docker compose up的时候docker 读取这个模板根据模板创建出容器。你可以预先配置好镜像、端口、环境变量、挂载规则每次启动都按照这份模板生成容器。补充deploy.replicas副本配置说明services:web:deploy:replicas:3字面含义希望启动3个web实例3个容器。但是deploy下面的replicas是专门给 Docker SwarmDocker集群模式设计的。✅ 如果开启 Docker Swarm 集群写replicas:3会自动创建3个web容器❌ 普通单机执行docker compose up日常开发使用完全不生效只会启动1个容器不会自动创建3个。 常见坑很多新手以为只写一行replicas:3单机compose就能自动生成多个相同容器做不到。单机想跑多个相同容器只能手动写多个 service单机环境如果想要同时跑 2 个 web 容器不能依靠 replicas需要在 services 下手动定义多份服务配置services:web1:image:nginxports:-8081:80web2:image:nginxports:-8082:80web1、web2 两个service配置几乎一样但是服务名称、宿主机端口必须不同端口不能冲突。执行docker compose up -d就会同时启动两个 nginx 容器。本质手动复制serviceCompose没有自动复制扩容的能力。重点区分Swarm / K8s声明replicas:3底层自动创建多个Pod/容器不用手动写多份配置支持集群自动扩缩容Docker Compose单机没有自动创建多个实例的能力yml文件里写多少个service就会创建多少个容器为什么 Compose 不支持 replicas 多实例Compose 的定位单机开发环境工具设计目标是拉起一套完整应用前端后端数据库不是用来做负载均衡、多实例集群。Compose ≠ 容器集群。副本自动调度、扩容是集群的能力。小结replicas 副本配置只在 Docker Swarm 集群生效普通单机docker compose up无效。单机 Compose 想要多个相同容器需要手动编写多个service每个service单独配置端口。Compose 是单机多容器管理工具没有集群自动扩容、副本调度能力。镜像、build 和 image 详解二选一build 和 image 不要同时乱用镜像image只读的应用环境模板用来创建容器。在service配置中通过image指定远程镜像或者build指令本地构建镜像。同一个镜像可以生成多个独立容器。在compose的service里面image和build两个配置二选一image直接拉取已经制作好、存放在镜像仓库Docker Hub的远程镜像build本地读取Dockerfile现场自己构建生成镜像image作用直接使用远程仓库现成镜像不需要本地构建。services:web:image:nginx:1.25含义去 Docker Hub 下载nginx:1.25这个镜像直接拿这个镜像创建容器。镜像别人已经提前做好包含系统、依赖、程序启动速度快不需要编译构建适合直接使用开源现成软件mysql、redis、nginx等注意nginx:1.25冒号后面是镜像标签tag用来区分版本不写tag默认拉latest最新版。build作用根据你本地写好的Dockerfile文件在本机现场打包构建出新镜像。services:web:build:./docker含义./docker代表目录到当前yml同级下的docker文件夹读取里面的Dockerfile执行打包自己生成镜像再用这个镜像启动容器。Dockerfile是镜像构建脚本写清楚怎么打包环境、拷贝代码、安装依赖适合自己项目后端/前端代码需要把自己代码打进镜像每次代码改动重新docker compose build就会重新打包镜像build还可以细写指定Dockerfile文件名、参数services:web:build:context:./dockerdockerfile:Dockerfile.devcontext构建上下文目录构建时能读取文件的目录dockerfile指定构建脚本文件名默认就叫Dockerfile为什么说二选一不要同时乱用❌ 错误写法同时写 build image新手容易踩坑services:web:image:myweb:v1build:./docker虽然可以运行但含义不是“先拉取image镜像再build”意思是build构建镜像并且给构建出来的镜像命名为image的值。日常学习场景建议只写其中一个减少混淆。✅ 两种正确场景场景1直接用现成软件镜像 → 只写imageservices:db:image:mysql:8.0场景2自己项目代码需要本地打包镜像 → 只写buildservices:web:build:./docker配置来源使用场景image远程仓库现成镜像直接下载使用别人做好的软件mysql、nginx、redisbuild本地Dockerfile现场构建镜像打包自己写的业务代码自定义环境命令区分docker compose pull拉取image指定的远程镜像docker compose build执行build本地构建镜像2. network网络默认自动创建项目网络所有服务默认加入该网络。也支持自定义网络实现服务分组隔离。一句话同一个 compose 项目下所有容器默认放进同一个独立网桥网络容器之间可以互通。示例 yml 里有两个服务 web 和 dbcompose 启动时自动新建一个隔离网络把 web 容器、db 容器都加入这个网络。web 容器访问数据库不用填写IP直接写服务名db就可以访问。这个网络是项目专属其他compose项目的容器默认无法接入实现资源隔离。你也可以手动自定义 networkservices:app:networks:-net1db:networks:-net1networks:net1:可以把不同服务分到不同网络例如前端在net1数据库单独放到net2控制访问权限做网络隔离。宿主机和外部网络访问容器需要依靠 ports 端口映射。3. volume数据卷Docker托管的持久化存储容器删除volume里的数据依然保留。volumedocker 自己管理的存储空间不用关心宿主机真实路径。特点由 Docker 管理存放在宿主机Docker内部目录使用者不用关心真实路径删除容器volume不会跟着删除数据永久保存最适合数据库这类需要持久保存数据的场景mysql数据services:db:volumes:-mysql_data:/var/lib/mysqlvolumes:mysql_data:这里mysql_data就是 volume。就算删掉db容器mysql_data卷还存在新建db容器挂载这个卷原有数据还在。docker compose down默认不会删除volume需要加上-v参数才会一并删除数据卷。4. bind mount绑定挂载常直接叫挂载把宿主机指定目录直接映射到容器内部开发常用。修改宿主机文件容器内文件同步变化。bind mount将宿主机真实文件夹直接挂载进容器宿主机与容器共用同一份文件。services:web:volumes:-./src:/app./src yml文件同级的src文件夹宿主机/app 容器内的目录效果在宿主机修改src里的代码容器内/app的文件实时同步更新。开发环境非常方便不用每次改代码都重新构建镜像。缺点依赖宿主机目录Linux环境容易出现文件权限问题。✅ volume vs bind mount 对比重点类型管理者用途volumeDocker 管理生产 / 数据库持久化不关心宿主机文件路径bind mount自己指定宿主机目录本地开发代码实时同步三、docker-compose.yml 完整配置示例services:web:# 构建镜像配置build:context:./docker# 构建上下文目录Dockerfile所在相对路径dockerfile:Dockerfile.dev# 指定Dockerfile文件名# 直接使用远程镜像二选一build 和 image 不要同时乱用# image: nginx:1.25ports:-8080:80# 宿主机端口:容器内部端口environment:-TZAsia/Shanghai# 设置时区env_file:.env# 从外部.env文件读取环境变量存放密码等敏感信息volumes:-./src:/app# bind mount宿主机 ./src 映射到容器 /appdepends_on:-db# 依赖db服务控制容器启动顺序先启动db再启动webrestart:unless-stopped# 重启策略no / always / on-failure / unless-stoppedhealthcheck:test:[CMD,curl,-f,[http://localhost](http://localhost)]interval:10stimeout:5sretries:3start_period:30sdb:image:mysql:8.0environment:MYSQL_ROOT_PASSWORD:${MYSQL_ROOT_PASSWORD}MYSQL_DATABASE:${MYSQL_DATABASE}volumes:-mysql_data:/var/lib/mysql# volume数据卷持久化数据库数据healthcheck:test:[CMD,mysqladmin,ping,-h,localhost]interval:10stimeout:5sretries:3volumes:mysql_data:# 声明数据卷由docker管理持久化存储# 自定义网络可选不写会自动创建默认网络# networks:# default:# driver: bridge⚠️ 重要坑点depends_on只能控制容器启动先后顺序不会等待应用程序就绪。例如 mysql容器进程启动成功但数据库初始化还没完成后端直接连接会报错。解决方案健康检查、业务代码增加等待重试逻辑。四、.env 环境变量文件同目录新建 .env.env文件存放配置、账号密码不要提交到Git代码仓库。MYSQL_ROOT_PASSWORDRoot123456 MYSQL_DATABASEdemo_dbyml中使用${变量名}读取.env中的内容。五、常用命令合集V2docker compose 空格版# 1. 后台启动全部服务dockercompose up-d# 2. 只构建镜像不启动容器dockercompose build# 3. 构建并单独启动指定服务示例只启动dbdockercompose up-ddb# 4. 查看运行中的容器dockercomposeps# 5. 实时查看日志dockercompose logs-f# 查看单个服务日志dockercompose logs-fweb# 6. 重启指定服务dockercompose restart web# 7. 校验并打印解析后的完整配置检查yml语法错误dockercompose config# 8. 进入容器内部终端dockercomposeexecwebbash# 9. 停止服务保留容器、网络、数据卷dockercompose stop# 10. 停止并删除容器、网络默认不删除数据卷volumedockercompose down# 11. down同时删除数据卷谨慎执行数据库数据会清空dockercompose down-v# 12. 拉取image定义的远程镜像不构建、不启动dockercompose pull# 13. 列出本机所有compose项目dockercomposels# 14. 指定自定义yml文件启动dockercompose-fdocker-compose.prod.yml up-d# 15. 多yml叠加基础配置 环境覆盖配置dockercompose-fdocker-compose.yml-fdocker-compose.override.yml up-d自动覆盖机制目录下docker-compose.override.yml会自动和主配置文件合并多用于开发环境覆盖配置不改动主yml。六、适用场景 局限性✅适合场景本地开发环境一键拉起整套微服务依赖单机测试环境快速部署CI自动化测试临时启动数据库、中间件❌不适合场景跨多台服务器集群Compose只管理单台主机容器无法跨机器调度生产大规模高可用集群没有容器故障自动迁移、负载均衡、滚动发布能力复杂编排需求灰度发布、细粒度权限、自动扩缩容等技术对比docker管理单个容器docker compose管理单机一组容器开发、单机测试首选Kubernetes(K8s)多机器集群编排大规模生产主流方案Docker SwarmDocker官方集群方案目前使用较少七、常见踩坑总结depends_on只控制容器启动顺序不等待应用就绪容易出现后端连接数据库失败。docker compose down默认不会删除volumes数据卷旧数据会残留。容器时间不对增加环境变量TZAsia/Shanghai。端口冲突宿主机端口已经被占用修改ports里宿主机端口。Linux宿主机bind mount挂载权限问题宿主机UID/GID和容器内用户ID不匹配。Windows / Mac Docker Desktop大量文件bind mount挂载时IO性能很差。.env 文件不要上传代码仓库防止账号密码泄露。参考官方文档链接Docker Compose 首页 入门教程https://docs.docker.com/compose/Compose File YAML配置参考手册查所有yml字段最重要https://docs.docker.com/reference/compose-file/docker compose 命令行CLI手册https://docs.docker.com/reference/cli/docker/compose/Compose 开放规范https://compose-spec.io/

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑