docker-compose(二):SpringBoot + Docker Compose

原文地址:http://www.linzichen.cn/article/1597479427321626624

在上篇 docker-compose(一):SpringBoot + Docker 案例 一文中,通过一个简单的 SpringBoot 项目整合了基于容器运行的 mysql 和 redis,并通过 nginx 做了接口的代理转发。在运维方面,其实是存在几个痛点的:

  • 容器启动的先后顺序要求固定,SpringBoot 容器启动一定要在其所依赖的容器启动完成后,方可启动。
  • 多个容器,需要执行多条 run 命令。
  • 作为一个整体项目,各个容器之间没有被统一编排,统一管理。

针对以上问题,我们可以使用 Docker 官方的开源项目 docker compose 来实现对 Docker 容器集群的快速编排。

简介

Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 OpenStack 中的 Heat 十分类似。

其代码目前在 https://github.com/docker/compose 上开源。

Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。

我们知道使用一个 Dockerfile 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。

Compose 恰好满足了这样的需求。它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。

Compose 中有两个重要的概念:

  • 服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
  • 项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。

Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。

Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose 来进行编排管理。

安装卸载

官方下载地址:https://docs.docker.com/compose/install/

在官方页面中,我们选择安装独立版本的 docker compose【Install the Compose standalone】

install.png

第一步:

根据页面上的链接进行安装,但是国内访问 github 速度超慢,可以用以下地址来替代:

curl -L https://get.daocloud.io/docker/compose/releases/download/v2.12.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

第二步:

开放权限

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

第三步:

查看版本

[root@localhost /]# docker-compose version
Docker Compose version v2.12.2

卸载:

如果使用上述方式安装的,那么卸载命令为

 rm /usr/local/bin/docker-compose

使用 Docker compose 发布 SpringBoot

1. 准备镜像

在使用 docker compose 之前,我们需要先把项目中依赖的镜像下载下来。

[root@localhost ~]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
nginx        1.22      404359394820   13 days ago     142MB
redis        6.0       5e9f874f2d50   11 months ago   112MB
mysql        5.7       c20987f18b13   11 months ago   448MB

2. 编写 docker-compose.yml

最终我们需要有三个文件:

  • SpringBoot 的 jar 文件
  • Dockerfile 文件
  • docker-compose.yml 文件

所以我们在服务器 /mydocker/app 中存放这三个文件。

docker-compose.yml:

version: "3"

services:
  # 给SpringBoot起一个自定义的服务名
  myappService:
    # 将来 Dockerfile 构建的镜像名及版本号
    image: myapp:1.2
    # 指定容器名称
    container_name: myapp
    # 开放端口
    ports:
      - "12311:12311"
    # 配置容器连接的自定义网络,跟mysql、redis 属于同一个网络
    networks:
      - app_net
    # 容器启动时依赖于以下服务
    depends_on:
      - redisServer
      - mysqlServer
  # mysql服务
  mysqlServer:
    image: mysql:5.7
    ports:
      - "3306:3306"
    volumes:
      - /mydocker/mysql/data:/var/lib/mysql
      - /mydocker/mysql/conf.d:/etc/mysql/conf.d
    environment:
      MYSQL_ROOT_PASSWORD: 'root'
    networks:
      - app_net
  # redis 服务
  redisServer:
    image: redis:6.0
    ports:
      - "6379:6379"
    volumes:
      - /mydocker/redis/data:/data
      - /mydocker/redis/redis.conf:/usr/local/etc/redis/redis.conf
    networks:
      - app_net
    command: redis-server
  # nginx 服务
  nginxServer:
    image: nginx:1.22
    volumes:
      - /mydocker/nginx/nginx.conf:/etc/nginx/nginx.conf
      - /mydocker/nginx/default.conf:/etc/nginx/conf.d/default.conf
      - /mydocker/nginx/html:/usr/share/nginx/html
    ports:
      - "80:80"
    networks:
      - app_net
networks:
  app_net:

3. 修改application.yml

docker-compose.yml 中定义了 mysqlServerredisServer,所以配置文件中服务地址不再写对应的ip了,而是改成服务名。

