前言
在上一篇Docker入门介绍 不搞虚的!快速把你拉入Docker 的门里 博客中介绍了如何将 SpringBoot 项目 Docker化。这篇博客将继续带你了解 Docker Compose 用法,通过本文你将了解到如下内容:
- 什么是 Docker Compose
- Docker Compose 运行 SpringBoot 项目
- Docker Compose 运行 SpringBoot + 数据库项目
- Docker Compose 启动 2个SprignBoot 项目并互相调用
需要注意的是文章中的操作是在Windows操作下执行,并且本文是 不搞虚的!快速把你拉入Docker 的门里 博客 的下篇,阅读前请先阅读 不搞虚的!快速把你拉入Docker 的门里 。
什么是 Docker Compose
通过 Docker 可以将 Web 项目变成 Docker 应用程序,但是如果有多个Docker 应用程序的话,就需要我们手动一个一个去启动。而 Docker Compose 可以帮助我们定义和运行多个容器 Docker 应用程序的工具。
通过 YML 文件来配置应用程序需要的所有服务。然后使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
实战操作
Docker Compose 运行 SpringBoot 项目
第一步:在 demo 项目中新建 docker-compose.yml 文件,然后添加如下内容:
version: '3'
services:
demo:
image: demo:latest
ports:
- 8080:8080
- version: ‘3’ Docker Compose 版本
- services: demo: image: demo:latest 配置服务名称以及启动依赖的镜像
- ports:配置镜像对外映射的端口号。
第二步:进入docker-compose.yml 文件夹下执行 docker-compose up -d 启动 demo 服务。如下图所示表示启动成功!
- docker-compose up:启动YML 配置的应用程序
- -d:后台运行
第三步:通过docker ps 或者 docker-compose ps demo 查看启动的容器。
docker-compose ps 是查看所有启动的容器
通过 docker-compose logs 服务名称:查看具体服务的输出日志信息。
- docker-compse stop:停止YML配置的所有服务
- docker-compose kill:强行停止YML配置的所有服务
我的机器执行 docker-compse stop 一直是执行中。然后在执行docker-compose ps
也卡住了。可能是我的机器配置差的原因。直接执行 docker-compose kill 很快速的关闭掉容器。
第四步:通过 ipconfig 查看 demo 容器的 ip
第五步:通过游览器 输入demo容器 ip 访问运行SpringBoot的项目。
到这里 Docker Compose 运行 SpringBoot 项目 操作完毕!接下来开始介绍如何使 demo项目连接上容器启动的MySql操作。
demo项目连接 MySql 容器
拉取MySql 的 Docker 镜像
访问 https://hub.docker.com/ 搜索 MySql 的镜像。
通过docker pull mysql:5.6 下载 mysql 镜像,如下图所示:
通过docker images 查看 已经拉取的MySql 镜像。
通过
docker run -itd --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 mysql
可以启动 一个运行中的MySql 容器,具体操作这里就不在进行演示。
SpirngBoot 项目接入MySql 数据库并编写测试程序
第一步引入:MySql starter 以及数据库驱动的依赖。具体代码如下:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
第二步:添加数据库源相关配置在 application.properties 中。
spring.datasource.url=jdbc:mysql://mysql:3306/demo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
需要注意的是 jdbc:mysql://mysql:3306/demo 这行配置中 mysql 是在 docker-compose.yml 中配置的服务名称。
第三步:添加获取用户表数据的Mapper类,具体内容如下:
package cn.zhuoqianmingyue.demo.mapper;
import cn.zhuoqianmingyue.demo.model.User;
import org.apache.ibatis.annotations.*;
@Mapper
public interface UserMapper {
@Results(id="user" ,value= {
@Result(property = "id", column = "id", id = true),
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age")
})
@Select("select * from user where id = #{id}")
public User findById(@Param("id") Long id);
}
第四步:添加用于测试获取用户信息的 Controller API,具体代码如下:
package cn.zhuoqianmingyue.demo.controller;
import cn.zhuoqianmingyue.demo.mapper.UserMapper;
import cn.zhuoqianmingyue.demo.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserMapper userMapper;
@GetMapping("/{id}")
public ResponseEntity<User> findById(@PathVariable(name = "id") Long id){
User user = userMapper.findById(id);
return ResponseEntity.ok(user);
}
}
Docker Compose 配置 MySql 服务
第一步:在 docker-compose.yml 文件中添加 MySql服务的相关配置,具体内容如下:
version: '3'
services:
demo:
image: demo:latest
ports:
- 8080:8080
depends_on:
- mysql
mysql:
image: mysql:5.6
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
restart: always
environment:环境变量的配置
MYSQL_ROOT_PASSWORD:配置连接数据的密码
MYSQL_ROOT_HOST:配置允许用户登录所使用的IP ‘%’(通配符):表示所有IP都有连接权限。
restart: 重启策略
- no:是默认的重启策略,在任何情况下都不会重启容器。
- always:容器总是重新启动。
- on-failure:在容器非正常退出时(退出状态非0),才会重启容器。
- unless-stopped:在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就 - 已经停止了的容器
第二步:通过 docker-compose up -d 启动 SpringBoot 项目和 MySql服务。如下图所示表示启动成功。
需要注意的是启动前需要通过docker ps 命令查看正在运行 demo项目容器 ID, 然后通过 docker rm -f demo项目容器 ID 将容器删除掉在执行 docker-compose up -d
第三步:连接 MySql 服务 并添加数据库和用户表以及用户表数据。
通过 SQLyong 连接容器数据库,具体操作如下图:
连接成功后将如下内容复制到SQLyong 工具中执行,具体内容如下:
/*
SQLyog Ultimate v9.62
MySQL - 5.5.53 : Database - demo
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`demo` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `demo`;
/*Table structure for table `user` */
CREATE TABLE `user` (
`id` bigint(16) NOT NULL AUTO_INCREMENT,
`name` varchar(52) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
insert into `user`(`id`,`name`,`age`) values (1,'zymy',18);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
通过游览器访问 SpringBoot 项目获取ID 为1的用户信息。
Docker Compose 启动 2个SprignBoot 项目并互相调用
搭建被调用的 SpringBoot 项目 demo2
第一步:创建 一个名称为 demo2 的SpringBoot 项目,具体操作请参考:快速把你拉入Docker 的门里 博客。
第二步:编写用于测试的Controller,具体代码如下:
package cn.zhuoqianmingyue.demo.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloDockerController {
@GetMapping("/hello")
public String hello(){
return "demo2 hello docker!";
}
}
将 demo2 项目 Docker 化
将SpringBoot 项目Docker 化的操作请参考:快速把你拉入Docker 的门里 博客。
将 demo2 项目Docker 化的 Dockerfile 文件内容如下:
#代表我们自定义的镜像基于 java:8镜像创建。
FROM java:8
#代表我们自定义的镜像基于 java:8镜像创建。
MAINTAINER zhuoqianmingyue ljk126wy@126.com
COPY target/demo2.jar /demo2.jar
ENTRYPOINT ["java", "-jar", "/demo2.jar"]
构建demo2项目镜像的脚本内容如下:
#!/usr/bin/env bash
mvn package
docker build -t demo2:latest .
编写 demo调用demo2项目的代码并通过 Docker Compose 启动
这里通过 demo 项目调用 demo2项目中 HelloDockerController 中的Get 请求API,调用通过 RestTemplate 来实现。
首先定义RestTemplate Config 类,其作用就是将 RestTemplate 注入到Spring的上下文中。
package cn.zhuoqianmingyue.demo.config;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestConfig {
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder){
return builder.build();
}
}
在 application.properties 配置文件中添加 demo2 项目的ip 和端口号,具体代码如下:
demo2.server.ip=demo2
demo2.server.port=8090
需要注意的是 demo2.server.ip=demo2 这行配置中 demo2 是 Docker Compose
YML 配置文件中的服务名称。
在demo项目中的 HelloDockerController 中编写通过 RestTemplate 调用 demo2 项目的方法,具体代码如下:
package cn.zhuoqianmingyue.demo.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class HelloDockerController {
@Value("${demo2.server.ip}")
private String demo2ServerIp;
@Value("${demo2.server.port}")
private String demo2ServerPort;
@Autowired
private RestTemplate restTemplate;
@GetMapping("/hello2")
public String hell2(){
String message = restTemplate.getForObject("http://"+demo2ServerIp+":"+demo2ServerPort+"/hello"
, String.class);
return message;
}
}
在 docker-compose.yml 中添加 demo2 服务,并通过 links: 配置 demo 项目需要依赖 demo2服务。具体配置内容如下:
version: '3'
services:
demo2:
image: demo2:latest
ports:
- 8090:8090
demo:
image: demo:latest
ports:
- 8080:8080
depends_on:
- mysql
links:
- demo2
mysql:
image: mysql:5.6
ports:
- 3306:3306
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_ROOT_HOST: '%'
restart: always
- links:可以使用服务别名进行访问,而非固定的ip。因为容器的ip是不固定的。
- depends_on:和links 功能一样,不多它可以设置一个依赖关系,如下面的代码表示先启动 mysql 在启动 demo2 最后启动 demo项目。
需要注意的是启动和准备就绪是两个概念 ,启动并不意味着一定就启动完成,它只是表示先启动谁后启动谁。不是 mysql 启动完成后再启动demo2 。
image: demo:latest ports: - 8080:8080 depends_on: - mysql - demo2 ```
最后通过 docker-compose up -d 启动 demo、demo2、MySql 三个容器,如下图所示表示启动成功。
通过游览器访问 demo 调用 demo2项目的 api,具体效果如下图所示:
启动过程中遇到问题
重新开机通过 Docker Compse 启动报 network 65a11537 not found 的错误。
通过执行 docker-compose down 后然后重新执行 docker-compose up -d 解决问题。
具体解决方案参考:https://github.com/docker/for-win/issues/2194
小结
Docker Compose 使用需要如下步骤:
- 通过 Dockerfile 将应用程序 Docker化,对于基础服务可以直接拉取现有的镜像。例如 MySql、redis 这样的服务。
- 在 docker-compose.yml 定义需要一起运行的服务以及他们之间依赖、启动顺序端口号等,服务就是我们需要启动的应用程序。
- 最后,执行 docker-compose 命令来启动、停止、重启所有的应用程序服务。
参考文献
https://www.linuxea.com/2299.html
https://www.runoob.com/docker/docker-compose.html
https://docs.docker.com/compose/
https://docs.docker.com/compose/completion/
https://github.com/docker/compose
https://github.com/docker/docker.github.io/blob/master/compose/reference/index.md
转载:https://blog.csdn.net/ljk126wy/article/details/104307924