第9章 Docker Compose
对于现代应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。例如,订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应用。而部署和管理大量的服务容器是一件非常繁琐的事情。而 Docker Compose 就是解决这类问题的。
1. 简介
Docker Compose 是一个需要在 Docker 主机上进行安装的 Docker 容器编排外部工具。其并不是通过脚本或各种冗长的 Docker 命令来将应用组件组织起来,而是通过一个声明式的配置文件描述整个应用,然后通过一条命令完成应用部署。部署成功后,还可通过一系列简单命令实现对其完整生命周期的管理。
Docker Compose 的前身是 Fig(无花果)。
2. compose 文件
2.1 文件简介
Docker Compose 使用 YAML 文件来定义服务。官方推荐的默认文件名为 compose.yml ,但同时也支持 docker-compose.yml。
由于一个 compose 文件中定义的为一个项目的所有服务,所以一般为在创建 compose文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile 放入该目录,并在该目录中新建 compose 文件。
compose 文件中包含 6 个顶级属性:version、services、networks、volumes、configs 与secrets,及很多的它们下面所包含的属性。下面简单介绍一下常用的属性。
2.2 version
version 是一个顶级属性,但已经过时,不再需要在 compose 文件中出现了。从以下官网说明中可以看出。

2.3 networks
networks 作为一个顶级属性,用于定义和创建应用中所使用到的所有网络。其下包含的第一级属性即为网络名称,这个网络名称可以随意命名。而在网络名称下还可包含很多的属性,常用属性如下:
services:
app:
networks:
- app_bridge: #这里使用的并不是网络名称
networks:
app_bridge:
name: appBGnet # 这才是网络名称
driver: bridg
2.3.1 name
networks 下的第一级属性—网络名称,并不是真正的网络名称,而仅仅是网络名称的一部分。在真正生成网络后,其真正的网络名称格式为:当前 compose 文件所在目录名_networks 下的第一级属性。
但如果设置了 name 属性,则网络名称即为这里指定的名称,不会出现名称再合成情况
2.3.2 driver
用于指定网络驱动,缺省驱动为 Bridge。
2.3.3 attachable
如果该属性设置为 true,则除了当前 compose 中定义的服务外,其它独立容器也可以连接到此网络,并能与该网络中的服务及也连接到该网络的其它独立容器通信。缺省状态为false。
2.4 volumes
volumes 作为一个顶级属性,用于定义和创建应用中所使用到的所有 volume。其下包含的第一级属性即为 volume 的卷标,这个卷标可以随意命名。这个卷标所代表的是当前 Docker主机中的目录,至于该目录的具体位置,是由系统自动分配的。
在网络名称下还可包含很多的属性,但这些属性并不常用,所以这里不进行介绍了
2.5 services
services 是一个顶级属性,用于定义一个应用中所包含的服务。Docker Compose 会将每个服务部署在各自的容器中。其下包含的第一级的属性即为服务名称,这个名称可以根据服务内容随意命名。而在服务名称下还可包含很多的属性,常用属性如下:
2.5.1 build
用于指定一个 Dockerfile 的路径。而该 Dockerfile 则是用于创建当前服务镜像的。这个路径可以是以斜杠(/)开头的绝对路径,也可以是相对于当前 compose 文件的、以点(.)号开头的相对路径
如果 Dockerfile 文件名不是默认名称,则需要通过 build 下的 context 属性指定路径,dockerfile 属性指定文件名。
build:
context: ./
dockerfile: myDockerfil
5.2.2 image
用户指定当前服务所需要使用的镜像,这个镜像可以是本地镜像,也可以是远程镜像仓库中的镜像(会自动 pull)。
如果设置了 build,此时再设置的 image 属性即为构建出的镜像的名称与 Tag。
5.2.3 container_name
该属性用于设置容器名称,但并不是必须的。如果没有设置该属性,容器名称则会采用“合成方式”。而合成时需要用到 services 下的第一级属性。在 services 下存在一级属性,称为服务名称。该级属性是作为 services 下的第一级属性出现的。服务名称将来会作为容器名称的一部分出现。容器的名称格式为:当前 compose文件所在目录名_ 服务名称。如果在 services 下没有指定 image 属性,而是使用 build 属性,即没有现成的镜像,而是根据 build 下指定的 Dockerfile 生成镜像,此时生成的镜像名称格式为:当前 compose 文件所在目录名-服务名称。
5.2.4 ports
一个列表。前面为暴露出的端口号,后面为容器中应用的端口号。如果仅设置了一个端口号,那么这个端口号是容器中应用的端口号,其暴露到宿主机的端口号会被随机分配
ports:
- 80:80 # 绑定容器的 80 端口到主机的 80 端口
- 9000:80 # 绑定容器的 80 端口到主机的 9000 端口
- 443 # 绑定容器的 443 端口到主机的任意端口,容器启动时随机分配绑定的主机端口号
5.2.5 command
用于覆盖 Dockerfile 中的 CMD 指令内容,即启动该服务容器后立即运行的命令。如果直接按照 Dockerfile 中的 CMD 指令内容执行即可,则 compose 文件中无需该 command 属性。
5.2.6 depends_on
一个列表。用于指定当前服务的启动所依赖的应用名称。即列表中指定的服务会先于当前服务启动。
5.2.7 deploy
用于指定当前服务容器的部署设置。其下有一个常用属性 replicas,用于指定该服务启动的容器的数量。即实现一个服务多个容器。一旦指定了 deploy:replicas,就不能再指定container_name 属性了。因为各个启动的容器名称不能相同,而只能由系统自动生成。
services:
frontend:
image: awesome/webapp
deploy:
mode: replicated
replicas: 6
2.5.8 networks
用于指定当前服务容器要连接到的网络。该网络必须是已经存在的,或通过顶级属性networks 创建的网络。
2.5.9 volumes
用于指定当前服务容器所使用到的所有 volume。这些 volume 可以使用路径与卷标两种方式。
例如,下面是路径方式,非常直观,易于查看,但需要管理本地路径。
db:
image: mariadb:latest
ports:
- "3306:3306"
volumes:
- /etc/mysql:/var/lib/mysql
再如,下面是卷标方式,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:
3. 常用命令
Docker Compose 通过 docker-compose 系列命令查看和控制 compose 中的所有服务容器。
docker-compose pull
拉取
compose中服务依赖的全部镜像或指定镜像。通过在命令后添加服务名称来指定。docker-compose config
检查
compose文件是否正确。可添加选项-q,表示只有存在问题时才有输出。docker-compose up
启动
compose中的所有容器。-d选项表示后台启动。docker-compose logs
查看
comopse中所有服务或指定服务的运行日志。通过在命令后添加服务名称来指定。默认情况下,将对不同的服务日志使用不同的颜色来区分。docker-compose ps
列出
compose中所有服务或指定服务。通过在命令后添加服务名称来指定。docker-compose top
列出
compose中当前正在运行的所有服务或指定服务。通过在命令后添加服务名称来指定。docker-compose images
列出
compose中所有服务或指定服务对应的镜像。通过在命令后添加服务名称来指定。docker-compose port
列出指定服务容器的指定端口所映射的宿主机端口。
docker-compose run
在指定服务上执行一条命令。
docker-compose exec
进入指定服务容器。通过在命令后添加服务名称来指定。
docker-compose pause
暂停
compose中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。docker-compose unpause
恢复
compose中处于暂停状态的所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。docker-compose stop
停止
compose中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。docker-compose restart
重启
compose中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。docker-compose start
启动
compose中所有服务容器或指定服务容器。通过在命令后添加服务名称来指定。docker-compose kill
通过发送
SIGKILL信号停止指定服务的容器。docker-compose rm
删除
compose中的处于停止状态的所有服务容器或指定服务容器。通过在命令后添
加服务名称来指定。docker-compose down
停止并删除
compose中的所有服务容器、网络、镜像、数据卷。
4. 安装
4.1 下载安装包

