前言
最近這段時間在做一個有關於"Docker Graceful shutdown",於是自己就開始做起了各種"小實驗"。
雖然說過程有點痛苦,但是結果總是好的,讓我對於docker有了一些新的認識。
正文
言歸正傳,今天我們的主題是Spring Boot + 外置tomcat + Docker,然後用做好的鏡像可以去做部署。
我們需要修改兩大塊的地方:
- Spring boot
- Docker
我並不是把tomcat落下了。原因是我們可以讓docker引用tomcat的鏡像。
首先我們來改造Spring boot 項目,讓他"擺脫"內置的tomcat
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.demo</groupId>
<artifactId>externaltomcattest</artifactId>
<version>1.0</version>
<packaging>war</packaging>
<name>externaltomcattest</name>
<description>This project is used to test graceful shutdown, and use external tomcat</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!--這個地方時擺脫tomcat的關鍵-->
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</exclusion>
<exclusion>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!--將tomcat的scope的作用域設置爲provided,這個地方和上面說的那個exclusion裏面其實選其一就行-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
啓動類:
package com.demo.externaltomcattest;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ExternaltomcattestApplication {
public static void main(String[] args) {
SpringApplication.run(ExternaltomcattestApplication.class, args);
}
}
和啓動類同級的地方,我們添加上這樣一個類,名字叫做ServletInitializer:
package com.demo.externaltomcattest;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(ExternaltomcattestApplication.class);
}
}
關鍵就是以上三步。
有不懂的可以參考我的github:https://github.com/luckypoison/SpringBootTomcatExternalTest。
️只需要注意上面我說的那幾個地方就行,剩下的是我爲了做grace-shutdown測試用的️。
接下來我們需要打出來一個war包用於部署,不知道何爲war包的,可以去自行搜索。
使用下面的命令進行打包:
mvn clean package
然後我們就可以在當前項目目錄下面的target目錄下面找到war包了。
在接下來我們就應該在一個空的文件夾下面,放上dockerfile,和我們的war包。
Dockerfile內容如下:
FROM tomcat:9.0
COPY externaltomcattest-1.0.war /usr/local/tomcat/webapps
EXPOSE 8080
CMD ["catalina.sh", "run"]
下面做一下基本的講解:
- FROM 指令告訴我們需要使用的Docker應該使用哪一個basic的鏡像
- 拷貝我們的war包到docker中的tomcat的一個路徑下。
- 暴露8080端口
- 啓動tomcat
然後使用下面的命令進行構建:
首先我們需要進到剛剛我們新創建的文件夾下面。
docker build -t external-tomcat-test:1.0 .
-t 後面跟着的是我們需要打包出來的鏡像的名字和版本號。
️後面的"."是不可以缺少的。
然後使用下面的命令,如果裏面有我們剛剛打包出來的鏡像,證明我們構建成功:
docker images
最後啓動就可以了。
docker run -p 8080:8080 <imageId>
如果有需要可以把構建鏡像和啓動放在需要的地方。
後記
這是一個簡單的例子,如果對docker上有什麼知道的命令可以去官網進行查詢:
https://docs.docker.com/engine/reference/run/
如果遇到了什麼問題,可以在下方評論區告訴我們,我會盡量進行解答。