当前位置:   article > 正文

【云原生 • Docker】Docker进阶_库存管理 docker

库存管理 docker

一、Docker-compose容器编排

1.1 是什么?

Docker-Compose是Docker官方的开源项目, 负责实现对Docker容器集群的快速编排。

Compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。你需要定义一个 YAML 格式的配置文件docker-compose.yml,写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。

使用前面介绍的Dockerfile我们很容易定义一个单独的应用容器。然而在日常开发工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器;再比如在分布式应用一般包含若干个服务,每个服务一般都会部署多个实例。如果每个服务都要手动启停,那么效率之低、维护量之大可想而知。这时候就需要一个工具能够管理一组相关联的的应用容器,这就是Docker Compose。

Compose有2个重要的概念:

  1. 项目(Project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
  2. 服务(Service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。

docker compose运行目录下的所有yml文件组成一个工程,一个工程包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务可包括多个容器实例。

docker-compose就是docker容器的编排工具,主要就是解决相互有依赖关系的多个容器的管理

1.2 能干嘛?

docker建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将每个服务单独的分割开来但是这样我们又面临了一个问题?

如果我需要同时部署好多个服务,难道要每个服务单独写Dockerfile然后在构建镜像,构建容器,这样累都累死了,所以docker官方给我们提供了docker-compose多服务部署的工具。

例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。。。。

Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)

可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。

1.3 安装docker-compose

官方文档地址:https://docs.docker.com/compose/compose-file/compose-file-v3/

官网下载:https://docs.docker.com/compose/install/

两种最新的docker安装方式

1.从github上下载docker-compose二进制文件安装

  • 下载最新版的docker-compose文件
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  • 1

若是github访问太慢,可以用daocloud下载(不推荐使用)

curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
  • 1
  • 添加可执行权限
chmod +x /usr/local/bin/docker-compose
  • 1
  • 测试安装结果
docker-compose --version
  • 1

在这里插入图片描述

2. pip安装(不推荐使用)

pip install docker-compose
  • 1

3. 卸载步骤

rm  /usr/local/bin/docker-compose
  • 1

在这里插入图片描述
如果使用卸载pip 安装,则使用以下命令

pip uninstall docker-compose
  • 1

1.4 Compose核心概念

一文件(重点)

docker-compose.yml

两要素(理解)

服务(service)

  • 一个个应用容器实例,比如订单微服务、库存微服务、mysql容器、nginx容器或者redis容器。

工程(project)

  • 由一组关联的应用容器组成的一个 完整业务单元·,在 docker-compose.yml 文件中定义。

1.5 Compose使用的三个步骤

  1. 编写Dockerfile定义各个微服务应用并构建出对应的镜像文件。
  2. 使用docker-compose.yml定义一个完整业务单元,安排好整体应用中的各个容器服务。
  3. 最后,执行docker-compose up命令 来启动并运行整个应用程序,完成一键部署上线

1.6 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/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 pause 暂停服务容器。
docker-compose unpause 恢复服务容器。
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

1.7 Compose编排微服务

改造升级微服务工程spring-boot-docker

【云原生 • Docker】Docker入门之中的Docker微服务实战
在这里插入图片描述

SQL建表建库

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=utf8 COMMENT='用户表'
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

改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.14</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.example</groupId>
    <artifactId>docker-boot</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!---->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>
        <!--SpringBoot  mybatis启动器-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.4</version>
        </dependency>
        <!--日志测试~-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>2.6.3</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--jetty-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>

        <!--热部署工具-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>
        <!--引入监控功能-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- 集成redis依赖  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.session</groupId>
            <artifactId>spring-session-data-redis</artifactId>
        </dependency>


        <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>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.8</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107

YML配置文件

server.port=6001
  # ========================alibaba.druid相关配置=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///192.168.111.169:3306/db2021?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.111.169
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=dhx.entity
  # ========================swagger=====================
spring.swagger2.enabled=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

主启动类

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan("dhx.mapper")
public class SpringBootDockerApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDockerApplication.class, args);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

RedisConfig配置类

/**
  * @auther dhx
  * @create 2023-6-27 17:19
  */

