通过网盘分享的文件:MD文档笔记
链接: https://pan.baidu.com/s/1ao2wfyLEdN50YmIqdzfGYQ?pwd=5w5z 提取码: 5w5z
–来自百度网盘超级会员v6的分享

一.Compose 简介

Docker Compose 是一个需要在 Docker 主机上安装的 Docker 容器编排外部工具

可以使用 YML 文件来配置应用程序需要的所有服务,然后通过一条命令就可以从 YML 配置文件中创建并启动所有服务,还可通过一系列简单命令实现对其完整生命周期的管理

Docker Compose 的前身是Fig(无花果)

二.Compose文件

1.文件简介

Docker Compose 使用 YAML 文件来定义服务

官方推荐的默认文件名为compose.yml,但同时也支持 docker-compose.yml

由于一个 compose 文件中定义的是一个项目中所有服务,所以一般在创建 compose文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile 放入该目录,并在该目录中新建 compose 文件

compose 文件中包含 6 个顶级属性及很多的它们下面所包含的属性

  • version
  • services
  • networks
  • volumes
  • configs
  • secrets

2.顶级属性

2.1.version

version 是一个顶级属性,但已经过时,不再需要在 compose 文件中出现了

从以下官网说明中可以看出

https://docs.docker.com/reference/compose-file/

在这里插入图片描述

2.2.networks

networks 作为一个顶级属性,用于定义和创建应用中所使用到的所有网络

其下包含的第一级属性即为网络名称,这个网络名称可以随意命名

networks:
  frontend:                          # 网络名称
    driver: bridge                   # 驱动类型(bridge 是默认值)
    driver_opts:                     # 驱动特定选项
      com.docker.network.driver.mtu: "1450"
    ipam:                            # IP 地址管理
      driver: default
      config:
        - subnet: 172.28.0.0/16
          gateway: 172.28.0.1
    attachable: true                 # 允许外部容器连接此网络
  backend:
    driver: overlay                  # Swarm 模式使用 overlay 实现跨主机通信
    internal: true                   # 内部网络,禁止访问外网
  proxy_net:
    external: true                   # 表示该网络已在 Docker 中创建
    name: my_existing_network        # 外部网络的实际名称

常用属性如下

  • driver_opts

    传递给驱动的额外参数

  • ipam

    自定义 IP 分配方案

  • internal

    是否隔离外部网络访问

  • external

    是否由外部创建(Compose 不创建)

  • name

    networks 下的第一级属性(网络名称),并不是真正的网络名称,而仅仅是网络名称的一部分

    在真正生成网络后,其真正的网络名称格式为:当前 compose 文件所在目录名_ networks 下的第一级属性

  • driver

    用于指定网络驱动

    • bridge:单机网络(缺省驱动为 bridge)

    • host

    • none

  • attachable

    如果该属性设置为 true,则除了当前 compose 中定义的服务外,其它独立容器也可以连接到此网络

    缺省状态为 false

2.3.volumes

volumes 作为一个顶级属性,用于定义和创建应用中所使用到的所有 volume

其下包含的第一级属性即为volume 的卷标,这个卷标可以随意命名,这个卷标所代表的是当前 Docker主机中的目录,至于该目录的具体位置,是由系统自动分配的

常用的属性

driver 存储驱动,默认为 local
driver_opts 特定于驱动的选项(如 bind mount、tmpfs)
labels 标签,便于管理
external 是否外部创建
name 实际卷名称(当 external=true 时必须匹配)

【示例】

services:
  backend:
    image: awesome/database 
	volumes:
      -	db-data: /etc/data 
  backup:
    image: backup-service 
	volumes:
      -	db-data:/var/lib/backup/data 
volumes:
  db-data:

2.4.serivces

services 是一个顶级属性,用于定义一个应用中所包含的服务

Docker Compose 会将每个服务部署在各自的容器中

