概要

docker-compose 可以方便组合多个 docker 容器服务, 但是, 当容器服务之间存在依赖关系时, docker-compose 并不能保证服务的启动顺序。
docker-compose 中的 depends_on 配置是容器的启动顺序, 并不是容器中服务的启动顺序.

环境清理

在做实验的时候,我在很多地方都定义了这些容器,为了不受之前启动过的容器和镜像的影响。在本次实验之前,做一下环境的清理。

删除所有容器

  1. docker rm -f $(docker ps -qa)

删除所有镜像

  1. docker rmi -f $(docker images -qa)

项目改造前

情况描述

docker-compose.yml 中定义了2个服务,但这里只能定义到服务容器的启动顺序。通常来说这种方式无法满足我们严格的顺序启动要求。比如说,我们需要等待 mysql 服务完成启动完毕后,再启动 nacos
image.png
虽然这2个服务都启动了,但 nacos启动报错了。也就是说我们无法登陆nacos 页面,具体如图:
image.png
image.png
image.png

项目改造

安装依赖

  1. yum -y install nc

编写脚本

在项目的根目录下创建脚本文件,并赋予执行权限

  1. vim ep.sh
  2. chmod +x ep.sh

其脚本内容:

  1. #!/bin/bash
  2. #set -x
  3. #******************************************************************************
  4. # @file : ep.sh
  5. # @author : liangcy02
  6. # @date : 2018-08- 1 10:18:43
  7. #
  8. # @brief : entry point for manage service start order
  9. # history : init
  10. #******************************************************************************
  11. : ${SLEEP_SECOND:=2}
  12. wait_for() {
  13. echo Waiting for $1 to listen on $2...
  14. while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
  15. }
  16. declare DEPENDS
  17. declare CMD
  18. while getopts "d:c:" arg
  19. do
  20. case $arg in
  21. d)
  22. DEPENDS=$OPTARG
  23. ;;
  24. c)
  25. CMD=$OPTARG
  26. ;;
  27. ?)
  28. echo "unkonw argument"
  29. exit 1
  30. ;;
  31. esac
  32. done
  33. for var in ${DEPENDS//,/ }
  34. do
  35. host=${var%:*}
  36. port=${var#*:}
  37. wait_for $host $port
  38. done
  39. eval $CMD

测试脚本

测试 mysql

  1. ./ep.sh -d 192.168.3.18:3306 -c 'echo "start mysql service here"'

参数说明: -d 后面跟着 ip地址:端口号 -c 监听到端口启动后,需要执行的命令 这里的测试,就是说监听3.18 的3306端口,如果端口启动了,那就 打印输出 start mysql service here

测试 nacos

  1. ./ep.sh -d 192.168.3.18:8848 -c 'echo "start nacos service here"'

编写 docker-compose.yml

关键点

image.png

思考问题

我们编写的脚本中 -c 后面要跟启动 服务的命令,但为什么是 bin/docker-startup.sh 这个命令?

答案

因为 entrypoint 指令会覆盖原来Dockerfile 文件的最后一条 entrypoint 指令,关键是这一条指令一般都是启动我们的服务的指令。那这条指令我们怎么找?
①、打开 nacos-docker 在github上的地址:https://github.com/nacos-group/nacos-docker
②、找到 Dockerfile 文件
image.png
③、Dockerfile 文件最后一条 entrypoint 指令
image.png

具体详细内容

  1. version : '3.8'
  2. services:
  3. ruoyi-nacos:
  4. container_name: ruoyi-nacos
  5. image: nacos/nacos-server
  6. build:
  7. context: ./nacos
  8. environment:
  9. - MODE=standalone
  10. volumes:
  11. - ./nacos/logs/:/home/nacos/logs
  12. - ./nacos/conf/application.properties:/home/nacos/conf/application.properties
  13. - ./ep.sh:/ep.sh
  14. entrypoint: /ep.sh -d ruoyi-mysql:3306 -c 'bin/docker-startup.sh';
  15. ports:
  16. - "8848:8848"
  17. - "9848:9848"
  18. - "9849:9849"
  19. depends_on:
  20. - ruoyi-mysql
  21. ruoyi-mysql:
  22. container_name: ruoyi-mysql
  23. image: mysql:5.7
  24. build:
  25. context: ./mysql
  26. ports:
  27. - "3306:3306"
  28. volumes:
  29. - ./mysql/conf:/etc/mysql/conf.d
  30. - ./mysql/logs:/logs
  31. - ./mysql/data:/var/lib/mysql
  32. command: [
  33. 'mysqld',
  34. '--innodb-buffer-pool-size=80M',
  35. '--character-set-server=utf8mb4',
  36. '--collation-server=utf8mb4_unicode_ci',
  37. '--default-time-zone=+8:00',
  38. '--lower-case-table-names=1'
  39. ]
  40. environment:
  41. MYSQL_ROOT_PASSWORD: password

MySQL和Nacos镜像

参考之前写的,后面将整个项目构建完成会将源码上传

启动镜像

  1. docker-compose up

image.png