Spring Boot with Docker -- 入門教程

帶Docker的Spring Boot

本指南將指導您構建運行Spring Boot應用程序的Docker鏡像的過程。

你要建造什麼

Docker是一個具有“社交”方面的Linux容器管理工具包,允許用戶發佈容器圖像並使用其他人發佈的容器圖像。Docker鏡像是運行容器化過程的配方,在本指南中,我們將爲簡單的Spring啓動應用程序構建一個。

你需要什麼

如果您不使用Linux計算機,則需要虛擬化服務器。通過安裝VirtualBox,Mac的boot2docker等其他工具可以爲您無縫管理。訪問VirtualBox的下載站點,選擇適合您機器的版本。下載並安裝。不要擔心實際運行它。

您還需要Docker,它只能在64位計算機上運行。有關爲計算機設置Docker的詳細信息,請參閱https://docs.docker.com/installation/#installation。在繼續之前,請驗證您是否可以docker從shell 運行命令。如果你正在使用boot2docker你需要運行第一

如何完成本指南

與大多數Spring 入門指南一樣,您可以從頭開始並完成每個步驟,或者您可以繞過您已熟悉的基本設置步驟。無論哪種方式,您最終都會使用工作代碼。

從頭開始,請繼續使用Gradle構建

跳過基礎知識,請執行以下操作:

完成後,您可以根據代碼檢查結果gs-spring-boot-docker/complete

設置一個Spring Boot應用程序

現在您可以創建一個簡單的應用程序

src/main/java/hello/Application.java

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello Docker World";
    }

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

該類被標記爲a @SpringBootApplication和as @RestController,這意味着它可以由Spring MVC用於處理Web請求。@RequestMapping映射/home()只發送“Hello World”響應的方法。該main()方法使用Spring Boot的SpringApplication.run()方法來啓動應用程序。

現在我們可以在沒有Docker容器的情況下運行應用程序(即在主機操作系統中)。

如果您使用的是Gradle,請執行:

./gradlew build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar

如果您使用的是Maven,請執行:

./mvnw package && java -jar target/gs-spring-boot-docker-0.1.0.jar

並轉到localhost:8080以查看您的“Hello Docker World”消息。

容納它

Docker有一個簡單的Dockerfile文件格式,用於指定圖像的“圖層”。那麼讓我們繼續在Spring Boot項目中創建一個Dockerfile:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG JAR_FILE
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

這個Dockerfile非常簡單,但是你需要運行一個沒有多餘裝飾的Spring Boot應用程序:只需要Java和一個JAR文件。項目JAR文件ADDed作爲“app.jar”到容器,然後在ENTRYPOINT

  我們添加了一個VOLUME指向“/ tmp”的內容,因爲這是Spring Boot應用程序默認爲Tomcat創建工作目錄的地方。效果是在主機“/ var / lib / docker”下創建一個臨時文件,並將其鏈接到“/ tmp”下的容器。對於我們在此處編寫的簡單應用程序,此步驟是可選的,但如果需要在文件系統中實際編寫,則對於其他Spring Boot應用程序可能是必需的。
  爲了減少Tomcat的啓動時間,我們添加了一個指向“/ dev / urandom”的系統屬性作爲熵源。如果您使用Tomcat(或任何其他Web服務器)的“標準”版本,則對於更新版本的Spring Boot,這不是必需的。

爲了利用Spring Boot胖jar文件中依賴項和應用程序資源之間的清晰分離,我們將使用稍微不同的Dockerfile實現:

Dockerfile

FROM openjdk:8-jdk-alpine
VOLUME /tmp
ARG DEPENDENCY=target/dependency
COPY ${DEPENDENCY}/BOOT-INF/lib /app/lib
COPY ${DEPENDENCY}/META-INF /app/META-INF
COPY ${DEPENDENCY}/BOOT-INF/classes /app
ENTRYPOINT ["java","-cp","app:app/lib/*","hello.Application"]

 

 