其下包含的第一级的属性即为服务名称,这个名称可以根据服务内容随意命名,而在服务名称下还可包含很多的属性,常用属性如下

(1).build

用于指定一个 Dockerfile 的路径,该 Dockerfile 则是用于创建当前服务镜像的

  • 路径

    • 路径可以是以斜杠(/)开头的绝对路径

    • 可以是相对于当前 compose 文件的、以点(.)号开头的相对路径

  • 名称

    如果 Dockerfile 文件名不是默认名称,则需要通过 build 下的 context 属性指定路径,dockerfile 属性指定文件名

    build:
      context: ./
      dockerfile: myDockerfile
    
(2).image

指定当前服务所需要使用的镜像,这个镜像可以是本地镜像,也可以是远程镜像仓库中的镜像(会自动 pull)

如果设置了 build,此时再设置的 image 属性即为构建出的镜像的名称与 Tag

(3).container_name

该属性用于设置容器名称,但并不是必须的

如果没有设置该属性,容器名称则会采用 “合成方式”,而合成时需要用到 services 下的第一级属性

  • 在 services 下存在一级属性,称为服务名称,该级属性是作为 services 下的第一级属性出现的,服务名称将来会作为容器名称的一部分出现,容器的名称格式为:当前 compose文件所在目录名_ 服务名称

  • 如果在 services 下没有指定 image 属性,而是使用 bild 属性,即没有现成的镜像,而是根据 build 下指定的 Dockerfile 生成镜像,此时生成的镜像名称格式为:当前 compose 文件所在目录名-服务名称

(4).ports

一个端口号列表:前面为暴露出的端口号,后面为容器中应用的端口号

如果仅设置了一个端口号,那么这个端口号是容器中应用的端口号,其暴露到宿主机的端口号会被随机分配

ports:
  - 80: 80		# 绑定容器的 80 端口到主机的 80 端口
  - 9000: 80	    # 绑定容器的 80 端口到主机的 9000 端口
  - 443			# 绑定容器的 443 端口到主机的任意端口,容器启动时随机分配绑定的主机端口号
(5).command

用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令

如果直接按照Dockerfile 中的CMD 指令内容执行即可,则compose 文件中无需该command 属性

(6).depends_on

一个列表

用于指定当前服务的启动所依赖的应用名称

即列表中指定的服务会先于当前服务启动

(7).deploy

用于指定当前服务容器的部署设置

其下有一个常用属性 replicas,用于指定该服务启动的容器的数量(即实现一个服务多个容器)

一旦指定了 deploy:replicas,就不能再指定 container_name 属性了,因为各个启动的容器名称不能相同,而只能由系统自动生成

services:
  frontend:
    image: awesome/webapp 
	deploy:
      mode: replicated
      replicas: 6
(8).networks

用于指定当前服务容器要连接到的网络

该网络必须是已经存在的,或通过顶级属性networks 创建的网络

(9).volumes

用于指定当前服务容器所使用到的所有 volume

这些 volume 可以使用路径与卷标两种方式

【示例1】下面是路径方式,非常直观,易于查看,但需要管理本地路径

db:
  image: mariadb:latest 
  ports:
    - "3306:3306"
  volumes:
    - /etc/mysql:/var/lib/mysql

【示例2】

下面是卷标方式,backend 与 backup 两个服务共享了 db-data 的卷,逻辑简洁明了,且无需管理本地路径

但具体卷标所代表的是 Docker 主机的哪个路径,并不能直观的看到,需要通过 docker volume inspect [卷标]来查看

services:
  backend:
    image: awesome/database 
	volumes:
      -	db-data: /etc/data 
  backup:
    image: backup-service 
	volumes:
      -	db-data:/var/lib/backup/data 
volumes:
  db-data:

2.5.secrets

安全地传递敏感信息(密码、密钥等)到容器内

所有 secrets 默认挂载为只读文件,路径 /run/secrets/<name>

