Docker Compose详解与项目构建
前言
通过之前的文章,我们知道了Docker的安装、镜像操作、容器操作,也初步了解了Dockerfile构建自己的镜像,接下来需要从一个项目的角度考虑如何通过Docker部署了。
我们先考虑一种简单的项目(SpringBoot+MySQL+Redis),这里我们需要部署三个服务
- 基于JDK的SpringBoot服务
- 基于MySQL 5.7.37的服务
- 基于Redis的服务
如果只是通过Docker和Dockerfile我们可以做到
- Dockerfile构建部署基于JDK的SpringBoot服务
- Docker部署基于MySQL 5.7.37的服务
- Docker部署基于Redis的服务
但是这个过程是每个服务都需要单独进行操作,为了应对这种局面,Docker Compose出现了
Docker Compose通过编写yaml配置文件,将这一系列操作集于一身,一次性实现一个项目所有服务的镜像构建和运行。
接下来,我们先学习下Docker Compose的安装、语法、命令,最后进行一下项目实战。
一、Docker Compose安装
在安装Docker Compose之前,请先安装Docker
1、下载
# 这里下载到了/usr/local/bin
curl -L https://get.daocloud.io/docker/compose/releases/download/v2.4.1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
2、授权
chmod +x /usr/local/bin/docker-compose
3、创建软链接
这样就可以在任何目录使用docker-compose命令了
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
4、测试
docker-compose --version
显示版本号则表示安装成功
二、Docker Compose配置文件语法
1、配置文件说明
version: '3.0' # Compose版本
services: # 定义所有的 service 信息, services 下面的第一级别的 key 既是一个 service 的名称
web: # 自定义的一个服务名,名称自己区
build: # 指定包含构建上下文的路径, 或作为一个对象,该对象具有context和指定的dockerfile文件以及args参数值
context: ./web # dockerfile所在路径,如果其他参数默认,可以将其作为build的值
dockerfile: Dockerfile # 指定context目录下Dockerfile文件名称,默认Dockerfile
args: # Dockerfile在build过程中使用的参数,(等同于 docker build --build-arg 的作用)
cache_from: # v3.2中新增的参数, 指定缓存的镜像列表 (等同于 docker build --cache_from 的作用)
labels: # v3.3中新增的参数, 设置镜像的元数据 (等同于 docker build --labels 的作用)
shm_size: # v3.5中新增的参数, 设置容器 /dev/shm 分区的大小 (等同于 docker build --shm-size 的作用)
container_name: my-web # 容器名,(等同于 docker run --name 的作用),不建议指定,自动生成会带(项目名_服务名),防止重复
image: # 指定 docker 镜像, 可以是远程仓库镜像、本地镜像,(等同于 docker build 镜像名:标签名 的作用)
ports: # 端口映射,(等同于 docker run -p 的作用)
- "8000" # 暴露容器的 8000 端口, 宿主机的端口由 docker 随机映射一个没有被占用的端口
- "8001-8010" # 暴露容器的 8001-8010 端口, 宿主机的端口由 docker 随机映射没有被占用的端口
- "5000:5000" # 暴露容器的 5000 端口, 宿主机5000端口映射容器端口
- "9090-9091:8080-8081" # 批量暴露容器端口,指定宿主机多端口与之映射
- "127.0.0.1:8001:8001" # 指定映射宿主机的指定地址的
- "127.0.0.1:5000-5010:5000-5010" # 同上类似
- "6060:6060/udp" # 指定协议,默认tcp协议
command: ["bundle", "exec", "thin", "-p", "3000"] # 覆盖容器启动的默认命令, 支持 shell 格式和 [] 格式
depends_on: # 依赖服务,依赖服务启动之后才会启动
- redis
- mysql
entrypoint: # 覆盖容器的默认 entrypoint 指令 (等同于 docker run --entrypoint 的作用)
- java
- -jar
- demo.jar
env_file: # 从文件加载环境变量
- ./common.env
- ./apps/web.env
- /opt/secrets.env
environment: # 环境变量, environment 的值可以覆盖 env_file 的值 (等同于 docker run --env 的作用)
expose: # 暴露端口, 但不映射宿主机, 同 Dockerfile 的 EXPOSE 指令
- "8000"
- "8001"
network_mode: "bridge" # 网络模式 (等同于 docker run --net 的作用)
networks: # 将容器加入指定网络,
network-name: # 加入下面网络中定义的网络
- aliase-name # 网络别名,容器之间可以通过别名访问
restart: always # 重启策略,no:禁止自动重启,always:无论如何都重启,on-failure:当出现on-failure错, 容器重启
volumes: # 挂在卷,注意:docker-compose目录必须存在,不会自动创建
- /var/lib/mysql # 映射容器内的 /var/lib/mysql 到宿主机的一个随机目录中
- /opt/data:/var/lib/mysql # 映射容器内的 /var/lib/mysql 到宿主机的 /opt/data
- ./cache:/tmp/cache # 映射容器内的 /var/lib/mysql 到宿主机 compose 文件所在的位置
- ~/configs:/etc/configs/:ro # 映射容器宿主机的目录到容器中去, 权限只读
- datavolume:/var/lib/mysql # datavolume 为 volumes 自定义的目录
deploy: # 指定与部署和运行服务相关的配置, 详情待
devices: # 指定设备映射列表 (等同于 docker run --device 的作用)
dns: # 设置 DNS 地址(等同于 docker run --dns 的作用)
dns_search: # 设置 DNS 搜索域(等同于 docker run --dns-search 的作用)
tmpfs: # v2 版本以上, 挂载目录到容器中, 作为容器的临时文件系统(等同于 docker run --tmpfs 的作用)
links: # 链接到其它服务中的容器,可以不用IP访问其他容器, 目前已被用户自定义网络名称空间取代
external_links: # 连接不在 docker-compose.yml 中定义的容器或者不在 compose 管理的容器
extra_hosts: # 添加 host 记录到容器中的 /etc/hosts 中 (等同于 docker run --add-host 的作用)
healthcheck: # v2.1 以上版本, 定义容器健康状态检查, 类似于 Dockerfile 的 HEALTHCHECK 指令
pid: 'host' # 共享宿主机的 进程空间(PID)
logging: # 设置容器日志服务
networks: # 网络定义
network-name: # 网络名称
driver: bridge # 网络模式
volumes: # 数据卷定义
volume-name: # 数据卷名称
2、配置文件理解
Compose配置文件有四个一级属性
# version Compose和Docker兼容性: Compose 文件格式有3个版本,分别为1, 2.x 和 3.x,目前主流的为 3.x 其支持 docker 1.13.0 及其以上的版本 # services 服务,配置文件的核心,有多少服务,则配置多少个服务,如一个项目由SpringBoot、MySQL、Redis组成,则其下配置三个服务 # networks 定义网络,事先定义好在services中需要使用的网络,servcies中用到的网络如果不存在,不会自动创建 # volumes 定义数据卷,事先定义好在services中需要使用的数据卷,servcies中用到的数据卷如果不存在,不会自动创建Services
服务由两种方式创建,一种是build,另一种是镜像。其中大部分命令可以理解为docker run的另一种表现形式,如:
-p -> ports -v -> volumns --network -> networks --name -> container_name -e -> enviroment ...
三、Docker Compose构建命令
1、up
格式:
docker-compose up [options] [SERVICE...]
说明:
重新构建镜像并启动服务
选项:
-d后台运行-f指定compse文件-t多少秒后启动服务
示例:
docker-compose up
docker-compose up -d
docker-compose up -f xxx.yml -d
docker-compose up -d mysql redis
2、ps
格式:
docker-compose ps [options]
说明:
列出所有运行的服务
选项:
-q仅仅显示服务的ID-a显示所有的服务,包含未运行的服务
示例:
docker-compose ps
docker-compose ps -q
3、down
格式:
docker-compose down [options]
说明:
停止服务,会删除容器、网络,不会删除数据卷
选项:
-v指定停止容器时删除的卷-t多少秒后t停止服务
示例:
docker-compose down
4、rm
格式:
docker-compose rm [options] [SERVICE...]
说明:
删除停止状态的的服务
选项:
-v指定停止容器时删除的卷-f强制删除,包括运行中的容器-s在删除前,先停止容器
示例:
docker-compose rm redis
docker-compose rm -f redis
5、run
格式:
docker-compose run [options] [-v VOLUME...] [-p PORT...] [-e KEY=VAL...] [-l KEY=VALUE...] SERVICE [COMMAND] [ARGS...]
说明:
运行一个服务
选项:
- 同docker run
-v-p-d-e-l-w
示例:
docker-compose run -p 3306:3306 -v mysqlData:/var/lib/mysql mysql
6、start
格式:
docker-compose start [SERVICE...]
说明:
启动一个已经存在的容器
选项:
示例:
docker-compose start mysql redis
7、stop
格式:
docker-compose stop [options] [SERVICE...]
说明:
停止已运行的服务的容器
选项:
-t多少秒之后停止服务
示例:
docker-compose stop mysql
docker-compose stop -t 20 mysql
8、restart
格式:
docker-compose restart [options]
说明:
重启容器
选项:
-t多少秒之后停止服务,并启动
示例:
docker-compose restart
docker-compose restart -t 20
7、pause/unpause
格式:
docker-compose pause [SERVICE...]
docker-compose unpause [SERVICE...]
说明:
暂停已运行的服务
恢复服务
选项:
示例:
docker-compose pause mysql
docker-compose unpause mysql
8、kill
格式:
docker-compose kill [options] [SERVICE...]
说明:
杀死指定的服务
选项:
-sSIGNAL to send to the container. (default “SIGKILL”)
示例:
docker-compose kill mysql
9、logs
格式:
docker-compose logs [options] [SERVICE...]
说明:
查看服务日志
选项:
-fFollow log output-t显示时间
示例:
docker-compose logs mysql
docker-compose logs -t mysql
10、port
格式:
docker-compose port [options] [--] SERVICE PORT
说明:
查看服务端口号的映射
选项:
示例:
docker-compose port mysql 3306
11、其他
其他命令暂时略过了
- pull
- push
- scale
- build
- convert
- cp
- …
四、一个简单的项目示例
有过上面的学习之后,接下来用一个简单项目进行实战,还是以之前Docker部署SpringBoot为例子,现在使用Docker Compose进行部署运行
1、项目目录及部署文件准备
└── demo
├── docker-compose.yml
└── sboot
├── demo-0.0.1-SNAPSHOT.jar
└── Dockerfile
- 项目目录:demo,最好是项目名称
- Compose配置文件:docker-compose.yml
- SpringBoot项目构建目录:sboot,里面包含项目包和Dockerfile文件
2、Docker Compose文件编写
version: "3.0"
services:
web:
build: ./sboot
ports:
- 8000:8000
networks:
- demo
restart: always
mysql:
image: mysql:5.7.37
ports:
- 3306:3306
networks:
- demo
environment:
MYSQL_ROOT_PASSWORD: 123456
restart: always
volumes:
- mysql_data:/var/lib/mysql
redis:
image: redis:alpine
ports:
- 6379:6379
networks:
- demo
restart: always
networks:
demo:
volumes:
mysql_data:
3、执行
docker-compose up -d
执行成功后,请求自己的地址,如果能够成功则OK了
4、可能遇到的问题
# 端口占用
服务端端口映射可能被其他容器占用
# 错误:services.mysql.volumes.0 type is required
注意yaml语法,端口映射和数据源映射的值,冒号后面不要由空格,如mysql_data:/var/lib/mysql,不要写成mysql_data: /var/lib/mysql
# 其他语法错误
其他模板语法错误都可能导致构建失败
五、总结
至此,我们已经初步掌握了Docker Compose构建项目的方式了。但是,真实的项目往往比这复杂的多,比如上面的项目示例中可以继续考虑如下问题:
- MySQL
- 第一次MySQL数据初始化问题?
- 后续项目迭代,数据库增量问题?
- 重启数据是否能保留?
- Redis
- 自定义配置文件?
- 重启数据是否能保留?
- SpringBoot项目
- 项目功能迭代,单独更新?
接下来会写一篇针对上面问题的深入优化偏,后续可能会继续往里面追加MQ、文件存储等其他中间件。
感谢大家的阅读,如果有什么建议或者意见可以留下评论哦! ~ 不负热爱 奔赴山海 ~