這個Dockerfile有一個DEPENDENCY參數指向我們解壓縮胖jar的目錄。如果我們做對了,它已經包含一個BOOT-INF/lib帶有依賴項jars的BOOT-INF/classes目錄,以及一個包含應用程序類的目錄。請注意,我們正在使用應用程序自己的主類hello.Application(這比使用胖jar啓動器提供的間接更快)。

  如果你正在使用boot2docker你需要運行它首先,你與泊塢窗命令行或生成工具(它運行的守護進程來處理你在虛擬機的工作)做任何事情之前。

要構建圖像,您可以從社區使用Maven或Gradle的一些工具(非常感謝PalantirSpotify提供這些工具)。

使用Maven構建Docker鏡像

在Maven中pom.xml你應該添加一個這樣的新插件(有關更多選項,請參閱插件文檔)::

pom.xml

<properties>
   <docker.image.prefix>springio</docker.image.prefix>
</properties>
<build>
    <plugins>
        <plugin>
            <groupId>com.spotify</groupId>
            <artifactId>dockerfile-maven-plugin</artifactId>
            <version>1.3.6</version>
            <configuration>
                <repository>${docker.image.prefix}/${project.artifactId}</repository>
            </configuration>
        </plugin>
    </plugins>
</build>

配置指定了1個必需的東西:具有圖像名稱的存儲庫,最終將在此處作爲springio/gs-spring-boot-docker

其他一些屬性是可選的:

  • 胖jar將要解壓縮的目錄的名稱,將Maven配置公開爲docker的構建參數。可以使用<buildArgs/>插件配置指定它。

  • 圖像標記,如果未指定則最終爲“最新”。它可以用<tag/>元素設置,

  在繼續執行以下步驟(使用Docker的CLI工具)之前,請確保通過鍵入正確運行Dockerdocker ps。如果收到錯誤消息,可能無法正確設置某些內容。用Mac?添加$(boot2docker shellinit 2> /dev/null)到您的.bash_profile(或類似的環境設置配置文件)的底部並刷新shell以確保配置了正確的環境變量。

爲確保在創建docker鏡像之前解壓縮jar,我們爲依賴項插件添加一些配置:

pom.xml

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-dependency-plugin</artifactId>
    <executions>
        <execution>
            <id>unpack</id>
            <phase>package</phase>
            <goals>
                <goal>unpack</goal>
            </goals>
            <configuration>
                <artifactItems>
                    <artifactItem>
                        <groupId>${project.groupId}</groupId>
                        <artifactId>${project.artifactId}</artifactId>
                        <version>${project.version}</version>
                    </artifactItem>
                </artifactItems>
            </configuration>
        </execution>
    </executions>
</plugin>

 

您可以使用命令行構建標記的docker鏡像,如下所示:

$ ./mvnw install dockerfile:build

你可以將圖像推送到dockerhub ./mvnw dockerfile:push

  您不必將新創建的Docker鏡像推送到實際運行它。此外,如果您不是Dockerhub上“springio”組織的成員,“push”命令將失敗。將構建配置和命令行更改爲您自己的用戶名而不是“springio”,以使其實際工作。
  您可以dockerfile:push通過將其添加到插件配置來自動運行安裝或部署生命週期階段。

pom.xml

<executions>
	<execution>
		<id>default</id>
		<phase>install</phase>
		<goals>
			<goal>build</goal>
			<goal>push</goal>
		</goals>
	</execution>
</executions

使用Gradle構建Docker鏡像

如果您使用的是Gradle,則需要添加如下新插件:

build.gradle

buildscript {
    ...
    dependencies {
        ...
        classpath('gradle.plugin.com.palantir.gradle.docker:gradle-docker:0.13.0')
    }
}

group = 'springio'

...
apply plugin: 'com.palantir.docker'

task unpack(type: Copy) {
    dependsOn bootJar
    from(zipTree(tasks.bootJar.outputs.files.singleFile))
    into("build/dependency")
}
docker {
    name "${project.group}/${bootJar.baseName}"
    copySpec.from(tasks.unpack.outputs).into("dependency")
    buildArgs(['DEPENDENCY': "dependency"])
}