常用属性

属性 说明
file 从本地文本文件加载内容
environment 从宿主机环境变量读取值
external 使用已有 secret
name 对应 Docker 中的 secret 名称

【示例】

secrets:
  db_password:                   # secret 名称
    file: ./secrets/db_pass.txt  # 从本地文件读取内容
  jwt_key:
    environment: JWT_SECRET_KEY  # 从当前环境变量获取(Compose 主机上设置)
  tls_cert:
    external: true               # 使用 Docker 已有的 secret(如通过 `docker secret create` 创建)
    name: prod_tls_cert

services:
  web:
    image: nginx
    secrets:
      - db_password
      - source: db_password
        target: /run/secrets/postgres_password  # 自定义挂载路径
        uid: "1000"
        gid: "1000"
        mode: 0400                              # 权限设置

2.6.configs

用于传递非敏感的配置文件(如 Nginx conf、JSON 配置等)

类似于 secrets,但内容不加密,适合通用配置文件

【示例】

configs:
  app_config:
    file: ./config/app.yaml        # 从本地文件加载
  nginx_conf:
    external: true                # 使用已创建的 config
    name: live_nginx_conf

services:
  web:
    image: nginx
    configs:
      - source: app_config
        target: /etc/myapp/config.yaml
        uid: "1000"
        gid: "1000"
        mode: 0440

2.7.name

显式设置 Compose 项目的名称

默认项目名为当前目录名

【示例】

name: production-api-stack

services:
  web:
    image: myapp:latest

设置后,所有资源前缀变为 production-api-stack_web_1 而非 <dir>_web_1

3.常用命令

Docker Compose 通过docker-compose 系列命令查看和控制compose 中的所有服务容器

(1).docker-compose pull

拉取compose 中服务依赖的全部镜像或指定镜像

通过在命令后添加服务名称来指定

(2).docker-compose config

检查 compose 文件是否正确

可添加选项-q,表示只有存在问题时才有输出

(3).docker-compose up

启动 compose 中的所有容器

-d 选项表示后台启动

(4).docker-compose logs

查看comopse 中所有服务或指定服务的运行日志

通过在命令后添加服务名称来指定

默认情况下,将对不同的服务日志使用不同的颜色来区分

(5).docker-compose ps

列出 compose 中所有服务或指定服务

通过在命令后添加服务名称来指定

(6).docker-compose top

列出 compose 中当前正在运行的所有服务或指定服务

通过在命令后添加服务名称来指定

(7).docker-compose images

列出compose 中所有服务或指定服务对应的镜像

通过在命令后添加服务名称来指定

(8).docker-compose port

列出指定服务容器的指定端口所映射的宿主机端口

(9).docker-compose run

在指定服务上执行一条命令

(10).docker-compose exec

进入指定服务容器

通过在命令后添加服务名称来指定

(11).docker-compose pause

暂停 compose 中所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(12).docker-compose unpause

恢复 compose 中处于暂停状态的所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(13).docker-compose stop

停止 compose 中所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(14).docker-compose restart

重启 compose 中所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(15).docker-compose start

启动 compose 中所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(16).docker-compose kill

通过发送 SIGKILL 信号停止指定服务的容器

(17).docker-compose rm

删除 compose 中处于停止状态的所有服务容器或指定服务容器

通过在命令后添加服务名称来指定

(18).docker-compose down

停止并删除 compose 中的所有服务容器、网络、镜像、数据卷

4.Compose 使用步骤

  1. 使用 Dockerfile 定义应用程序的环境
  2. 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行
  3. 执行 docker-compose up 命令来启动并运行整个应用程序

三.Compose 安装

1.CentOS安装

(1).使用Python安装

yum -y install python3-pip

pip3 install --upgrade pip -i https://pypi.tuna.tsinghua.edu.cn/simple

pip3 install docker-compose -i https://pypi.tuna.tsinghua.edu.cn/simple

