Dynamically package the versioned image according to the jar name, and create a script implementation for the corresponding container

Dynamically package versioned images and containers based on jar names

Use shell scripts to dynamically create versioned Docker images and versioned containers based on the project name and version number in the jar name.

background

Murphy’s law that no one can escape

The cause of the matter comes from a recent production environment accident : We have two servers in the environment of Party A, one is used for grayscale testing and the other is used for rumor. After a project I was responsible for completed the defect repair and passed the test, The product was submitted to the production environment release process. When the process came to me, I found that the operation and maintenance person responsible for on-site release in the process requested a release, and he also released the release, and gave me a screenshot of the successful script startup, but There is no current server IP in the screenshot , which paved the way for later problems to be exposed...

After the 'new version' was running for about a week, the implementation reflected that the previously fixed bug reappeared. So I asked the operation and maintenance to download the log to me. It turned out that the current business did not follow the logic after the new version was repaired, and the new version was not displayed. Additional log information. So I speculated that the package was not posted, so I asked the operation and maintenance to compare the docker container creation time and jar package upload time and found that it was really not posted . So I checked the previous chat records and found out that the package was not posted before. The screenshot of the screenshot does not capture the IP address of the server . As Murphy's Law says: anything that can go wrong will definitely go wrong.

Reflection on events

Afterwards, through communication with operation and maintenance and other colleagues, I learned: In fact, at work, the daily workload of operation and maintenance is also very large. Even if I have helped you send packages before, due to time and personal reasons, you will still forget it when you send the package again. Some environment configuration situations. There are also problems on my side. I did not confirm carefully after publishing...

Based on the above reflection, I decided to:

  1. Before every time you need operation and maintenance assistance to issue a contract, organize the contract documents and ask them to strictly follow the documents to issue the contract.
  2. Optimize the original startup script and dynamically package the versioned image according to the jar name ,
    so that the operation and maintenance side can also see whether the new version of the jar is successfully sent.

A journey of hardship

The entire script production process is combined with the use of ChatGPT. The middle process is a bit tortuous and long,
so I took some time to review it, hoping to bring some inspiration to myself and everyone.
If you want to see the final script directly, please jump directly to the final script part. That’s it

Prerequisite preparation

In the chapter about enabling remote debugging in idea , I shared the script for docker packaging jar package environment. The
core of this script is to use DockerFIle to make the jar into an image, and then use the startup script to generate the image into a container and start it.
But because of the previous The shared jars are all version 0.0.1 (Figure 1), so both the image tag (Figure 2) and the image information in the container at startup (Figure 3) are all 0.0.1. So how to dynamically package the
jar Is the version information in the image dynamically entered into the image tag and container name?

figure 1

figure 2

Insert image description here

image 3

Insert image description here

Share this script with everyone again

# 1.DockerFIle
FROM java:8

COPY 待启动jar-0.0.1-SNAPSHOT.jar 待启动jar-0.0.1-SNAPSHOT.jar

EXPOSE 项目对外端口

ENTRYPOINT ["java","-Duser.timezone=GMT+8","-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=远程调试端口","-jar","待启动jar-0.0.1-SNAPSHOT.jar"]


# 2.start.sh
sudo docker build --no-cache -f DockerFile -t 待启动jar:0.0.1 .;

sudo docker stop 待启动jar;

sudo docker rm 待启动jar;

sudo docker run -d --restart=always --name 待启动jar \
	-p 项目对外端口:项目对外端口 -p 远程调试端口:远程调试端口 \
	-v /home:/home \
	-v /home/待启动jar/logs:/logs \
	待启动jar:0.0.1 --spring.profiles.active=sit

1. Script startup sequence

Here we need to sort out the startup sequence of the script, which will help us ask questions later . The correct sequence is

->运行脚本start.sh
->通过DockerFIle制作新版本镜像
->停止并删除原来镜像对应的容器
->根据新的镜像创建容器
->执行根据DockerFIle中ENTRYPOINT关键字添加的, 启动容器所需执行的命令

2. Prerequisite knowledge

The writing of this article used a lot of DockerFIle keywords and basic knowledge of shell scripts
. If you encounter difficulties in subsequent reading, you can click on the link here to learn more about it (or use ChatGPT to learn about it briefly)

PS: If you don’t understand what the above script does, you can directly ask ChatGPT to translate it for you.

Insert image description here

brainstorming method

  1. At the beginning, I chose the "simplest and crudest way" and asked questions directly.
    Insert image description here

  2. As you can see, there still seems to be no problem in giving the DockerFIle file , but continue reading.
    Insert image description here

  3. You can see that there is a problem with the startup script. What I want is to dynamically obtain the project name and version number based on the jar name.
    But the script provided here is hard-coded from the beginning
    , which means that GPT does not correctly understand my problem. Dynamic reading means,
    Insert image description here

  4. Moreover, even if I used the above method to run the DockerFIle and startup script provided to me by ChatGPT,
    I found that it was still unsuccessful. The reason is that although the value of the parameter in the startup script is passed --build-arg to DockerFIle,
    after replacing the jar name in ENTRYPOINT The execution still reported an error,
    and the parameters defined through arg in DockerFIle could ${}not be obtained through ENTRYPOINT.
    I tried to use CMD to execute the parameters, but it still failed in this way.
    Therefore, I found that debugging a little bit on the whole is not as good as starting from the beginning. I broke through the details bit by bit .
    So I adjusted my questioning strategy: from asking questions as a whole to asking questions step by step.

step-by-step questioning

When planning the steps, the core is to dynamically obtain the jar package version number and jar name.
Therefore, at the beginning, I divided the main steps into 3 steps: dynamically read the information in the jar package name -> dynamically package the image -> dynamically create And run the container.
In the subsequent thinking, I added these two steps : Get the server IP-> Delete the original container and mirror
. If students with limited time want to get the final script directly, they can jump to the "Final Script" Part.
Let’s start with how to ask questions step by step to let ChatGP solve the problem.

1. Dynamically read the information in the jar package name

Based on the above premise preparation - the script startup sequence part, we summarized the startup sequence. I decided to modify the startup file start.sh first , and
handed over the problem of dynamically obtaining the jar name and version to ChatGPT. You can see that it was obtained quickly. a plan

Insert image description here
By reading the above script, I found that there are still flaws in providing the script, because the jar package name JAR_FILE is still hard-coded in the script,
rather than dynamically obtained. It can be seen that the current ChatGPT does not understand my needs.
Therefore, we need to continue to raise the issue. From ChatGPT,
Insert image description here
you can see that the previous problem has been solved.
At this point, the core three lines of the entire script have been obtained.

	# 获取当前jar全称
	JAR_FILE=$(ls  *.jar | head -n 1)
	# 获取当前jar实际名称(通过-分隔的第1列信息, 这里后续需要根据自己jar的格式进行调整)
	BASE_NAME=$(echo "$JAR_FILE" | 

Guess you like

Origin blog.csdn.net/qq_43371556/article/details/131116610