server:
  port: 12311
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://mysqlServer/db_docker?serverTimezone=Asia/Shanghai&characterEncoding=utf-8&useSSL=false
    username: root
    password: root
  redis:
    host: redisServer
    port: 6379

4.编写 Dockerfile

# 基于java8
FROM openjdk:8
# 创建容器的工作目录
WORKDIR /app
# 将jar包添加到容器中,并改命为 demo.jar
ADD spring-docker-compose-0.0.1-SNAPSHOT.jar /app/myapp.jar
# 暴露端口
EXPOSE 12311
# 运行jar包
ENTRYPOINT ["java", "-jar"]
CMD ["myapp.jar"]

5.上传服务器

将 SpringBoot 打成jar,然后上传至服务器,需要保证 jar包、Dockerfile、docker-compose.yml 在同一个目录下。这里上传到 /mydocker/app 目录下:

[root@localhost /]# cd /mydocker/app
[root@localhost app]# ll
总用量 27800
-rw-r--r--. 1 root root     1362 12月  5 16:13 docker-compose.yml
-rw-r--r--. 1 root root      284 11月 23 20:00 Dockerfile
-rw-r--r--. 1 root root 28458970 12月  5 16:16 spring-docker-compose-0.0.1-SNAPSHOT.jar

6.构建SpringBoot 镜像

需要保证构建的镜像名称及版本号,和 docker-compose.yml 中定义的一致。

[root@localhost app]# docker build -t myapp:1.2 .

# 查看镜像是否构建成功
[root@localhost app]# docker images
REPOSITORY   TAG       IMAGE ID       CREATED         SIZE
myapp        1.2       e786e60a85aa   9 minutes ago   554MB
nginx        1.22      404359394820   2 weeks ago     142MB
openjdk      8         e24ac15e052e   11 months ago   526MB
redis        6.0       5e9f874f2d50   11 months ago   112MB
mysql        5.7       c20987f18b13   11 months ago   448MB

7.执行docker-compose up

[root@localhost app]# docker-compose up

出现以下日志,就说明命令执行没有问题。

up.png

默认情况,docker-compose up 启动的容器都在前台,控制台将会同时打印所有容器的输出信息,可以很方便进行调试。
当通过 Ctrl-C 停止命令时,所有容器将会停止。
如果使用 docker-compose up -d,将会在后台启动并运行所有的容器。一般推荐生产环境下使用该选项。

8. 查看运行容器

[root@localhost ~]# docker ps
CONTAINER ID   IMAGE        COMMAND                  CREATED              STATUS              PORTS                                                  NAMES
fa60e0fabf10   myapp:1.2    "java -jar myapp.jar"    About a minute ago   Up About a minute   0.0.0.0:12311->12311/tcp, :::12311->12311/tcp          myapp
002f18d9ba02   redis:6.0    "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:6379->6379/tcp, :::6379->6379/tcp              app-redisServer-1
56b831972238   mysql:5.7    "docker-entrypoint.s…"   About a minute ago   Up About a minute   0.0.0.0:3306->3306/tcp, :::3306->3306/tcp, 33060/tcp   app-mysqlServer-1
b9162bf9fb8e   nginx:1.22   "/docker-entrypoint.…"   About a minute ago   Up About a minute   0.0.0.0:80->80/tcp, :::80->80/tcp                      app-nginxServer-1

docker-compose 使用对比

对比.png

通过上面对比图可以发现,在服务不多的情况下,使用 docker-compose 和 不使用区别不大。

但是前者需要多少个服务,就得 docker run 多少次,在服务多或者搭建集群的场景下还是适合用 docker-compose。

docker run 时需要注意服务的启动顺序,比如 启动SpringBoot时需要先启动 mysql 和 redis,而 docker-compose 只需要指定 depends_on 即可。

总体来说,使用 docker-compose 可以将一组应用容器组成一个完整的业务单元,一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。当服务器上一个镜像运行了很多个容器后,我们很难搞清哪个容器对应哪个服务,使用 docker-compose 可以一目了然的发现各个容器之间的协作关系,方便运维管理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值