docker-compose version

(2).使用github安装

Linux 上可以从 Github 上下载它的二进制包来使用

最新发行的版本地址:https://github.com/docker/compose/releases

在这里插入图片描述

运行以下命令以下载 Docker Compose 的当前稳定版本

# 下载2.38.1版本
sudo curl -L "https://github.com/docker/compose/releases/download/v2.38.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

# 下载v5.1.0版本
sudo curl -L "https://github.com/docker/compose/releases/download/v5.1.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose

下载过程会非常慢,甚至前几次都无法连接,需要多次尝试

在这里插入图片描述

反复几次下载之后下载成功

在这里插入图片描述

该命令会从 github 下载 docker compose 插件到当前主机的/usr/local/bin 目录中,并被重命名为 docker-compose

要安装其他版本的 Compose请替换版本号"2.38.1"

添加可执行权限

sudo chmod +x /usr/local/bin/docker-compose

ll /usr/local/bin

在这里插入图片描述

创建软链

sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose

在这里插入图片描述

测试是否安装成功

docker-compose version

在这里插入图片描述

注意: 对于 alpine,需要以下依赖包: py-pip,python-dev,libffi-dev,openssl-dev,gcc,libc-dev,和 make

2.macOS

Mac 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Mac 用户不需要单独安装 Compose

3.windows PC

Windows 的 Docker 桌面版和 Docker Toolbox 已经包括 Compose 和其他 Docker 应用程序,因此 Windows 用户不需要单独安装 Compose

四.项目构建

1.手工启动项目示例

1.1.项目代码

这是一个金融产品交易平台中的部分功能,是一个 Spring Boot 工程

控制器具有三个接口

  • 查询所有产品
  • 根据产品名称查询
  • 上线新产品

整个架构包含一个 Redis 与 MySQL服务器

(1).数据库
CREATE DATABASE IF NOT EXISTS `test`;

USE `test`;

DROP TABLE IF EXISTS `product`;

CREATE TABLE `product` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(20) DEFAULT NULL,
`rate` double DEFAULT NULL,
`amount` double DEFAULT NULL,
`raised` double DEFAULT NULL,
`cycle` int(11) DEFAULT NULL,
`endTime` char(10) DEFAULT '0',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8;


INSERT INTO `product` VALUES
(1,'TXTY',2.76,50000,20000,30,'2022-07-10'),
(2,'GTTY',2.86,30000,30000,60,'2022-07-12'),
(3,'GTGX',2.55,60000,50000,90,'2022-07-09'),
(4,'GFMA',2.96,30000,20000,7,'2022-05-10'),
(5,'TYXD',2.65,80000,60000,20,'2022-07-05'),
(6,'HNSY',3.05,30000,20000,10,'2022-06-10'),
(7,'HNSX',2.76,50000,30000,30,'2022-07-02'),
(8,'LXSY',2.86,30000,20000,20,'2022-07-11');

(2).启动类
package com.abc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;

@EnableCaching
@SpringBootApplication
public class SsrmApplication {