配置指定了4件事:

  • 解壓胖jar文件的任務

  • 圖像名稱(或標記)是從jar文件屬性設置的,最終將在此處作爲 springio/gs-spring-boot-docker

  • 解壓縮的jar文件的位置,我們可以在其中進行硬編碼 Dockerfile

  • docker指向jar文件的構建參數

您可以構建標記的docker鏡像,然後使用Gradle將其推送到遠程存儲庫:

$ ./gradlew build docker

推後

“docker push”將失敗(除非您是Dockerhub中“springio”組織的一部分),但是如果您更改配置以匹配您自己的docker ID,那麼它應該會成功,並且您將有一個新的標記,部署圖片。

 

您不必註冊docker或發佈任何東西來運行docker鏡像。您仍然擁有本地標記的圖像,您可以像這樣運行它:

$ docker run -p 8080:8080 -t springio/gs-spring-boot-docker
....
2015-03-31 13:25:48.035  INFO 1 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2015-03-31 13:25:48.037  INFO 1 --- [           main] hello.Application                        : Started Application in 5.613 seconds (JVM running for 7.293)

然後可以在http:// localhost:8080上訪問該應用程序(訪問它並顯示“Hello Docker World”)。要確保整個過程真正起作用,請將前綴從“springio”更改爲其他內容(例如${env.USER}),然後再從構建到docker run再次查看。

 

將Mac與boot2docker一起使用時,通常會在啓動時看到類似的內容:

Docker client to the Docker daemon, please set:
    export DOCKER_CERT_PATH=/Users/gturnquist/.boot2docker/certs/boot2docker-vm
    export DOCKER_TLS_VERIFY=1
    export DOCKER_HOST=tcp://192.168.59.103:2376

要查看應用程序,您必須訪問DOCKER_HOST中的IP地址而不是localhost。在這種情況下,http://192.168.59.103:8080,VM的面向公衆的IP。

當它運行時,您可以在容器列表中看到,例如:

$ docker ps
CONTAINER ID        IMAGE                                   COMMAND                  CREATED             STATUS              PORTS                    NAMES
81c723d22865        springio/gs-spring-boot-docker:latest   "java -Djava.secur..."   34 seconds ago      Up 33 seconds       0.0.0.0:8080->8080/tcp   goofy_brown

並再次關閉它你可以docker stop使用上面列表中的容器ID(你的不同):

$ docker stop 81c723d22865
81c723d22865

如果您願意,也可以在完成後刪除容器(它在/var/lib/docker某個地方保存在您的文件系統中):

$ docker rm 81c723d22865

使用Spring配置文件

使用Spring配置文件運行剛剛創建的Docker鏡像就像將環境變量傳遞給Docker run命令一樣簡單

$ docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t springio/gs-spring-boot-docker

要麼

$ docker run -e "SPRING_PROFILES_ACTIVE=dev" -p 8080:8080 -t springio/gs-spring-boot-docker

在Docker容器中調試應用程序

要調試應用程序,可以使用JPDA Transport。所以我們將容器視爲遠程服務器。要啓用此功能,請在JAVA_OPTS變量中傳遞Java代理設置,並在容器運行期間將代理程序的端口映射到localhost。使用Docker for Mac存在限制,因爲我們無法通過IP訪問容器而不使用黑魔法

$ docker run -e "JAVA_OPTS=-agentlib:jdwp=transport=dt_socket,address=5005,server=y,suspend=n" -p 8080:8080 -p 5005:5005 -t springio/gs-spring-boot-dockerspan>

摘要

恭喜!您剛剛爲Spring Boot應用程序創建了一個Docker容器!默認情況下,Spring Boot應用程序在容器內的端口8080上運行,我們使用命令行上的“-p”將其映射到主機上的同一端口。

也可以看看

以下指南也可能有所幫助:

想要撰寫新指南或爲現有指南做出貢獻?查看我們的貢獻指南

  所有指南均附有代碼的ASLv2許可證,以及Attribution,NoDerivatives創作公共許可證
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章