Start the service sequentially, solve the slow start of the docker-compose startup sequence mysql cause the service to fail

problem generation

I wrote a script using docker-compose , including mysql , redis , spring boot server . However, due to the large amount of mysql data, the startup will slow down, causing the spring boot server to fail to start

Even if the depends_on configuration is used,  it is invalid, because this configuration can only guarantee the startup sequence of the container, but the mysql container is started but the service has not yet started, so this problem occurs.

Solve the problem

If you are in a hurry, please use my final solution directly, and  modify the images and commands in your docker-compose

  • image: an image containing scripts listening to other ports
  • entrypoint:  wait for mysql and redis to start and execute the command after -c
my_server:
    image: sunbrightness/jdk-wait_run:8
    container_name: my_server
    ports:
      - 8080:8080
    environment:
      - LANG=C.UTF-8
      - TZ=Asia/Shanghai
    volumes:
      # 配置文件
      - ./server/:/home/java/
    privileged: true
    entrypoint: 'wait_run -d my_mysql:3306,my_redis:6379 -c "java -jar admin.jar"'
    restart: always
    depends_on:
      - km_mysql
      - km_redis

problem details

write a sh script

Use the netcat tool in linux to monitor the port, and run the spring boot server after the port is started

touch wait_run
chmod +x wait_run
vim wait_run
#!/bin/bash
#set -x

: ${SLEEP_SECOND:=2}

wait_for() {
    echo Waiting for $1 to listen on $2...
    while ! nc -z $1 $2; do echo waiting...; sleep $SLEEP_SECOND; done
}

declare DEPENDS
declare CMD

while getopts "d:c:" arg
do
    case $arg in
        d)
            DEPENDS=$OPTARG
            ;;
        c)
            CMD=$OPTARG
            ;;
        ?)
            echo "unkonw argument"
            exit 1
            ;;
    esac
done

for var in ${DEPENDS//,/ }
do
    host=${var%:*}
    port=${var#*:}
    wait_for $host $port
done

eval $CMD

In this way, you can use the following command to wait for multiple ports to start before executing your command

/bin/bash wait_run -d 127.0.0.1:3306,127.0.0.1:6379 -c "java -jar admin.jar"

Note that the docker container of jdk does not contain this command nc

So we need to customize a Dockerfile to install netcat

# 基础镜像
FROM openjdk:8
# author
MAINTAINER sunbrightness

# 挂载目录
VOLUME /home/java
# 创建目录
RUN mkdir -p /home/java
# 指定路径
WORKDIR /home/java

# fix apt update error
RUN echo "deb https://mirrors.bfsu.edu.cn/debian/ bullseye main contrib non-free" > /etc/apt/sources.list
RUN apt-get update
# 安装netcat用于监听端口启动
RUN apt-get -y install netcat

# 将刚刚创建的nc命令移动到镜像中
COPY ./wait_run /bin
RUN chmod +x /bin/wait_run

This is the sunbrightness/jdk-wait_run:8 image I mentioned above .

It took a long time to get it right. I also know that the docker image of java8 is based on the Debian 11 system

Guess you like

Origin blog.csdn.net/SUNbrightness/article/details/130018141