手把手带你入门 Docker Compose

前言

在上一篇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-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 [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 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

发布了138 篇原创文章 · 获赞 523 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/ljk126wy/article/details/104307924