本文主要是介绍10.Docker Compose容器编排,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
文章目录
- Compose简介
- 安装和卸载步骤
- 核心概念
- compose文件
- 两要素
- 使用步骤
- Compose常用命令
- 微服务测试
- 本地编码
- 打包
- 编写Dockerfile文件
- 构建镜像
- 不使用Compose调试
- 使用Compose调试
- WordPress测试验证增量更新
Compose简介
docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来。但是这样我们又面临以下问题:
如果我需要同时部署好多个服务,那么每个服务需要单独编写Dockerfile文件、构建镜像、构建容器等步骤,非常麻烦。所以docker官方给我们提供了docker-compose多服务部署的工具。
例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器、redis服务器、注册中心eureka、负载均衡容器等。
Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何管理编排的问题。
总结:Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排,可以管理多个Docker容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令就能同时启动/关闭这些容器。
官方网站:https://docs.docker.com/compose/
安装和卸载步骤
一般情况下,安装docker engine时会自带docker compose。docker engine的详细安装可看博客:2.核心概念与安装配置
手动安装compose:https://docs.docker.com/compose/install/
核心概念
compose文件
Compose文件的默认路径是在当前工作目录中的compose.yaml
(推荐)或compose.yml
文件。为早期版本的向后兼容性Compose也支持docker-compose.yaml
和docker-compose.yml
。如果这两个文件都存在,Compose更倾向于使用规范的compose.yaml
。
两要素
-
服务(service)
一个个应用容器实例,比如各种微服务、mysql容器、nginx容器、redis容器等
-
工程(project)
由一组关联的应用容器组成的一个完整业务单元,在docker-compose.yml文件中定义。
使用步骤
- 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
- 使用docker-compose.yml定义一个完整的业务单元,安排好整体应用中的各个容器服务
- 执行
docker compose up
命令启动运行整个应用程序,完成一件部署上线
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 docker-compose.yml文件中写的服务id /bin/bashdocker-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 # 停止服务
微服务测试
本地编码
-
POM文件
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.6</version><!--<version>2.3.10.RELEASE</version>--><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.zyn.docker</groupId><artifactId>docker_boot</artifactId><version>0.0.1-SNAPSHOT</version><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><junit.version>4.12</junit.version><log4j.version>1.2.17</log4j.version><lombok.version>1.16.18</lombok.version><mysql.version>5.1.47</mysql.version><druid.version>1.1.16</druid.version><mapper.version>4.1.5</mapper.version><mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version></properties><dependencies><!--guava Google 开源的 Guava 中自带的布隆过滤器--><dependency><groupId>com.google.guava</groupId><artifactId>guava</artifactId><version>23.0</version></dependency><!-- redisson --><dependency><groupId>org.redisson</groupId><artifactId>redisson</artifactId><version>3.13.4</version></dependency><!--SpringBoot通用依赖模块--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!--swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger2</artifactId><version>2.9.2</version></dependency><dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version></dependency><!--SpringBoot与Redis整合依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!--springCache--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-cache</artifactId></dependency><!--springCache连接池依赖包--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!-- jedis --><dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.1.0</version></dependency><!--Mysql数据库驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47</version></dependency><!--SpringBoot集成druid连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>${druid.version}</version></dependency><!--mybatis和springboot整合--><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.spring.boot.version}</version></dependency><!-- 添加springboot对amqp的支持 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-amqp</artifactId></dependency><dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.10</version></dependency><!--通用基础配置junit/devtools/test/log4j/lombok/hutool--><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.2.3</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>${junit.version}</version></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><scope>runtime</scope><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><optional>true</optional></dependency><!--persistence--><dependency><groupId>javax.persistence</groupId><artifactId>persistence-api</artifactId><version>1.0.2</version></dependency><!--通用Mapper--><dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>${mapper.version}</version></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-resources-plugin</artifactId><version>3.1.0</version></plugin></plugins></build></project>
-
application.yaml
server.port=6001 # ========================alibaba.druid????===================== spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://192.168.10.101:3306/boot_docker?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.druid.test-while-idle=false # ========================redis????===================== spring.redis.database=0 spring.redis.host=192.168.10.101 spring.redis.port=6379 spring.redis.password= spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 # ========================mybatis????=================== mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.wang.docker.entities # ========================swagger===================== spring.swagger2.enabled=true
-
主启动类
package com.wang.docker;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import tk.mybatis.spring.annotation.MapperScan;/*** @ClassName: DockerBootApplication* @Description* @Version 1.0*/ @SpringBootApplication @MapperScan("com.wang.docker.mapper") //import tk.mybatis.spring.annotation.MapperScan; public class DockerBootApplication {public static void main(String[] args) {SpringApplication.run(DockerBootApplication.class,args);} }
业务类如下:
-
config配置类
RedisConfig.java
package com.wang.docker.config;import lombok.extern.slf4j.Slf4j; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer;import java.io.Serializable;/*** @ClassName: RedisConfig* @Description* @Version 1.0*/@Configuration @Slf4j public class RedisConfig {/*** @param lettuceConnectionFactory* @return** redis序列化的工具配置类,下面这个请一定开启配置* 127.0.0.1:6379> keys ** 1) "ord:102" 序列化过* 2) "\xac\xed\x00\x05t\x00\aord:102" 野生,没有序列化过*/@Beanpublic RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory){RedisTemplate<String,Serializable> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(lettuceConnectionFactory);//设置key序列化方式stringredisTemplate.setKeySerializer(new StringRedisSerializer());//设置value的序列化方式jsonredisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.setHashKeySerializer(new StringRedisSerializer());redisTemplate.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());redisTemplate.afterPropertiesSet();return redisTemplate;}}
SwaggerConfig.java
package com.wang.docker.config;import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.service.ApiInfo; import springfox.documentation.spi.DocumentationType; import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.swagger2.annotations.EnableSwagger2;import java.text.SimpleDateFormat; import java.util.Date;/*** @ClassName: SwaggerConfig* @Description* @Version 1.0*/ @Configuration @EnableSwagger2 public class SwaggerConfig {@Value("${spring.swagger2.enabled}")private Boolean enabled;@Beanpublic Docket createRestApi() {return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).enable(enabled).select().apis(RequestHandlerSelectors.basePackage("com.wang.docker")) //你自己的package.paths(PathSelectors.any()).build();}public ApiInfo apiInfo() {return new ApiInfoBuilder().title("aaaa测试"+"\t"+new SimpleDateFormat("yyyy-MM-dd").format(new Date())).description("docker-compose").version("1.0").termsOfServiceUrl("https://www.atguigu.com/").build();}}
-
entity
user.java
package com.wang.docker.entities;import java.io.Serializable; import java.util.Date; import javax.persistence.*;@Table(name = "t_user") public class User implements Serializable {@Id@GeneratedValue(generator = "JDBC")private Integer id;/*** 用户名*/private String username;/*** 密码*/private String password;/*** 性别 0=女 1=男*/private Byte sex;/*** 删除标志,默认0不删除,1删除*/private Byte deleted;/*** 更新时间*/@Column(name = "update_time")private Date updateTime;/*** 创建时间*/@Column(name = "create_time")private Date createTime;/*** @return id*/public Integer getId() {return id;}/*** @param id*/public void setId(Integer id) {this.id = id;}/*** 获取用户名** @return username - 用户名*/public String getUsername() {return username;}/*** 设置用户名** @param username 用户名*/public void setUsername(String username) {this.username = username;}/*** 获取密码** @return password - 密码*/public String getPassword() {return password;}/*** 设置密码** @param password 密码*/public void setPassword(String password) {this.password = password;}/*** 获取性别 0=女 1=男** @return sex - 性别 0=女 1=男*/public Byte getSex() {return sex;}/*** 设置性别 0=女 1=男** @param sex 性别 0=女 1=男*/public void setSex(Byte sex) {this.sex = sex;}/*** 获取删除标志,默认0不删除,1删除** @return deleted - 删除标志,默认0不删除,1删除*/public Byte getDeleted() {return deleted;}/*** 设置删除标志,默认0不删除,1删除** @param deleted 删除标志,默认0不删除,1删除*/public void setDeleted(Byte deleted) {this.deleted = deleted;}/*** 获取更新时间** @return update_time - 更新时间*/public Date getUpdateTime() {return updateTime;}/*** 设置更新时间** @param updateTime 更新时间*/public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}/*** 获取创建时间** @return create_time - 创建时间*/public Date getCreateTime() {return createTime;}/*** 设置创建时间** @param createTime 创建时间*/public void setCreateTime(Date createTime) {this.createTime = createTime;} }
UserDTO.java
package com.wang.docker.entities;import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.io.Serializable; import java.util.Date; /*** @ClassName: UserDTO* @Description* @Version 1.0*/ @AllArgsConstructor @NoArgsConstructor @Data @ApiModel(value = "用户信息") public class UserDTO implements Serializable {@ApiModelProperty(value = "用户ID")private Integer id;@ApiModelProperty(value = "用户名")private String username;@ApiModelProperty(value = "密码")private String password;@ApiModelProperty(value = "性别 0=女 1=男 ")private Byte sex;@ApiModelProperty(value = "删除标志,默认0不删除,1删除")private Byte deleted;@ApiModelProperty(value = "更新时间")private Date updateTime;@ApiModelProperty(value = "创建时间")private Date createTime;/*** @return id*/public Integer getId() {return id;}/*** @param id*/public void setId(Integer id) {this.id = id;}/*** 获取用户名** @return username - 用户名*/public String getUsername() {return username;}/*** 设置用户名** @param username 用户名*/public void setUsername(String username) {this.username = username;}/*** 获取密码** @return password - 密码*/public String getPassword() {return password;}/*** 设置密码** @param password 密码*/public void setPassword(String password) {this.password = password;}/*** 获取性别 0=女 1=男** @return sex - 性别 0=女 1=男*/public Byte getSex() {return sex;}/*** 设置性别 0=女 1=男** @param sex 性别 0=女 1=男*/public void setSex(Byte sex) {this.sex = sex;}/*** 获取删除标志,默认0不删除,1删除** @return deleted - 删除标志,默认0不删除,1删除*/public Byte getDeleted() {return deleted;}/*** 设置删除标志,默认0不删除,1删除** @param deleted 删除标志,默认0不删除,1删除*/public void setDeleted(Byte deleted) {this.deleted = deleted;}/*** 获取更新时间** @return update_time - 更新时间*/public Date getUpdateTime() {return updateTime;}/*** 设置更新时间** @param updateTime 更新时间*/public void setUpdateTime(Date updateTime) {this.updateTime = updateTime;}/*** 获取创建时间** @return create_time - 创建时间*/public Date getCreateTime() {return createTime;}/*** 设置创建时间** @param createTime 创建时间*/public void setCreateTime(Date createTime) {this.createTime = createTime;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", password='" + password + '\'' +", sex=" + sex +'}';} }
-
mapper
UserMapper.java
package com.wang.docker.mapper;import com.wang.docker.entities.User; import tk.mybatis.mapper.common.Mapper;public interface UserMapper extends Mapper<User> { }
src\main\resources路径下新建mapper文件夹并新增
UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.wang.docker.mapper.UserMapper"><resultMap id="BaseResultMap" type="com.wang.docker.entities.User"><!--WARNING - @mbg.generated--><id column="id" jdbcType="INTEGER" property="id" /><result column="username" jdbcType="VARCHAR" property="username" /><result column="password" jdbcType="VARCHAR" property="password" /><result column="sex" jdbcType="TINYINT" property="sex" /><result column="deleted" jdbcType="TINYINT" property="deleted" /><result column="update_time" jdbcType="TIMESTAMP" property="updateTime" /><result column="create_time" jdbcType="TIMESTAMP" property="createTime" /></resultMap> </mapper>
-
service
UserService.java
package com.wang.docker.service;import com.wang.docker.entities.User; import com.wang.docker.mapper.UserMapper; import lombok.extern.slf4j.Slf4j; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @ClassName: UserService* @Description* @Version 1.0*/ @Service @Slf4j public class UserService {public static final String CACHE_KEY_USER = "user:";@Resourceprivate UserMapper userMapper;@Resourceprivate RedisTemplate redisTemplate;/*** addUser* @param user*/public void addUser(User user){//1 先插入mysql并成功int i = userMapper.insertSelective(user);if(i > 0){//2 需要再次查询一下mysql将数据捞回来并okuser = userMapper.selectByPrimaryKey(user.getId());//3 将捞出来的user存进redis,完成新增功能的数据一致性。String key = CACHE_KEY_USER+user.getId();redisTemplate.opsForValue().set(key,user);}}/*** findUserById* @param id* @return*/public User findUserById(Integer id){User user = null;String key = CACHE_KEY_USER+id;//1 先从redis里面查询,如果有直接返回结果,如果没有再去查询mysqluser = (User) redisTemplate.opsForValue().get(key);if(user == null){//2 redis里面无,继续查询mysqluser = userMapper.selectByPrimaryKey(id);if(user == null){//3.1 redis+mysql 都无数据//你具体细化,防止多次穿透,我们规定,记录下导致穿透的这个key回写redisreturn user;}else{//3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率redisTemplate.opsForValue().set(key,user);}}return user;} }
-
controller
UserController.java
package com.wang.docker.controller;import cn.hutool.core.util.IdUtil; import com.wang.docker.entities.User; import com.wang.docker.service.UserService; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import lombok.extern.slf4j.Slf4j; import org.springframework.web.bind.annotation.*;import javax.annotation.Resource; import java.util.Random;/*** @ClassName: UserController* @Description* @Author:我自己* @Date: 2022/8/6 16:16* @Version 1.0*/ @RestController @Api(description = "用户User接口") @Slf4j public class UserController {@Resourceprivate UserService userService;@ApiOperation("数据库新增3条记录")@RequestMapping(value = "/user/add",method = RequestMethod.POST)public void addUser(){for (int i = 1; i <=3; i++) {User user = new User();user.setUsername("wfc"+i);user.setPassword(IdUtil.simpleUUID().substring(0,6));user.setSex((byte) new Random().nextInt(2));userService.addUser(user);}}/* @ApiOperation("删除1条记录")@RequestMapping(value = "/user/delete/{id}",method = RequestMethod.POST)public void deleteUser(@PathVariable Integer id){userService.deleteUser(id);}@ApiOperation("修改1条记录")@RequestMapping(value = "/user/update",method = RequestMethod.POST)public void updateUser(@RequestBody UserDTO userDTO){User user = new User();BeanUtils.copyProperties(userDTO,user);userService.updateUser(user);}*/@ApiOperation("查询1条记录")@RequestMapping(value = "/user/find/{id}",method = RequestMethod.GET)public User findUserById(@PathVariable Integer id){return userService.findUserById(id);}}
打包
maven打包上传至服务器的/mydocker目录下
编写Dockerfile文件
# 基础镜像使用javaFROM java:8# 作者MAINTAINER zzyy# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmpVOLUME /tmp# 将jar包添加到容器中并更名为zzyy_docker.jarADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar# 运行jar包RUN bash -c 'touch /zzyy_docker.jar'ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]#暴露6001端口作为微服务EXPOSE 6001
构建镜像
docker build -t zzyy_docker:1.6 .
不使用Compose调试
-
启动mysql容器
docker run -p 3306:3306 --name mysql57 --privileged=true -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
-
进入容器创建boot_docker数据库
docker exec -it mysql57 /bin/bash mysql -uroot -p123456 create database boot_docker; use boot_docker; 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 /app/redis/redis.conf:/etc/redis/redis.conf -v /app/redis/data:/data -d redis:6.0.8 redis-server /etc/redis/redis.conf
-
本地启动主启动类程序测试
http://localhost:6001/swagger-ui.html#/
执行两个测试接口均正常,可以读写到mysql数据并且redis内数据正常。
-
微服务容器
docker run -d -p 6001:6001 zzyy_docker:1.6
-
访问微服务
http://192.168.10.101:6001/swagger-ui.html#/
swagger页面、接口均正常。
上述过程运行成功。但是存在以下几个问题:
- 先后顺序要求固定,先mysql+redis,后微服务
- 多个run命令需要启动容器
- 容器间的启停或宕机有可能导致IP地址对应容器变化,导致服务异常。可以使用自定义网络通过域名进行解决。
接下来通过使用compose解决上述问题。
使用Compose调试
-
在mycompose目录下创建docker-compose.yml
version: "3"services:microService:image: zzyy_docker:1.7container_name: ms01ports:- "6001:6001"volumes:- /app/microService:/datanetworks: - atguigu_net depends_on: - redis- mysqlredis:image: redis:6.0.8ports:- "6379:6379"volumes:- /app/redis/redis.conf:/etc/redis/redis.conf- /app/redis/data:/datanetworks: - atguigu_netcommand: redis-server /etc/redis/redis.confmysql:image: mysql:5.7environment:MYSQL_ROOT_PASSWORD: '123456'MYSQL_ALLOW_EMPTY_PASSWORD: 'no'MYSQL_DATABASE: 'db2021'MYSQL_USER: 'zzyy'MYSQL_PASSWORD: 'zzyy123'ports:- "3306:3306"volumes:- /app/mysql/db:/var/lib/mysql- /app/mysql/conf/my.cnf:/etc/my.cnf- /app/mysql/init:/docker-entrypoint-initdb.dnetworks:- atguigu_netcommand: --default-authentication-plugin=mysql_native_password #解决外部无法访问networks: atguigu_net:
-
修改docker_boot中application.yaml文件,主要将IP换为服务名称。通过服务名访问,与IP无关。
server.port=6001 # ========================alibaba.druid????===================== spring.datasource.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.driver-class-name=com.mysql.jdbc.Driver #spring.datasource.url=jdbc:mysql://192.168.10.101:3306/boot_docker?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.url=jdbc:mysql://mysql:3306/boot_docker?useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456 spring.datasource.druid.test-while-idle=false # ========================redis????===================== spring.redis.database=0 #spring.redis.host=192.168.10.101 spring.redis.host=redis spring.redis.port=6379 spring.redis.password= spring.redis.lettuce.pool.max-active=8 spring.redis.lettuce.pool.max-wait=-1ms spring.redis.lettuce.pool.max-idle=8 spring.redis.lettuce.pool.min-idle=0 # ========================mybatis????=================== mybatis.mapper-locations=classpath:mapper/*.xml mybatis.type-aliases-package=com.wang.docker.entities # ========================swagger===================== spring.swagger2.enled=true
重新打包上传服务器的mycompose目录
-
在mycompose目录下编写Dockerfile文件
# 基础镜像使用javaFROM java:8# 作者MAINTAINER zzyy# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmpVOLUME /tmp# 将jar包添加到容器中并更名为zzyy_docker.jarADD docker_boot-0.0.1-SNAPSHOT.jar zzyy_docker.jar# 运行jar包RUN bash -c 'touch /zzyy_docker.jar'ENTRYPOINT ["java","-jar","/zzyy_docker.jar"]#暴露6001端口作为微服务EXPOSE 6001
-
构建镜像
docker build -t zzyy_docker:1.7 .
-
通过compose启动各个容器
docker compose up #后台 docker compose up -d
-
进入mysql容器新建数据库和表
docker exec -it 容器实例id /bin/bash mysql -uroot -p create database boot_docker; use boot_docker; 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='用户表';
-
测试通过
-
停止
docker compose stop
WordPress测试验证增量更新
不用compose
#创建网络
docker network create blog#启动mysql
docker run -d -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-v /app/mysql-data:/var/lib/mysql \
-v /app/myconf:/etc/mysql/conf.d \
--restart always --name mysql \
--network blog \
mysql:8.0docker run -d -p 3306:3306 \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=wordpress \
-v mysql-data:/var/lib/mysql \
-v /app/myconf:/etc/mysql/conf.d \
--restart always --name mysql \
--network blog \
mysql:8.0#启动wordpress
docker run -d -p 8080:80 \
-e WORDPRESS_DB_HOST=mysql \
-e WORDPRESS_DB_USER=root \
-e WORDPRESS_DB_PASSWORD=123456 \
-e WORDPRESS_DB_NAME=wordpress \
-v wordpress:/var/www/html \
--restart always --name wordpress-app \
--network blog \
wordpress:latest
使用compose
name: myblog
services:mysql:container_name: mysqlimage: mysql:8.0ports:- "3306:3306"environment:- MYSQL_ROOT_PASSWORD=123456- MYSQL_DATABASE=wordpressvolumes:- mysql-data:/var/lib/mysql- /app/myconf:/etc/mysql/conf.drestart: alwaysnetworks:- blogwordpress:image: wordpressports:- "8080:80"environment:WORDPRESS_DB_HOST: mysqlWORDPRESS_DB_USER: rootWORDPRESS_DB_PASSWORD: 123456WORDPRESS_DB_NAME: wordpressvolumes:- wordpress:/var/www/htmlrestart: alwaysnetworks:- blogdepends_on:- mysqlvolumes:mysql-data:wordpress:networks:blog:
特点:
-
增量更新(修改8080为80重新启动)
- 修改 Docker Compose 文件。重新启动应用。只会触发修改项的重新启动。
-
数据不删
- 默认就算down了容器,所有挂载的卷不会被移除。比较安全
强制删除数据卷:
docker compose -f compose.yaml down --rmi all -v
这篇关于10.Docker Compose容器编排的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!