手把手带你入门 Docker Compose

手把手带你入门 Docker Compose_第1张图片

前言

在上一篇Docker入门介绍 不搞虚的!快速把你拉入Docker 的门里 博客中介绍了如何将 SpringBoot 项目 Docker化。这篇博客将继续带你了解 Docker Compose 用法,通过本文你将了解到如下内容:

  1. 什么是 Docker Compose
  2. Docker Compose 运行 SpringBoot 项目
  3. Docker Compose 运行 SpringBoot + 数据库项目
  4. 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 Compose_第2张图片

  • docker-compse stop:停止YML配置的所有服务
  • docker-compose kill:强行停止YML配置的所有服务

我的机器执行 docker-compse stop 一直是执行中。然后在执行docker-compose ps
也卡住了。可能是我的机器配置差的原因。直接执行 docker-compose kill 很快速的关闭掉容器。

第四步:通过 ipconfig 查看 demo 容器的 ip
手把手带你入门 Docker Compose_第3张图片

第五步:通过游览器 输入demo容器 ip 访问运行SpringBoot的项目。
手把手带你入门 Docker Compose_第4张图片
到这里 Docker Compose 运行 SpringBoot 项目 操作完毕!接下来开始介绍如何使 demo项目连接上容器启动的MySql操作。

demo项目连接 MySql 容器

拉取MySql 的 Docker 镜像

访问 https://hub.docker.com/ 搜索 MySql 的镜像。
手把手带你入门 Docker Compose_第5张图片
手把手带你入门 Docker Compose_第6张图片
通过docker pull mysql:5.6 下载 mysql 镜像,如下图所示:
在这里插入图片描述
通过docker images 查看 已经拉取的MySql 镜像。
手把手带你入门 Docker Compose_第7张图片

通过 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 连接容器数据库,具体操作如下图:
手把手带你入门 Docker Compose_第8张图片
连接成功后将如下内容复制到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 */;

手把手带你入门 Docker Compose_第9张图片
通过游览器访问 SpringBoot 项目获取ID 为1的用户信息。
手把手带你入门 Docker Compose_第10张图片

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 [email protected]

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 Compose_第11张图片
启动过程中遇到问题

重新开机通过 Docker Compse 启动报 network 65a11537 not found 的错误。

通过执行 docker-compose down 后然后重新执行 docker-compose up -d 解决问题。
具体解决方案参考:https://github.com/docker/for-win/issues/2194

小结

Docker Compose 使用需要如下步骤:

  1. 通过 Dockerfile 将应用程序 Docker化,对于基础服务可以直接拉取现有的镜像。例如 MySql、redis 这样的服务。
  2. 在 docker-compose.yml 定义需要一起运行的服务以及他们之间依赖、启动顺序端口号等,服务就是我们需要启动的应用程序。
  3. 最后,执行 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

你可能感兴趣的:(Docker)