@Configuration
public class RedisConfig {
    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(
                Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer<?> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);// key序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);// value序列化
        redisTemplate.setHashKeySerializer(stringSerializer);// Hash key序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);// Hash value序列化
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

SwaggerConfig配置类

/**
  * @auther dhx
  * @create 2023-6-27 17:19
  */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    @Value("${spring.swagger2.enabled}")
    private Boolean enabled;

    @Bean
    public Docket createRestApi() {
    return  new Docket(DocumentationType.SWAGGER_2).groupName("学习DEMO").apiInfo(apiInfo()).select()
                .apis(RequestHandlerSelectors.basePackage("dhx.controlle")).paths(PathSelectors.any())
                .build();
    }

    public ApiInfo apiInfo() {
        return new ApiInfoBuilder()
            .title("docker-compose的学习Demo"+"\t"+new SimpleDateFormat("yyyy-MM-dd").format(new Date()))
            .description("docker-compose")
            .version("1.0")
            .termsOfServiceUrl("")
            .build();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

新建entity的User实体类

public class User implements Serializable {

    private Integer id;
    /**
          * 用户名
          */
    private String username;
    /**
          * 密码
          */
    private String password;
    /**
          * 性别 0=女 1=男 
          */
    private Byte sex;
/**
          * 删除标志,默认0不删除,1删除
          */
    private Byte deleted;
    /**
          * 更新时间
          */
    private Date updateTime;

/**
          * 创建时间
          */
    private Date createTime;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

UserDTO

@NoArgsConstructor
@AllArgsConstructor
@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;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

新建接口UserMapper

@Mapper
public interface UserMapper {
    int deleteByPrimaryKey(Integer id);
    int insert(User record);
    User selectByPrimaryKey(Integer id);
    List<User> selectAll();
    int updateByPrimaryKey(User record);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

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="dhx.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="dhx.entity.User">
    <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>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from t_user
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="dhx.entity.User" useGeneratedKeys="true" keyProperty="id">
    insert into t_user (id, username, password, 
      sex, deleted, update_time, 
      create_time)
    values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, #{password,jdbcType=VARCHAR}, 
      #{sex,jdbcType=TINYINT}, #{deleted,jdbcType=TINYINT}, #{updateTime,jdbcType=TIMESTAMP}, 
      #{createTime,jdbcType=TIMESTAMP})
  </insert>
  <update id="updateByPrimaryKey" parameterType="dhx.entity.User">
    update t_user
    set username = #{username,jdbcType=VARCHAR},
      password = #{password,jdbcType=VARCHAR},
      sex = #{sex,jdbcType=TINYINT},
      deleted = #{deleted,jdbcType=TINYINT},
      update_time = #{updateTime,jdbcType=TIMESTAMP},
      create_time = #{createTime,jdbcType=TIMESTAMP}
    where id = #{id,jdbcType=INTEGER}
  </update>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap" >

    select id, username, password, sex, deleted, update_time, create_time
    from t_user
    where id = #{id,jdbcType=INTEGER}
  </select>
  <select id="selectAll" resultMap="BaseResultMap">
    select id, username, password, sex, deleted, update_time, create_time
    from t_user
  </select>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45

新建service


@Service
@Slf4j
public class UserService {

    public static final String CACHE_KEY_USER = "user:";

    @Resource
    private UserMapper userMapper;

    @Resource
    private RedisTemplate redisTemplate;

    /**
      * addUser
      * @param user
          */
    public void addUser(User user){
        //1 先插入mysql并成功
        int i =userMapper.insert(user);
        if(i >0){
            //2 需要再次查询一下mysql将数据捞回来并ok
            user = userMapper.selectByPrimaryKey( user.getId());
            //3 将捞出来的user存进redis,完成新增功能的数据一致性。
            String key = CACHE_KEY_USER+user.getId();
            System.out.println("key"+key);
            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里面查询,如果有直接返回结果,如果没有再去查询mysql
        user = (User) redisTemplate.opsForValue().get(key);
        if (user == null) {
            //2 redis里面无,继续查询mysql
            user = userMapper.selectByPrimaryKey(id);
            if (user == null) {
                //3.1 redis+mysql 都无数据
                //你具体细化,防止多次穿透,我们规定,记录下导致穿透的这个key回写redis
                return user;
            } else {
                //3.2 mysql有,需要将数据写回redis,保证下一次的缓存命中率
                redisTemplate.opsForValue().set(key, user);
            }
        }
        return user;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

新建controller

@ApiModel(description = "用户User接口")
@RestController
@Slf4j
public class UserController {
    @Resource
    private 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("zzyy"+i);
            user.setPassword(UUID.randomUUID().toString().substring(0,6));
            user.setSex((byte) new Random().nextInt(2));
            user.setDeleted((byte)0);
            userService.addUser(user);
        }
    }
    @ApiOperation("查询1条记录")
    @RequestMapping(value = "/user/find/{id}",method = RequestMethod.GET)
    public User  findUserById(@PathVariable Integer id){
        return userService.findUserById(id);
    }
   
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

打包

mvn package命令将微服务形成新的jar包 并上传到Linux服务器/mydocker目录下

编写Dockerfile

# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER zzyy
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

构建镜像

docker build -t zzyy_docker:1.6 .
  • 1

1.8 不用Compose

单独的mysql容器实例

新建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
  • 1

进入mysql容器实例并新建库db2021+新建表t_user

docker exec -it mysql57 /bin/bash
  • 1
mysql -uroot -p
  • 1
create database db2021;
use db2021;
  • 1
  • 2
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='用户表';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

单独的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
  • 1

微服务工程

docker run -d -p 6001:6001 zzyy_docker:1.6
  • 1

上面三个容器实例依次顺序启动成功
在这里插入图片描述

swagger测试

http://localhost:你的微服务端口/swagger-ui.html#/

上面成功了,有哪些问题?

  1. 先后顺序要求固定,先mysql+redis才能微服务访问成功
  2. 多个run命令…
  3. 容器间的启停或宕机,有可能导致IP地址对应的容器实例变化,映射出错, 要么生产IP写死(可以但是不推荐),要么通过服务调用

1.9 使用Compose

编写docker-compose.yml文件

version: "3"                        # 描述 Compose 文件的版本信息
# 定义服务,可以多个
services:
 microService:                      #服务名称
  image: zzyy_docker:1.6            #使用哪个镜像
  container_name: ms01              #相当于run的 --name
  ports:                            #用来完成host与容器的端口映射关系
  - "6001:6001"						# 左边宿主机端口:右边容器端口
  volumes:                          #完成宿主机与容器中目录数据卷共享
  - /app/microService:/data         #使用自定义路径映射
  networks:                        # 配置容器连接的网络,引用顶级 networks 下的条目
   - atguigu_net 
  depends_on:                       #依赖前面两个容器
   - redis
   - mysql

 redis:
  image: redis:6.0.8
  ports:
  - "6379:6379"
  volumes:
  - /app/redis/redis.conf:/etc/redis/redis.conf
  - /app/redis/data:/data
  networks:
   - atguigu_net
  command: redis-server /etc/redis/redis.conf

 mysql:
  image: mysql:5.7
  environment:
   MYSQL_ROOT_PASSWORD: '123456'
   MYSQL_ALLOW_EMPTY_PASSWORD: 'no'
   MYSQL_DATABASE: 'db2021'
   MYSQL_USER: 'zzyy'
   MYSQL_PASSWORD: 'zzyy123'
  ports:
   - "3310:3306"
  volumes:
   - /app/mysql/db:/var/lib/mysql
   - /app/mysql/conf/my.cnf:/etc/my.cnf
   - /app/mysql/init:/docker-entrypoint-initdb.d
  networks:
   - atguigu_net
  command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks: 
    atguigu_net: # 一个具体网络的条目名称
    #name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
    #driver: bridge # 网络模式,默认为 bridge
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

第二次修改微服务工程docker_boot

server.port=6001
  # ========================alibaba.druid相关配置=====================
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#spring.datasource.url=jdbc:mysql:///192.168.111.169:3306/db2021?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.url=jdbc:mysql:///mysql:3306/db2021?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.111.169
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=dhx.entity
  # ========================swagger=====================
spring.swagger2.enabled=true
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

就用docker-compose 里的 服务名+容器内端口 访问,即:mysql:3306,其中3306必须是容器的端口,不能是主机的端口。

通过服务名访问,IP无关

打包

mvn package命令将微服务形成新的jar包 并上传到Linux服务器/mydocker目录下

编写Dockerfile

# 基础镜像使用java
FROM java:8
# 作者
MAINTAINER zzyy
# VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp
VOLUME /tmp
# 将jar包添加到容器中并更名为zzyy_docker.jar
ADD 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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

构建镜像

docker build -t zzyy_docker:1.6 .
  • 1

启动

执行 docker-compose up 或者 执行 docker-compose up -d
  • 1

在这里插入图片描述
在这里插入图片描述

进入mysql容器实例并新建库db2021+新建表t_user

docker exec -it mysql57 /bin/bash
  • 1
mysql -uroot -p
  • 1
create database db2021;
use db2021;
  • 1
  • 2
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='用户表';
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

测试通过

关停

docker-compose stop
  • 1

在这里插入图片描述

Docker-compose模板指令详解

Docker Compose 允许用户通过 docker-compose.yml 文件(YAML 格式)来定义一组相关联的容器为一个工程(project)。一个工程包含多个服务(service),每个服务中定义了创建容器时所需的镜像、参数、依赖等。

工程名若无特殊指定,即为 docker-compose.yml 文件所在目录的名称。

Docker Compose 模板文件我们需要关注的顶级配置有 versionservicesnetworksvolumes 几个部分,除 version 外,其他几个顶级配置下还有很多下级配置,后面也会详细给大家介绍,先来看看这几个顶级配置都什么意思:

  • version:描述 Compose 文件的版本信息,当前最新版本为 3.8,对应的 Docker 版本为 19.03.0+
  • services:定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等;
  • networkds:定义网络,可以多个,根据 DNS server 让相同网络中的容器可以直接通过容器名称进行通信;
  • volumes:数据卷,用于实现目录挂载。

version

描述 Compose 文件的版本信息,当前最新版本为 3.8,对应的 Docker 版本为 19.03.0+。关于每个版本的详细信息请参考:https://docs.docker.com/compose/compose-file/compose-versioning/

以下为 Compose 文件的版本信息所对应的 Docker 版本。

Compose file formatDocker Engine release
3.819.03.0+
3.718.06.0+
3.618.02.0+

services

刚才我们提到 docker-compose.yml 文件中包含很多下级配置项,下面带大家把一些常用的配置项详细了解一下,先从顶级配置 services 开始。

services 用来定义服务,可以多个,每个服务中定义了创建容器时所需的镜像、参数、依赖等,就像将命令行参数传递给 docker run 一样。同样,网络和数据卷的定义也是一样的。

比如,之前我们通过 docker run 命令构建一个 MySQL 应用容器的命令如下:

docker run \
-d \
--name mysql8 \
-p 3306:3306 \
-v /opt/data/docker_mysql/conf:/etc/mysql/conf.d \
-v /opt/data/docker_mysql/data:/var/lib/mysql 
\-e MYSQL_ROOT_PASSWORD=root 
\mysql:8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

使用 docker-compose.yml 以后则可以这样定义:

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mysql: # 服务名称
    image: mysql:8 # 创建容器时所需的镜像
    container_name: mysql8 # 容器名称,默认为"工程名称_服务条目名称_序号"
    ports: # 宿主机与容器的端口映射关系
      - "3306:3306" # 左边宿主机端口:右边容器端口
    environment: # 创建容器时所需的环境变量
      MYSQL_ROOT_PASSWORD: root
    volumes:
      - "/opt/data/docker_mysql/conf:/etc/mysql/conf.d"
      - "/opt/data/docker_mysql/data:/var/lib/mysql"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

然后通过 dokcer-compose 相关命令即可完成容器的创建,停止或删除等一系列操作。

image

指定创建容器时所需的镜像名称标签或者镜像 ID。如果镜像在本地不存在,会去远程拉取。

services:
  web:
    image: hello-world
  • 1
  • 2
  • 3

build

除了可以基于指定的镜像构建容器,还可以基于 Dockerfile 文件构建,在使用 up 命令时会执行构建任务。

通过 build 配置项可以指定 Dockerfile 所在文件夹的路径。Compose 将会利用 Dockerfile 自动构建镜像,然后使用镜像启动服务容器。

build 配置项可以使用绝对路径,也可以使用相对路径。

# 绝对路径,在该路径下基于名称为 Dockerfile 的文件构建镜像
/usr/local/docker-centos
# 相对路径,相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜像
.
  • 1
  • 2
  • 3
  • 4

创建目录并编写 docker-compose.yml 文件。

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mycentos: # 服务名称
    build: . # 相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile-alternate 的文件构建镜像
    container_name: mycentos7 # 容器名称,默认为"工程名称_服务条目名称_序号"
    ports: # 宿主机与容器的端口映射关系
      - "8080:8080" # 左边宿主机端口:右边容器端口
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

context

该选项可以是 Dockerfile 文件的绝对/相对路径,也可以是远程 Git 仓库的 URL,当提供的值是相对路径时,相对当前 docker-compose.yml 文件所在目录。

build:
  context: . # 相对当前 docker-compose.yml 文件所在目录,基于名称为 Dockerfile 的文件构建镜像
  • 1
  • 2

dockerfile

一般情况下,默认都基于文件名叫 Dockerfile 的文件构建镜像,当然也可以是自定义的文件名,使用 dockerfile 声明,不过这个选项只能声明文件名,文件所在路径还是要通过 centext 来声明

build:
  context: . # 相对当前 docker-compose.yml 文件所在目录
  dockerfile: Dockerfile-alternate # 基于名称为 Dockerfile-alternate 的文件构建镜像
  • 1
  • 2
  • 3

container_name

Compose 创建的容器默认生成的名称格式为:工程名称_服务条目名称_序号。如果要使用自定义名称,使用 container_name 声明。

services:
  mycentos:
    container_name: mycentos7 # 容器名称,默认为"工程名称_服务条目名称_序号"
  • 1
  • 2
  • 3

因为 Docker 容器名称必须是唯一的,所以如果指定了自定义名称,就不能将服务扩展至多个容器。这样做可能会导致错误。

关于序号

序号是干什么用的呢,看下面这个例子你就懂了,docker-compose.yml 文件内容如下:

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  helloworld: # 服务名称
    image: hello-world
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

然后通过 --scale 指定 helloworld 服务一次性启动 3 个。

docker-compose up -d --scale helloworld=3
  • 1

通过下图可以看到有 3 个容器被创建,容器名称最后的序号是从 1 开始累加的,这就是序号的作用。所以如果指定了自定义名称,就不能将服务扩展至多个容器。
在这里插入图片描述

depends_on

使用 Compose 最大的好处就是敲最少的命令做更多的事情,但一般项目容器启动的顺序是有要求的,如果直接从上到下启动容器,必然会因为容器依赖问题而启动失败。例如在没有启动数据库容器的情况下启动了 Web 应用容器,应用容器会因为找不到数据库而退出。depends_on 就是用来 解决容器依赖、启动先后问题的配置项 。以下先启动redis db 再启动web

version: "3.0"
services:
  web:
    build: .
    depends_on:            #但是web服务不会等待redis  db完全启动之后再启动
     - db  (服务的ID名称)
     - redis
  redis:
    image: redis
  db: 
    image: mysql:5.6 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

上述 YAML 文件定义的容器会先启动 db 和 redis 两个服务,最后才启动 web 服务。

ports

容器对外暴露的端口,格式:左边宿主机端口:右边容器端口

ports:
  - "3000"
  - "8080:8080"
  - "49100:22"
  - "127.0.0.1:8080:8080"
  • 1
  • 2
  • 3
  • 4
  • 5

expose

容器暴露的端口不映射到宿主机,只允许能被连接的服务访问。

expose:
 - "80"
 - "8080"
  • 1
  • 2
  • 3

restart

容器重启策略,简单的理解就是 Docker 重启以后容器要不要一起启动:

  • no:默认的重启策略,在任何情况下都不会重启容器;
  • on-failure:容器非正常退出时,比如退出状态为非0(异常退出),才会重启容器;
  • always:容器总是重新启动,即使容器被手动停止了,当 Docker 重启时容器也还是会一起启动;
  • unless-stopped:容器总是重新启动,除非容器被停止(手动或其他方式),那么 Docker 重启时容器则不会启动。
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    restart: always
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

environment

设置环境变量 可以使用数组字典两种格式,布尔相关的值(true、false、yes、no)都需要用引号括起来,以确保 YML 解析器不会将它们转换为真或假。

只给定名称的变量会自动获取运行compose主机上对应的变量

environment:
  RACK_ENV: development
  SHOW: 'true'
  SESSION_SECRET:
  • 1
  • 2
  • 3
  • 4

或者以下格式:

environment:
  - RACK_ENV=development
  - SHOW=true
  - SESSION_SECRET
  • 1
  • 2
  • 3
  • 4

env_file

从文件中获取环境变量,可以指定一个或多个文件,可以指定一个或多个文件。

如果docker-compose -f FILE 方式来指定Compose模板文件 则env_file中变量的路径会基于模板文件路径

env_file: .env

env_file:
  - /opt/runtime_opts.env # 绝对路径
  - ./common.env # 相对路径,相对当前 docker-compose.yml 文件所在目录
  - ./apps/web.env # 相对路径,相对当前 docker-compose.yml 文件所在目录
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注意:env 文件中的每一行需采用 键=值 格式。以 # 开头的行会被视为注释并被忽略。空行也会被忽略。

comand

覆盖容器启动后默认执行的命令

command: echo "hello world"
  • 1

该命令也可以是一个列表。

command: ["echo", "helloworld"]
  • 1

volumes

数据卷,用于实现目录挂载,支持指定目录挂载匿名挂载具名挂载。并可以设置访问模式

  • 指定目录挂载的格式为:左边宿主机目录:右边容器目录,或者 左边宿主机目录:右边容器目录:读写权限
  • 匿名挂载格式为:容器目录即可,或者 容器目录即可:读写权限
  • 具名挂载格式为:数据卷条目名称:容器目录,或者 数据卷条目名称:容器目录:读写权限
# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mysql: # 服务名称
    volumes:
      # 绝对路径
      - "/opt/data/docker_mysql/data:/var/lib/mysql"
      # 相对路径,相对当前 docker-compose.yml 文件所在目录
      - "./conf:/etc/mysql/conf.d"
      # 匿名挂载,匿名挂载只需要写容器目录即可,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "/var/lib/mysql"
      # 具名挂载,就是给数据卷起了个名字,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定义数据卷,可以多个
volumes:
  mysql-data-volume: # 一个具体数据卷的条目名称
    name: mysql-data-volume # 数据卷名称,默认为"工程名称_数据卷条目名称"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

network_mode

设置网络模式,类似 docker run 时添加的参数 --net host 或者 --network host 的用法。

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"
  • 1
  • 2
  • 3
  • 4
  • 5

networks

配置容器连接的网络,引用顶级 networks 下的条目。

# 定义服务,可以多个
services:
  nginx: # 服务名称
    networks: # 配置容器连接的网络,引用顶级 networks 下的条目
      - nginx-net # 一个具体网络的条目名称

# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks:
  nginx-net: # 一个具体网络的条目名称
    name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
    driver: bridge # 网络模式,默认为 bridge
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

aliases

网络上此服务的别名。同一网络上的其他容器可以使用服务名或此别名连接到服务容器。同一服务在不同的网络上可以具有不同的别名。

# 定义服务,可以多个
services:
  nginx: # 服务名称
    networks: # 配置容器连接的网络,引用顶级 networks 下的条目
      nginx-net: # 一个具体网络的条目名称
        aliases: # 服务别名,可以多个
          - nginx1 # 同一网络上的其他容器可以使用服务名或此别名连接到服务容器

# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
networks:
  nginx-net: # 一个具体网络的条目名称
    name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
    driver: bridge # 网络模式,默认为 bridge
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

volumes

通过顶级配置 services 的学习,大家应该已经明白顶级配置 volumes 是干嘛的了,这里再详细把配置的不同方式讲解一下。

以下方式的数据卷声明创建卷时会使用默认的名称:"工程名称_数据卷条目名称"

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mysql:
    image: mysql:8
    container_name: mysql8
    ports:
      - "3306:3306"
    environment
      MYSQL_ROOT_PASSWORD: root
    volumes:
      # 具名挂载,就是给数据卷起了个名字,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定义数据卷,可以多个
volumes:
  mysql-data-volume: # 一个具体数据卷的条目名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

在这里插入图片描述
以下方式的数据卷声明创建卷时会使用自定义的名称。

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  mysql:
    image: mysql:8
    container_name: mysql8
    ports:
      - "3306:3306"
    environment
      MYSQL_ROOT_PASSWORD: root
    volumes:
      # 具名挂载,就是给数据卷起了个名字,容器外对应的目录会在 /var/lib/docker/volume 中生成
      - "mysql-data-volume:/var/lib/mysql"

# 定义数据卷,可以多个
volumes:
  mysql-data-volume: # 一个具体数据卷的条目名称
    name: mysql-data-volume # 数据卷名称,默认为"工程名称_数据卷条目名称"
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

在这里插入图片描述

networks

通过顶级配置 services 的讲解,大家其实已经明白顶级配置 networks 是干嘛的了,这里再详细把配置的不同方式讲解一下。

如果不声明网络,每个工程默认会创建一个网络名称为"工程名称_default"bridge 网络。

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"

# 定义网络,可以多个。如果不声明,默认会创建一个网络名称为"工程名称_default"的 bridge 网络
#networks:
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

在这里插入图片描述

以下方式的网络声明创建网络时会使用默认的名称:"工程名称_网络条目名称",网络模式默认为 bridge

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    networks: # 配置容器连接的网络,引用顶级 networks 下的条目
      nginx-net:

# 定义网络,可以多个
networks:
  nginx-net: # 一个具体网络的条目名称
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这里插入图片描述

以下方式的网络声明创建网络时会使用自定义的名称,还可以通过 driver 选择网络模式,默认为 bridge

# 描述 Compose 文件的版本信息
version: "3.8"
# 定义服务,可以多个
services:
  nginx:
    image: nginx
    container_name: mynginx
    ports:
      - "80:80"
    networks: # 配置容器连接的网络,引用顶级 networks 下的条目
      nginx-net:

# 定义网络,可以多个
networks:
  nginx-net: # 一个具体网络的条目名称
    name: nginx-net # 网络名称,默认为"工程名称_网络条目名称"
    driver: bridge # 网络模式,默认为 bridge
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

在这里插入图片描述

healtheck

通过命令检查容器是否健康运行

healthcheck:
  test: ["CMD","curl","-f","http://localhost"]
  interval: 1m30s
  timeout: 10s 
  retries: 3
  • 1
  • 2
  • 3
  • 4
  • 5

sysctls

配置容器的内核参数

sysctls:
  net.core.somaxconn: 1024
  net.ipv4.tcp_syncookies: 0

sysctls:
  - net.core.somaxconn=1024
  - net.ipv4.tcp_syncookies=0
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

ulimits

ulimits:
  nproc: 65535
  nofile:
    soft: 20000
    hard: 40000
  • 1
  • 2
  • 3
  • 4
  • 5

compose的build指令

build 指令
作用:将指定的dockefile打包成指对应镜像,然后运行该镜像

services:
  web:
   build: 指定Dockerfile所在目录,先根据build中的dockerfile自动构成镜像,自动运行容器
     context: demo   ./demo   /root/demo指定上下文目录  Dockerfile所在目录 
     dockerfile: Dockerfile
   container_name: demo
   ports:
     - "8081:8081"
   networks:
     - hello  
   depends_on:
     - tomcat01
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

外部命令

'创建卷'
$ docker volume create  tomcatwebapps01 
 
'查看卷'
$ docker volume ls 
 
'创建网桥'
$ docker network  create bridge hello  
 
'查看网桥' 
$ docker network ls 
 
'查看容器信息' 
$ docker inspect 容器名 
 
'如果要使用自定义卷名就要手动创建卷名' 
$ docker volume create 卷名 
 
'如果要使用自定义网桥就要手动创建桥' 
$ docker network create -d bridge 桥名
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/73519
推荐阅读
相关标签
  

闽ICP备14008679号