curl -SL https://github.com/docker/compose/releases/download/v2.17.3/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose

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

这个过程会比较慢。前面几次可能就无法开始下载,多尝试几次。
4.2 添加可执行权限
为 docker-compose 文件添加可执行权限。

4.3 测试
通过 docker-compose version 测试安装是否成功。

5. 项目构建
5.1 项目代码
5.1.1 功能描述
这是一个金融产品交易平台中的部分功能,是一个 Spring Boot 工程。控制器具有三个接口:查询所有产品、根据产品名称查询、上线新产品。整个架构包含一个 Redis 与 MySQL服务器。
5.1.2 依赖
<?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.5.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.docker-compose</groupId>
<artifactId>docker-compose</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>docker-compose</name>
<description>docker-compose</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mybatis-plus与 spring boot整合依赖-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- druid驱动 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
<!--tomcat内置的 JSP解析器-->
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
</dependency>
<!--jstl依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
5.1.3 sql文件
以下是生成 product 表及相应数据的 SQL 文件内容。
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');
运行MySQL用docker容器来运行。
docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=111 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/log:/var/log/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-dp 3306:3306 \
mysql:5.7

5.1.4 实体类
package generator.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.io.Serializable;
import lombok.Data;
/**
*
* @TableName product
*/
@TableName(value ="product")
@Data
public class Product implements Serializable {
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 产品名称
*/
private String name;
/**
* 年化利率
*/
private Double rate;
/**
* 募集总额
*/
private Double amount;
/**
* 已募集金额
*/
private Double raised;
/**
* 产品周期
*/
private Integer cycle;
/**
* 产品募集结束时间
*/
private String endtime;
@TableField(exist = false)
private static final long serialVersionUID = 1L;
}
5.1.5 ProductMapper 接口
public interface ProductMapper extends BaseMapper<Product> {
}
5.1.6 ProductService接口
public interface ProductService extends IService<Product> {
}
5.1.7 ProductServiceImpl实现类
@Service
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product>
implements ProductService {
}
5.1.8 ProductControlle 类
package com.dockercompose.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.dockercompose.pojo.Product;
import com.dockercompose.service.ProductService;
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 javax.annotation.Resource;
import javax.sound.sampled.Port;
import java.util.List;
/**
* @author 念心卓
* @version 1.0
* @description: TODO
* @date 2023/5/14 17:19
*/
@RestController
public class ProductController {
@Resource
private ProductService productService;
/**
* 查询所有商品
* @return
*/
@GetMapping("/")
public List<Product> getAllProduct(){
return productService.list();
}
/**
* 上架新商品
* @param product 商品对象
* @return
*/
@PostMapping("/register")
public String registerProduct(@RequestBody Product product){
return productService.save(product) ? "save success" : "save failure";
}
/**
* 根据商品名称查询商品
* @param name 商品名称
* @return
*/
@GetMapping("/list")
public List<Product> getProductByName(String name){
LambdaQueryWrapper<Product> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(Product::getName,name);
return productService.list(queryWrapper);
}
}
5.1.9 配置文件
server:
port: 9000
#数据库设置
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource #指定类型为德鲁伊连接池
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.254.131/test?useUnicode=true&characterEncoding=utf-8
username: root
password: 111
#redis配置
redis:
host: 192.168.254.131
#配置logback日志控制
logging:
#指定日志在输出到控制台的同时也输出到指定文件
file:
name: "/var/applogs/finance.log"
pattern:
#指定日志输出格式
console: level-%-5level - %msg%n
file: level-%-5level - %msg%n
#设置日志显示级别
level:
root: warn #项目启动日志级别
5.1.10 启动类
package com.dockercompose;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
@SpringBootApplication
@MapperScan("com/dockercompose/mapper")
public class DockerComposeApplication {
public static void main(String[] args) {
SpringApplication.run(DockerComposeApplication.class, args);
}
}
5.1.11 项目整体结构