    public static void main(String[] args) {
        SpringApplication.run(SsrmApplication.class, args);
    }

}
(3).依赖
<?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 https://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.7.18</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.abc</groupId>
    <artifactId>ssrm</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>
        <tika.version>1.28.5</tika.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.2</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.23</version>
        </dependency>

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

        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-parsers</artifactId>
            <version>${tika.version}</version>
            <type>pom</type>
        </dependency>
        <!--<dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-core</artifactId>
            <version>${tika.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika-parsers-standard-package</artifactId>
            <version>${tika.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.tika</groupId>
            <artifactId>tika</artifactId>
            <version>${tika.version}</version>
        </dependency>-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
(4).配置文件

这里特别要注意 mysql 与 redis 的 IP,使用的是相应 Docker 主机的 IP

mybatis:
  mapper-locations: classpath:*.xml
  type-aliases-package: com.abc.bean

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://192.168.1.11:3306/test?useUnicode=true&characterEncoding=utf-8
    username: root
    password: root

  redis:
    host: 192.168.1.11
    port: 6379
  cache:
    type: redis
    cache-names: pc

logging:
  file:
    name: "/var/applogs/finance.log"
  pattern:
    console: level-%-5level - %msg%n
    file: level-%-5level - %msg%n
  level:
    root: warn
    com.abc.dao: debug
(5).控制器
package com.abc.controller;

import com.abc.bean.Product;
import com.abc.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class ProductController {

    @Autowired
    private ProductService service;

    // 查询所有产品
    @GetMapping("/")
    public String indexHandle() {
        List<Product> allProducts = service.findAllProducts();

        StringBuilder sb = new StringBuilder();
        for (Product product : allProducts) {
            sb.append(product).append("<br>");
        }
        return sb.toString();
    }

    // 上架新产品
    @PostMapping("/register")
    public String registerHandle(@RequestBody Product product) {
        // 添加新产品
        service.saveProduct(product);
        return "save success";
    }

    // 根据产品名称查询产品
    @GetMapping("/list")
    public String listHandle(String name) {
        List<Product> result = service.findProductsByName(name);

        StringBuilder sb = new StringBuilder();
        for (Product product : result) {
            sb.append(product).append("<br>");
        }
        return sb.toString();
    }
}
(6).实体类
package com.abc.bean;

import lombok.Data;

import java.io.Serializable;


@Data
public class Product implements Serializable {
    private Integer id;
    // 产品名称
    private String name;
    // 年化利率
    private Double rate;
    // 募集总额
    private Double amount;
    // 已募集金额
    private Double raised;
    // 产品周期
    private Integer cycle;
    // 产品募集结束时间
    private String endTime;
}
(7).Service
  • ProductService
package com.abc.service;

import com.abc.bean.Product;

import java.util.List;

public interface ProductService {
    void saveProduct(Product product);

    List<Product> findAllProducts();

    List<Product> findProductsByName(String name);
}
  • ProductServiceImpl
package com.abc.service;

import com.abc.bean.Product;
import com.abc.dao.ProductDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;

@Service
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductDao dao;

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(value = "pc", allEntries = true)
    public void saveProduct(Product product) {
        dao.insertProduct(product);
    }

    @Cacheable(value = "pc", key = "'product_'+#name")
    @Override
    public List<Product> findProductsByName(String name) {
        return dao.selectProductsByName(name);
    }

    @Cacheable(value = "pc", key = "'product_all'")
    @Override
    public List<Product> findAllProducts() {
        return dao.selectAllProducts();
    }
}
(8).DAO
package com.abc.dao;

import com.abc.bean.Product;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface ProductDao {
    void insertProduct(Product product);

    List<Product> selectAllProducts();

    List<Product> selectProductsByName(String name);
}
(9).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.abc.dao.ProductDao">
    <insert id="insertProduct">
        insert into product(name, rate, amount, raised, cycle, endTime)
        values(#{name}, #{rate}, #{amount}, #{raised}, #{cycle}, #{endTime})
    </insert>

    <select id="selectAllProducts" resultType="Product">
        select id,name,rate, amount, raised, cycle, endTime
        from product
    </select>

    <select id="selectProductsByName" resultType="Product">
        select id,name,rate, amount, raised, cycle, endTime
        from product
        where name like '%' #{xxx} '%'
    </select>
</mapper>

1.2.定义Dockerfile

在 Docker 主机的任意目录中新建一个目录,该新建目录名称与项目名称相同

这里在/root 目录中 mkdir 一个名称为 finance(金融)的目录

mkdir -p /root/ssrm

在这里插入图片描述

然后在该目录中新建 Dockerfile 文件

[root@docker ~]# cd /root/ssrm/
[root@docker ssrm]# vim Dockerfile

# 指定当前镜像继承自 openjdk:8u102,因为下面要运行 Jar 包,需要 JDK 环境
FROM openjdk:8u102
# 作者与项目相关说明
MAINTAINER zhangsan zs@163.com
LABEL version="1.0" description="this is a spring boot application"
# 将当前目录下的 jar 包 copy 到容器中
# 注意:这个当前目录指的是 docker build 命令最后一个参数指定的上下文路径
COPY ssrm-0.0.1-SNAPSHOT.jar ssrm.jar
# 一定要执行的 exec
ENTRYPOINT ["java", "-jar", "ssrm.jar"]
# 指定对外暴露的端口号
EXPOSE 9000

在这里插入图片描述

注意可以在 Dockerfile 中通过 VOLUME 指定数据卷

1.3.项目打包

将项目 package 打为 jar 包,然后再上传到 Docker 主机的"/root/ssrm"目录中

在这里插入图片描述

1.4.手工启动项目

为了与使用 Docker Compose 编排项目进行对比,体现 Docker Compose 的方便快捷,这里先使用纯手工方式启动项目

1.4.1.启动 mysql 容器

在该系统中,要首先启动 mysql 或 redis,这里先启动 mysql 容器

docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=root \
-v /root/software/mysql/data:/var/lib/mysql \
-v /root/software/mysql/log:/var/log \
-v /root/software/mysql/conf:/etc/mysql/conf.d \
-dp 3306:3306 \
mysql:8

在这里插入图片描述

进入 mysql

docker exec -it mysql /bin/bash

mysql -uroot -p

在这里插入图片描述

  • 创建数据库
show databases;

create database if not exists test;

use test;

drop table if exists product;

在这里插入图片描述

  • 创建表
CREATE TABLE IF NOT EXISTS `product`(

  `id` INT(11) not null AUTO_INCREMENT,

  `name` VARCHAR(100) default NULL,

  `rate` double default NULL,

  `amount` double default NULL,

  `raised` double default NULL,

  `cycle` int(11) default NULL,

  `endTime` char(10) default '0',

  PRIMARY KEY ( `id` )

)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

在这里插入图片描述

  • 插入数据
insert into product(id,name,rate,amount,raised,cycle,endTime)values(1,'TXTY',2.76,50000,20000,6,'2020-10-10');

insert into product(id,name,rate,amount,raised,cycle,endTime)values(2,'JULY',3.31,20000,40000,7,'2021-11-11');

insert into product(id,name,rate,amount,raised,cycle,endTime)values(3,'LUCY',1.09,2456,4537,3,'2011-11-11');

insert into product(id,name,rate,amount,raised,cycle,endTime)values(4,'TOM' ,8.09,8976,3456,4,'2031-11-11');

在这里插入图片描述

查看数据表

SHOW TABLES;

在这里插入图片描述

查询数据

select * from product;

在这里插入图片描述

1.4.2.启动 redis 容器

注意这里可以直接执行下面的启动 redis 容器的命令的前提是,借用了之前在"常用服务器安装"章节中安装单机版 Redis 中创建的外挂文件/root/software/redis/redis.conf

docker run --name myredis \
-v /root/software/redis/redis.conf:/etc/redis/redis.conf \
-v /root/software/redis/data:/data \
-dp 6379:6379 \
redis:7 \
redis-server /etc/redis/redis.conf

在这里插入图片描述

1.4.3.启动应用容器
(1).检查应用配置文件

在构建应用镜像之前,打开项目的配置文件,再次确认配置文件中指定的 mysql 与 redis主机的 IP 地址是否为 Docker 主机的 IP

注意:不是相应的 Docker 容器的 IP,而是宿主机的IP,因为是通过宿主机的端口映射到容器的端口上的

如果不是则需要在修改后重新对项目进行 package 打包,然后再次将打包后的 jar 包上传到 Linux 系统的"/root/ssrm" 项目目录中

在这里插入图片描述

(2).构建应用镜像

构建镜像

docker build -t finance:1.0 .

在这里插入图片描述

此时便可查看到该新创建出的镜像

docker images

在这里插入图片描述

(3).启动容器
docker run --name myapp \
-v /root/myapp/log:/var/applogs \
-dp 9000:8080 finance:1.0

在这里插入图片描述

此时已经启动了三个容器

docker ps

在这里插入图片描述

(4).访问应用
  • 页面访问

    http://192.168.1.11:9000/

    在这里插入图片描述

  • 查看 Redis

    此时查看 Redis,可以看到新增的缓存

    [root@docker ssrm]# docker exec -it myredis /bin/bash
    root@6ced4e608fb9:/data#
    root@6ced4e608fb9:/data# redis-cli
    127.0.0.1:6379>
    127.0.0.1:6379> keys *
    

    在这里插入图片描述

  • 查看日志

    此时查看数据卷/root/myapp/log 中的日志文件 finance.log

    cat  /root/myapp/log/finance.log 
    

    在这里插入图片描述

2.Compose 编排启动项目

手工启动项目不仅繁琐易错,而且还存在一个致命问题:当前应用访问的 mysql 与 redis只能是运行在当前 Docker 宿主机之上的,否则将无法访问到它们

因为在应用的配置文件中已经将 mysql 与 redis 的 IP 进行了硬编码,而使用 Docker Compose 可以解决所有问题

(1).定义 compose.yml

在"/root/ssrm"目录中新建一个文件 compose.yml

[root@docker ~]# vim /root/ssrm/compose.yml

services:
  myapp: #指定app包的位置在当前compose.yml同级目录
    build: ./
    container_name: myapp #指定app容器的名字
    ports:
      - 9000:8080 #指定app容器的端口号,将宿主机的9000端口映射到容器的8080端口
    volumes:
      - ./logs:/var/applogs #指定app的日志目录的挂载点为app包所在目录下的logs目录
    depends_on: #执行依赖的服务,在指定的服务启动后再启动app服务
      - mysql
      - redis
  mysql:
    image: mysql:8.0.32 #执行镜像
    environment:
      - "MYSQL_ROOT_PASSWORD=root" #设置root用户密码
    ports:
      - 3306:3306 #指定对外暴露的端口
    volumes: #执行数据卷
      - /root/ssrm/mysql/log:/var/log/mysql
      - /root/ssrm/mysql/data:/var/lib/mysql
      - /root/ssrm/mysql/conf:/etc/mysql/conf.d
  redis:
    image: redis:7.0
    ports:
      - 6379:6379
    volumes:
      - /root/ssrm/redis/redis.conf:/etc/redis/redis.conf
      - /root/ssrm/redis/data:/data
    command: redis-server /etc/redis/redis.conf

在这里插入图片描述

(2).修改应用

对于应用程序需要修改其配置文件 application.yml,将 mysql 与 redis 的主机名修改为它们相应服务的名称

在这里插入图片描述

(3).上传文件

由于应用程序的配置文件发生了变化,所以需要对应用程序重新进行 package 打包,并将新的 jar 包上传到 Linux 系统中的"/root/ssrm"目录中

在这里插入图片描述

将redis.conf文件上传到"/root/ssrm/redis/"目录下

mkdir -p /root/ssrm/redis

在这里插入图片描述

(4).启动所有容器

cd /root/ssrm/

docker-compose up -d

在这里插入图片描述

查看容器

docker ps

在这里插入图片描述

(5).写入 mysql 数据

  1. 进入 mysq

    docker exec -it  ssrm-mysql-1 /bin/bash  
    
    mysql -uroot -p
    

    在这里插入图片描述

  2. 准备数据

    复制前面的 sql 文件中的内容,直接粘贴到 mysql 命令行即可

    show databases;
    
    create database if not exists test;
    
    use test;
    
    drop table if exists product;
    
    CREATE TABLE IF NOT EXISTS `product`(
       `id` INT(11) not null AUTO_INCREMENT,
       `name` VARCHAR(100) default NULL,
       `rate` double default NULL,
       `amount` double default NULL,
       `raised` double default NULL,
       `cycle` int(11) default NULL,
       `endTime` char(10) default '0',
       PRIMARY KEY ( `id` )
    )ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    insert into product(id,name,rate,amount,raised,cycle,endTime)values(1,'TXTY',2.76,50000,20000,6,'2020-10-10');
    insert into product(id,name,rate,amount,raised,cycle,endTime)values(2,'JULY',3.31,20000,40000,7,'2021-11-11');
    insert into product(id,name,rate,amount,raised,cycle,endTime)values(3,'LUCY',1.09,2456,4537,3,'2011-11-11');
    insert into product(id,name,rate,amount,raised,cycle,endTime)values(4,'TOM' ,8.09,8976,3456,4,'2031-11-11');
    
    SHOW TABLES;
    
    select * from product;
    

    在这里插入图片描述

  3. 访问应用

    与前面手工启动项目的访问方式相同

    192.168.1.11:9000

    在这里插入图片描述

3.指定各组件名称

前面的 compose.yml 文件中应用生成的镜像采用的是默认名称

mysql 与 redis 生成的容器名称采用的是默认名称,生成并加入的 bridge 网络也称默认名称的网络

这些组件的所使用的默认名称也可以被指定名称所代替

(1).定义 compose2.yml

[root@docker ssrm]# vim /root/ssrm/compose2.yml

services:
  myapp: #指定app包的位置在当前compose.yml同级目录
    build: ./
    container_name: someapp #指定app容器的名字
    image: finance:2.0
    ports:
      - 9000:8080 #指定app容器的端口号,将宿主机的9000端口映射到容器的8080端口
    volumes:
      - ./logs:/var/applogs #指定app的日志目录的挂载点为app包所在目录下的logs目录
    networks:
      - ab
    depends_on: #执行依赖的服务,在指定的服务启动后再启动app服务
      - mysql
      - redis
  mysql:
    image: mysql:8.0.32 #执行镜像
    container_name: somemysql
    environment:
      - "MYSQL_ROOT_PASSWORD=root" #设置root用户密码
    ports:
      - 3306:3306 #指定对外暴露的端口
    networks:
      - ab
    volumes: #执行数据卷
      - /root/ssrm/mysql/log:/var/log/mysql
      - /root/ssrm/mysql/data:/var/lib/mysql
      - /root/ssrm/mysql/conf:/etc/mysql/conf.d
  redis:
    image: redis:7.0
    container_name: someredis
    ports:
      - 6379:6379
    networks:
      - ab
    volumes:
      - /root/ssrm/redis/redis.conf:/etc/redis/redis.conf
      - /root/ssrm/redis/data:/data
    command: redis-server /etc/redis/redis.conf
networks:
  ab:

在这里插入图片描述

(2).启动所有容器

这里通过-f 选项指定要使用的 compose 文件

[root@docker ssrm]# docker rm -f $(docker ps -qa)

[root@docker ssrm]# docker-compose -f /root/ssrm/compose2.yml up -d

在这里插入图片描述

(3).查看容器

查看容器可以看到容器名称为指定的名称

在这里插入图片描述

(4).查看网络

此时查看网络可以看到又新生成一个网络

对于生成的网络其生成的名称为"当前compose 文件所在目录名_ networks 下的第一级属性"

docker network ls

在这里插入图片描述

(5).查看网络详情

通过"docker network inspect ssrm_ab"命令查看该网络的详情

可以看到compose中定义的三个服务容器都在该网络中

docker network inspect ssrm_ab

在这里插入图片描述

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