
目录一、Docker Compose 是什么二、为什么要 Docker Compose三、安装与验证四、docker-compose.yml 文件1. 文件基本结构2. 常见指令详解五、Docker Compose 命令清单六、基本操作七、综合案例一部署自定义服务八、综合案例二部署 WordPress九、常见问题辨析一、Docker Compose 是什么Docker Compose 是 Docker 官方开源项目用Python编写通过调用 Docker 服务 API 进行容器管理及编排用于定义和运行多个 Docker 容器的应用。两个核心概念概念说明service服务一个应用的容器可包含若干运行相同镜像的容器实例project项目由一组关联的应用容器组成的完整业务单元在docker-compose.yml中定义整个 yml 文件定义一个项目Compose 默认管理对象是项目通过子命令对项目中的一组容器进行生命周期管理。生活案例Docker Compose 像一艘航母舰载机、防空导弹等就是一个个容器服务整艘航母就是一个项目。二、为什么要 Docker ComposeDocker 是一个轻量化的应用程序Docker 官方推荐每个 Docker 容器中只运行一个进程。一个应用若涉及 MySQL、nginx 等环境需分别为各组件创建并启动容器每次至少docker run三次繁琐且容器分散独立不便管理。既然都为同一应用服务应放一起管理——这就是 Docker Compose 的意义。三、安装与验证安装 Docker 时默认已安装 docker-compose组件包名为docker-compose-plugin。验证dockercompose version# 输出示例Docker Compose version v2.16.0四·、Docker Compose 的功能使用步骤使用docker-compose.yml 定义构成应用程序的服务这样他们可以在隔离环境中一起运行。最后执行docker compose up命令来启动并运行整个应用程序。核心功能启动、停止和重建服务查看正在运行的服务的状态流式输出运行服务的日志输出在服务上运行一次性命令五、Docker Compose文件(docker-compose.yml )yml 文件的全部指令与字段含义见 Compose 文件规范。1. 文件基本结构关于文件语法版本官方支持 Version 1已废弃、Version 2、Version 3当前最新3.8要求 Docker Engine 不低于 19.03.0。version:3.8# 版本号必须是字符串services:# 服务可存在多个servicename:# 服务名也是内部 bridge 网络的 DNS nameimage:# 必选镜像名command:# 可选覆盖镜像默认 CMDenvironment:# 可选等价 docker run --envvolumes:# 可选等价 docker run -vnetworks:# 可选等价 docker run --networkports:# 可选等价 docker run -pexpose:# 可选暴露容器端口build:# 构建目录depends_on:# 服务依赖配置env_file:# 环境变量文件servicename2:image:volumes:# 可选等价 docker volume createnetworks:# 可选等价 docker network create2. 常见字段语法格式image必选指定运行镜像image:redisimage:redis:5image:library/redisimage:my_private.registry:5000/rediscommand 参数/ entrypoint主程序覆盖启动命令command:bundle exec thin-p 3000# 数组格式command:[bundle,exec,thin,-p,3000]entrypoint:/code/entrypoint.sh#数组格式每个-后面代表一个独立的参数entrypoint:-php--d-zend_extension/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so--d-memory_limit-1-vendor/bin/phpunitenvironment环境变量支持 map 或数组语法布尔值需加引号# map 语法environment:RACK_ENV:developmentSHOW:true# 数组语法environment:-RACK_ENVdevelopment-SHOWtruenetworks指定容器网络可配置别名和 IP配置容器网络services:frontend:image:awesome/webappnetworks:-front-tier-back-tiernetworks:front-tier:back-tier:配置网络驱动和子网services:frontend:networks:front-tier:ipv4_address:172.16.238.10networks:front-tier:ipam:#IP地址管理模块driver:default#驱动config:#网段配置数组 -代表一段子网#一条网段同时包含subnet和gateway所以gateway前面不需要加--subnet:172.16.238.0/24#网段/子网掩码gateway:172.16.238.1volumes挂载数据卷支持短语法和完整语法将主机的数据卷或者文件挂载到容器里# 短语法volumes:-/localhost/data:/var/lib/postgresql/data# 完整语法volumes:-type:volumesource:db-datatarget:/data#volume 仅对命名卷可用的子配置块#默认行为首次挂载命名卷时Docker会把内容内target目录里的文件自动复制到命名卷中。true就是关闭这个自动拷贝。volume:nocopy:true-type:bindsource:/var/run/postgres/postgres.socktarget:/var/run/postgres/postgres.sock 短语法方式全都是bind绑定挂载。这种方式当宿主机目录不存在Docker会自动化创建这个目录。但是如果是完整语法方式则会直接报错。ports端口映射# 短语法ports:-8000:8000-127.0.0.1:8001:8001-6060:6060/udp# 完整语法ports:-target:80#容器内部端口host_ip:127.0.0.1#宿主机上绑定的IP地址默认是0.0.0.0published:8080#宿主机端口protocol:tcp#传输层协议#端口发布模式# host: 宿主机端口房补默认使用宿主机iptables做端口转发# ingress: 用于Swarm集群在集群网络里发布端口多节点负载均衡mode:hostexpose仅仅是类似于一个文档声明不做任何端口转发expose:-3000-8000build构建镜像上下文路径#去 ./dir这个目录拿到Dockerfile(后续章节讲)执行构建生成镜像build:./dir# 或对象形式build:context:./dir#dockerfile文件路径dockerfile:Dockerfile-alternate#指定构建镜像的Dockerfile文件名args:#添加构建参数只在构建过程中有效buildno:1labels:#设置构建镜像的标签用来描述镜像-com.example.descriptionAccounting webappdepends_on设置依赖关系控制启动顺序services:web:build:.depends_on:-db-redisredis:image:redisdb:image:postgresdocker compose up以依赖性顺序启动服务上述示例中先启动 db 和 redis再 启动web。docker compose stop按依赖关系顺序停止与启动的顺序相反上述示例中先停止web再停止db和redis。可指定条件需配合 healthcheckservices:web:image:nginx:1.24.0...depends_on:mysql:condition:service_healthymysql:image:mysql:5.7...healthcheck:test:mysql--userroot--passwordbit123-e SELECT 1;#测试运行正常命令interval:10s#每隔10s执行一次健康检测timeout:5s#检测命令超时时间retries:10#健康检测最多次数 上述示例中加了healthcheck这样web容器会等待mysql通过健康检查确认mysql服务真正可用(health)之后才会启动。env_file从文件添加环境变量env_file:.env# 数组格式env_file:-./common.env-./apps/web.env五、Docker Compose 命令清单完整命令参数见 Compose 命令参考。dockercompose[OPTIONS]COMMAND[ARGS...]# -f, --file 指定模板文件默认 docker-compose.yml# -p, --project-name 指定项目名称默认用目录名命令功能docker compose up构建、创建、启动、链接服务容器-d后台运行生产推荐docker compose down停止所有容器并删除容器和网络-v同时删除卷docker compose build构建服务只构建镜像docker compose create创建服务的容器docker compose start启动已停止的容器不创建新容器docker compose stop停止运行的容器docker compose restart重启服务docker compose run在指定服务容器上执行一次性命令退出后这个临时容器会直接销毁docker compose exec在容器中执行命令docker compose ps列出项目中所有容器docker compose ls显示所有项目docker compose logs显示日志docker compose top显示运行的进程docker compose images列出所有容器使用的镜像docker compose kill强制停止服务的容器docker compose pause/unpause暂停 / 恢复服务docker compose rm删除停止的容器docker compose port列出端口映射docker compose pull/push拉取 / 推送服务镜像docker compose config规范格式显示服务配置docker compose cp本地系统和容器间拷贝文件docker compose events获取实时事件docker compose version查看版本常见命令说明up它会尝试自动完成包括构建镜像、重新创建服务、启动服务并关联服务相关容器的一系列操作可以直接通过该命令来启动一个项目。dockercompose up[options][SERVICE...]参数-d在后台运行服务容器推荐在生产环境下使用该选项--force-recreate强制重新创建容器不能与--no-recreate同时使用--no-recreate如果容器已经存在了则不重新创建不能与--force-recreate同时使用down停止所有容器并删除容器和网络。dockercompose down[options][SERVEICE...]参数-v,--volumes删除容器同时删除目录映射run该命令可以在指定服务容器上执行相关命令。dockercompose run[options]SERVICE[COMMAND][ARGS...]例启动一个ubuntu服务容器并执行ping docker.com命令dockercompose run ubuntupingdocker.com参数-d后台运行容器--name NAME为容器指定一个名字--entrypoint CMD覆盖默认的容器启动命令-e KEYVAL设置环境变量值可多次使用选项来设置多个环境变量-u--user 指定运行容器的用户名或者uid--rm运行命令后自动删除容器-p--publish[]映射容器端口到本地主机psdockercomposeps[options][SERVICE...]参数-a-all显示所有状态容器运行已退出停止-q--quiet仅输出容器ID六、基本操作以下是一个包含 webnginx mysql redis 的基本 compose 项目示例version:3.8services:web:image:nginx:1.24.0environment:TEST:1ports:-8979:80networks:-mytestnetvolumes:-./mynginxhome:/usr/share/nginx/htmldepends_on:mysql:condition:service_healthyredis:condition:service_healthymysql:image:mysql:5.7environment:MYSQL_ROOT_PASSWORD:root123networks:-mytestnetvolumes:-/data/maxhou/mysqldata/varlib/:/var/lib/mysqlhealthcheck:test:mysql--userroot--passwordbit123-e SELECT 1;interval:10stimeout:5sretries:10redis:image:redis:7networks:-mytestnethealthcheck:test:redis-cli pinginterval:10stimeout:5sretries:10networks:mytestnet:操作流程# 1. 创建目录mkdir-p/data/myworkdir/compose/basecd/data/myworkdir/compose/base# 2. 创建 yml 文件将上述的内容输入进去vidocker-compose.yml# 3. 检查配置version 必须是字符串 3.8写数字 3.8 会报错dockercompose config# 4. 创建首页内容mkdir-p./mynginxhomeechoHello World./mynginxhome/index.html# 5. 启动服务后台dockercompose up-d# 6. 停止 / 启动 / 删除dockercompose stopdockercompose startdockercompose down七、综合案例一部署自定义服务架构nginx 反向代理 → C HTTP Web 服务 → MySQL 存储用户信息。目录结构prj16/ ├── docker-compose.yml ├── nginx/ │ └── conf.d/ │ └── bit.conf # nginx 反向代理配置 ├── cppweb/ │ ├── main.cpp # C HTTP 服务源码 │ └── Dockerfile # C 多阶段构建 └── mysql/ ├── varlib/ # MySQL 数据卷 └── init/ └── init.sql # 数据库初始化脚本init.sqldropdatabaseifexiststest;CREATEDATABASEtestDEFAULTCHARACTERSETutf8mb4;usetest;CREATETABLEusers(snoint(11)DEFAULTNULL,snamevarchar(50)DEFAULTNULL)ENGINEInnoDBDEFAULTCHARSETutf8mb4;INSERTINTOusers(sno,sname)VALUES(1,pony),(2,maxhou);C HTTP 服务main.cpp简化版监听 8081 端口返回用户信息页面#includeiostream#includenetinet/in.h#includestring.h#includeassert.h#includeunistd.h#includepthread.husingnamespacestd;void*serverForClient(void*arg);intmain(){structsockaddr_insever_add;memset(sever_add,0,sizeof(sever_add));sever_add.sin_familyPF_INET;sever_add.sin_addr.s_addrhtons(INADDR_ANY);sever_add.sin_porthtons(8081);intoption1;intsocket_fdsocket(AF_INET,SOCK_STREAM,0);assert(socket_fd0);setsockopt(socket_fd,SOL_SOCKET,SO_REUSEADDR,option,sizeof(option));intresbind(socket_fd,(structsockaddr*)sever_add,sizeof(sever_add));assert(res!-1);reslisten(socket_fd,1);assert(res!-1);coutserver initendl;while(1){structsockaddr_inclient;intclient_lensizeof(client);intconn_fdaccept(socket_fd,(structsockaddr*)client,(socklen_t*)client_len);pthread_t pt;pthread_create(pt,NULL,serverForClient,(void*)conn_fd);}return0;}void*serverForClient(void*arg){intconn_fd*(int*)arg;charrequest[1024];recv(conn_fd,request,1024,0);charbuf[520]HTTP/1.1 200 ok\r\nconnection: close\r\n\r\n;send(conn_fd,buf,strlen(buf),0);charbuf2[1024]!DOCTYPE htmlhtmlheadtitleUser Service/title/headbodyh1Users: root/h1/body/html;send(conn_fd,buf2,strlen(buf2),0);close(conn_fd);returnnullptr;}C Dockerfile多阶段构建FROM ubuntu:22.04 as buildstage RUN sed -i s//.*archive.ubuntu.com//mirrors.ustc.edu.cng /etc/apt/sources.list apt update RUN apt install -y build-essential WORKDIR /src COPY ./main.cpp . RUN g main.cpp -o mycppweb -lpthread FROM ubuntu:22.04 COPY --frombuildstage /src/mycppweb / CMD [/mycppweb]nginx 反向代理配置 bit.confserver { listen 80; access_log off; location / { proxy_pass http://mysys:8081; } } 容器内通过服务名访问其他服务DNS 解析如http://mysys:8081、jdbc:mysql://mysql:3306/test。docker-compose.ymlversion:3.8services:web:image:nginx:1.24.0ports:-8112:80networks:-myhellonetvolumes:-./nginx/conf.d:/etc/nginx/conf.ddepends_on:mysys:condition:service_startedmysys:build:context:./cppwebdepends_on:mysql:condition:service_healthynetworks:-myhellonetmysql:image:mysql:5.7environment:MYSQL_ROOT_PASSWORD:rootnetworks:-myhellonetvolumes:-./mysql/varlib/:/var/lib/mysql-./mysql/init/:/docker-entrypoint-initdb.d/# 自动执行 init.sqlhealthcheck:test:mysql--userroot--passwordroot-e SELECT 1;interval:10stimeout:5sretries:10networks:myhellonet:操作步骤# 创建目录和卷目录mkdir-p/data/mytest/mycompose/prj16cd/data/mytest/mycompose/prj16mkdir-p./nginx/conf.d ./cppweb ./mysql/varlib/ ./mysql/init/# 将 bit.conf 放入 ./nginx/conf.d# 将 main.cpp 和 Dockerfile 放入 ./cppweb# 将 init.sql 放入 ./mysql/init# 启动项目dockercompose up-d# 浏览器访问 nginx 端口 8112看到用户信息页面正常返回八、综合案例二部署 WordPressWordPress 是用 PHP MySQL 开发的博客平台/CMS镜像说明见 WordPress 官方镜像。docker-compose.ymlversion:3.8services:db:image:mysql:5.7volumes:-./db_data:/var/lib/mysqlrestart:alwaysenvironment:MYSQL_ROOT_PASSWORD:mywordpressMYSQL_DATABASE:wordpressMYSQL_USER:wordpressMYSQL_PASSWORD:wordpresshealthcheck:test:mysql--userroot--passwordmywordpress-e SELECT 1;interval:10stimeout:5sretries:10wordpress:depends_on:db:condition:service_healthyimage:wordpress:latestports:-8000:80restart:alwaysvolumes:-./wordpress:/var/www/htmlenvironment:WORDPRESS_DB_HOST:db:3306WORDPRESS_DB_USER:wordpressWORDPRESS_DB_PASSWORD:wordpressWORDPRESS_DB_NAME:wordpress操作步骤# 运行站点dockercompose up-d# 访问 http://宿主机:8000配置参数并安装# 登录后台管理# 删除释放空间dockercompose down关键点MySQL 的./mysql/init/:/docker-entrypoint-initdb.d/挂载方式可以让容器首次启动时自动执行 SQL 初始化脚本WordPress 通过WORDPRESS_DB_HOST: db:3306用服务名连接数据库。九、常见问题辨析1. up / run / start 的区别命令说明docker compose up启动或重新启动整个 compose 项目。默认附加模式可看到所有容器日志-d分离模式后台运行docker compose run运行一次性或临时任务只启动该服务及其依赖服务。类似docker run -ti打开交互式终端docker compose start仅重启先前创建但已停止的容器从不创建新容器2. 如何在同一主机上运行 Compose 的多个副本Compose 使用项目名称为所有容器和资源创建唯一标识符。通过-p命令行选项或COMPOSE_PROJECT_NAME环境变量设置自定义项目名称即可运行项目多个副本。3. 可以控制服务启动顺序吗可以。通过depends_on依赖指定并配合healthcheck健康检查用condition: service_healthy确保依赖服务健康后再启动。