5.2 定义Dockerfile
在 Docker 主机的任意目录中新建一个目录,该新建目录名称与项目名称相同。这里在/root 目录中 mkdir 一个名称为 docker-compose的目录。然后在该目录中新建 Dockerfile 文件。
在编写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 命令最后一个参数指定的上下文路径
#这里第一个dc.jar是我重命名之后的
COPY dc.jar dc.jar
# 一定要执行的 exec
ENTRYPOINT ["java", "-jar", "dc.jar"]
EXPOSE 9000 #可有可无
5.3 项目打包上传

将打包好的jar包上传到Linux中

6. 手工启动项目
为了与使用 Docker Compose 编排项目进行对比,体现 Docker Compose 的方便快捷,这里先使用纯手工方式启动项目。
6.1 启动MySQL容器
docker run --name mysql \
-e MYSQL_ROOT_PASSWORD=111 \
-v /root/mysql/data:/var/lib/mysql \
-v /root/mysql/log:/var/log/mysql \
-v /root/mysql/conf:/etc/mysql/conf.d \
-dp 3306:3306 \
mysql:5.7
6.1.2 进入 MySQL
docker exec -it mysql bash
mysql -uroot -p

6.1.3 准备数据
复制前面的 sql 文件中的内容,直接粘贴到 MySQL 命令行即可。
注意:此步骤前面我以及给出了截图,可以在本章
5.1.3 sql文件这一节查看

6.2 启动redis容器
docker run --name myredis \
-v /root/redis/redis.conf:/etc/redis/redis.conf \
-v /root/redis/data:/data \
-dp 6379:6379 \
redis:latest \
redis-server /etc/redis/redis.conf

