学习参考:尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出)
目录
- 一、核心概念
- 二、主要功能
- 二、docker compose常用命令
- 三、docker compose 案例
- 3.1 自己写一个微服务模块
- 3.2 用Dockerfile将上面的模块编排(不使用compose)
- 3.3 使用compose编排
- 总结
一、核心概念
compose有一个文件,两个要素。
一个文件:
docker-compose.yml
两个要素:服务(service)
,工程(project)
服务(service): 一个个应用容器实例。
工程(project): 由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml
文件中定义。
这里有必要说一下,最新官网是使用叫compose.yaml 或 compose.yml
,为了兼容之前的版本,也同样支持docker-compose.yml
Compose 文件是一个 YAML 文件,定义:
Version 版本(可选)
Services 服务(必填)
Networks 网络
Volumes 卷
Configs 配置
Secrets 保密
以下是官网对Compose文件的相关描述,可以参考:(可以一边使用一边理解)
- 您可以使用片段和扩展来保持 Compose 文件高效且易于维护。
- 可以将多个 Compose 文件合并在一起来定义应用程序模型。 YAML 文件的组合是通过根据您设置的 Compose 文件顺序附加或覆盖 YAML 元素来实现的。 简单的属性和映射会被最高阶的 Compose 文件覆盖,列表会通过附加进行合并。 只要要合并的补充文件托管在其他文件夹中,就会根据第一个 Compose 文件的父文件夹解析相对路径。 由于某些 Compose 文件元素既可以表示为单个字符串也可以表示为复杂对象,因此合并适用于扩展形式。
- 如果您想重用其他 Compose 文件,或者将应用程序模型的某些部分分解为单独的 Compose 文件,您还可以使用 include。 如果您的 Compose 应用程序依赖于由不同团队管理的另一个应用程序,或者需要与其他人共享,这非常有用。
二、主要功能
先看看官网怎么说:
使用Compose本质上就是
三部曲
:
- 使用 Dockerfile 定义应用程序的环境,以便可以在任何地方重现它。
(写Dockerfile)
- 在 docker-compose.yml 中定义组成应用程序的服务,以便它们可以在隔离的环境中一起运行。
(写docker-compose.yml)
- 运行 docker compose up,Docker compose 命令将启动并运行整个应用程序。也可以使用 Compose 独立运行 docker-compose up(docker-compose 二进制文件)。
(运行,docker compose up)
二、docker compose常用命令
Compose V2 版本不用写docke和compose中间的 -
命令 | 含义 |
---|---|
docker-compose -h | 查看帮助 |
docker-compose up | 启动所有docker-compose服务 |
docker-compose up -d | 启动所有docker-compose服务并后台运行 |
docker-compose down | 停止并删除容器、网络、卷、镜像。 |
docker-compose exec yml里面的服务id | 进入容器实例内部 |
docker-compose exec yml文件中写的服务id /bin/bash | 进入容器实例内部 |
docker-compose ps | 展示当前docker-compose编排过的运行的所有容器 |
docker-compose top | 展示当前docker-compose编排过的容器进程 |
docker-compose logs yml里面的服务id | 查看容器输出日志 |
docker-compose config | 检查配置 |
docker-compose config -q | 检查配置,有问题才有输出 |
docker-compose restart | 重启服务 |
docker-compose start | 启动服务 |
docker-compose stop | 停止服务 |
三、docker compose 案例
通过对比不使用compose和使用compose两种情况,看看用了compose到底有什么优势。
3.1 自己写一个微服务模块
实现User增添加和删除,这不是主要的,主要是学docker compose。下面给出我的gitee的源码。嫌费事就拉下来改一改,能跑起来就可以了。源码下载
项目记得改一下
- 自己虚拟机ip地址
- mysql版本(我用的8版本),密码
- redis密码
3.2 用Dockerfile将上面的模块编排(不使用compose)
-
在idea中打包上面的功能模块,放入虚拟机。
-
编写Dockerfile文件(保证和jar包在一个文件夹下!)
- 先创建Dockerfile
- 填入下面内容
# 基础镜像使用java FROM java:8 # 作者 LABEL 'author'='zwcoder' # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名为zwcoder_docker.jar ADD docker_demo-0.0.1-SNAPSHOT.jar zwcoder_docker.jar # 运行jar包 RUN bash -c 'touch /zwcoder_docker.jar' ENTRYPOINT ["java","-jar","/zwcoder_docker.jar"] #暴露6001端口作为微服务 EXPOSE 6001
- 先创建Dockerfile
-
通过Dockerfile构建镜像
docker build -t zwcoder_docker:2.0 . #这有个.别忘了!!!
-
查看新生成的镜像并运行
这里展示不使用compose的情况,很简单,就是把所用到的redis,mysql
容器先运行起来,在运行我们自己的为服务模块就好了。
- 运行
mysql
,并创建表
docker run -p 3306:3306 --name mysql8 --privileged=true -v /zwcoder/mysql/conf:/etc/mysql/conf.d -v /zwcoder/mysql/logs:/logs -v /zwcoder/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql docker exec -it mysql8 /bin/bash #进入容器
mysql -uroot -p #登录mysql create database docker_study; #创建数据库 use docker_study; #应用数据库 #建表 CREATE TABLE `t_user` ( `id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT, `username` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '用户名', `password` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '密码', `sex` TINYINT(4) NOT NULL DEFAULT '0' COMMENT '性别 0=女 1=男 ', `deleted` TINYINT(4) UNSIGNED NOT NULL DEFAULT '0' COMMENT '删除标志,默认0不删除,1删除', `update_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `create_time` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='用户表';
- 运行
redis
docker run -p 6379:6379 --name redis608 --privileged=true -v /zwcoder/myredis/redis.conf:/etc/redis/redis.conf -v /zwcoder/myredis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf docker exec -it redis608 /bin/bash
- 运行微服务模块
docker images docker run -d -p 6001:6001 zwcoder_docker:2.0
这样就成功了! - 运行
从这里就可以看出,不使用compose的时候,需要每次运行一个镜像,还要考虑到镜像启动的顺序问题,当镜像数量增多时,一定会变得非常繁琐!再看看使用compose。
3.3 使用compose编排
- 改一下微服务模块的
yml
文件,不再写死ip,而是使用服务名
再重新打包,上传到虚拟机,并重新构建新的镜像。(先把之前的容器和镜像删除,这些命令不熟悉的可以参考三、Docker命令及基本使用)
- 创建compose文件
Compose v1是用的docker-compose.yml
Compose v2是用的compose.yml
,但是兼容v1
这在上面的内容说了,这里直接使用compose.yml
services: #服务,下面是一个一个容器实例
microService: #我们自己打包的微服务模块
image: zwcoder_docker:3.0 #使用的镜像
container_name: ms01 #容器名
ports: #端口映射
- "6001:6001"
volumes: #容器数据卷
- /zwcoder/microService:/data
networks: #网络,保证容器都运行在一个网段
- atguigu_net #这个网络在最后一行定义了
depends_on: #当前容器实例依赖哪些容器实例
- redis
- mysql
redis:
image: redis:6.0.8
ports:
- "6379:6379"
volumes:
- /zwcoder/myredis/redis.conf:/etc/redis/redis.conf
- /zwcoder/myredis/redis/data:/data
networks:
- atguigu_net
command: redis-server /etc/redis/redis.conf
mysql:
image: mysql
environment:
MYSQL_ROOT_PASSWORD: '123456'
MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
MYSQL_DATABASE: 'docker_study'
MYSQL_USER: 'zwcoder'
MYSQL_PASSWORD: 'zwcoder'
ports:
- "3306:3306"
volumes:
- /zwcoder/mysql/db:/var/lib/mysql
- /zwcoder/mysql/conf/my.cnf:/etc/my.cnf
- /zwcoder/mysql/init:/docker-entrypoint-initdb.d
networks:
- atguigu_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks: #定义网络
atguigu_net:
- 验证compose.yml有没有写错
docker compose config -q
没有输出,就说明没问题! - 使用compose启动
docker compose up -d #后台运行
成功! - 测试
- 进入mysql容器,重新建表(和上面一样)
docker exec -it mysql容器id /bin/bash
- 进入redis容器
docker exec -it redis容器id /bin/bash
- 访问
虚拟机ip:6001/swagger-ui.html
- 测试微服务的方法
- 查看mysql容器表中的数据(mysql操作不在写了),会增加新数据
- 查看redis容器表中的数据
- 进入mysql容器,重新建表(和上面一样)
- 关停compose
docker compose stop
总结
Docker compose 在应对容器不太多,二三十个容器的时候还是挺好的,如果容器数量继续增加,那就要k8s登场了。