天天看點

Spring Boot + 外置tomcat + docker 打包部署

前言

最近這段時間在做一個有關于"Docker Graceful shutdown",于是自己就開始做起了各種"小實驗"。

雖然說過程有點痛苦,但是結果總是好的,讓我對于docker有了一些新的認識。

正文

言歸正傳,今天我們的主題是Spring Boot + 外置tomcat + Docker,然後用做好的鏡像可以去做部署。

我們需要修改兩大塊的地方:

  1. Spring boot
  2. 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"]           

下面做一下基本的講解:

  1. FROM 指令告訴我們需要使用的Docker應該使用哪一個basic的鏡像
  2. 拷貝我們的war包到docker中的tomcat的一個路徑下。
  3. 暴露8080端口
  4. 啟動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/

如果遇到了什麼問題,可以在下方評論區告訴我們,我會盡量進行解答。