6.3 启动应用程序
6.3.1 检查应用配置文件
在构建应用镜像之前,打开项目的配置文件,再次确认配置文件中指定的 mysql 与 redis主机的 IP 地址是否为 Docker 主机的 IP。注意,不是相应的 Docker 容器的 IP。如果不是,在修改后需要重新对项目进行 package 打包。然后再次将打包后的 jar 包上传到 Linux 系统的docker-compose项目目录中。

6.3.2 构建应用镜像

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

6.3.3 启动容器
docker run --name myapp \
-v /root/myapp/log:/var/applogs \
-dp 9000:9000 dc:1.0 #因为spring boot的启动程序是9000端口,所以第二个端口也要为9000,第一个9000端口为暴露给外部的端口

此时已经启动了三个容器。
6.4 访问应用
6.4.1 页面访问


6.4.2 提交 POST 请求
通过 Postman提交 Post 请求。


7. Compose 编排启动项目
手工启动项目不仅繁琐易错,而且还存在一个致命问题:当前应用访问的 mysql 与 redis只能是运行在当前 Docker 宿主机之上的,否则将无法访问到它们。因为在应用的配置文件中已经将 mysql 与 redis 的 IP 进行了硬编码。而使用 Docker Compose 可以解决所有问题。
7.1 定义compose.yml
在 docker-compose目录中新建一个文件 compose.yml
services:
nxzapp: #app表示服务名称
build: ./
container_name: myapp #生成的容器名称
ports:
- 9000:9000
volumes:
- ./logs:/var/applogs
depends_on: #先启动下面两个服务
- nxzmysql
- nxzredis
nxzmysql:
image: mysql:5.7 #指定MySQL的镜像
environment: #设置环境
MYSQL_ROOT_PASSWORD: 111
ports:
- 3306:3306
volumes:
- /root/mysql/log:/var/log/mysql
- /root/mysql/data:/var/lib/mysql
- /root/mysql/conf:/etc/mysql/conf.d
nxzredis:
image: redis:latest
ports:
- 6379:6379
volumes:
- /root/redis/redis.conf:/etc/redis/redis.conf
- /root/redis/data:/data
command: redis-server /etc/redis/redis.conf

编写完了输入命令查看是否有错
docker-compose config -q
7.2 修改应用
7.2.1 修改配置文件
对于应用程序,需要修改其配置文件 application.yml。将 mysql 与 redis 的主机名修改为它们相应服务的名称。

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

7.3 启动所有容器
在重启所有容器之前,修改
Dockerfile文件(如果你的jar包更换其他名字的话)。




启动所有容器,-d表示后台启动

注意看容器的名称,格式:
目录名称-应用名称-1

并且可以发现多了一个网络。
7.4 写入MySQL数据
7.4.1 进入MySQL

7.4.2 准备数据
复制前面的 sql 文件中的内容,直接粘贴到 mysql 命令行即可。
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');


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

7.6 指定各组件名称
前面的compose.yml文件中应用生成的镜像采用的是默认名称,mysql 与 redis 生成的容器名称采用的是默认名称,生成并加入的 bridge 网络也称默认名称的网络。这些组件的所使用的默认名称,也可以被指定名称所代替。
7.6.1 定义 compose2.yml
services:
nxzapp: #app表示服务名称
build: ./
container_name: someapp #生成的容器名称
image: dc:1.0
ports:
- 9000:9000
volumes:
- ./logs:/var/applogs
networks:
- ab
depends_on: #先启动下面两个服务
- nxzmysql
- nxzredis
nxzmysql:
image: mysql:5.7 #指定MySQL的镜像
container_name: somemysql #生成的容器名称
environment: #设置环境
MYSQL_ROOT_PASSWORD: 111
ports:
- 3306:3306
volumes:
- /root/mysql/log:/var/log/mysql
- /root/mysql/data:/var/lib/mysql
- /root/mysql/conf:/etc/mysql/conf.d
networks:
- ab
nxzredis:
image: redis:latest
container_name: someredis #生成的容器名称
ports:
- 6379:6379
volumes:
- /root/redis/redis.conf:/etc/redis/redis.conf
- /root/redis/data:/data
networks:
- ab
command: redis-server /etc/redis/redis.conf
networks:
ab:

7.6.2 启动所有容器
这里通过-f 选项指定要使用的 compose 文件。

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

7.6.4 查看网络
此时查看网络可以看到,又新生成一个网络。对于生成的网络,其生成的名称为“当前compose 文件所在目录名_networks 下的第一级属性”。

7.6.5 查看网络详情

