1. 程式人生 > >Spring Boot應用Docker打包成映象

Spring Boot應用Docker打包成映象

本教程將引導你通過建立一個Docker映象來執行Spring Boot應用。

你將構建什麼

Docker是一個具有社群性的Linux容器管理工具集,它允許使用者釋出映象或者使用其他開發者釋出的映象。Docker映象本質上是一個程序的執行環境。在這篇guide中,我們將構建一個執行Spring Boot應用程式的映象。

構建之前你要準備的東西

如果你當前使用的系統不是Linux,那麼你需要一個虛擬機器。通過安裝VirtualBox或者像mac的boot2docker等其他工具都可以滿足你的使用。
訪問VirtualBox下載地址選擇你的系統版本來下載VirtualBox,並且安裝執行起來。

當然你也需要安裝Docker(只能在64位機器上執行),有關詳細資訊請參閱https://docs.docker.com/installation/#installation來安裝Docker到你的系統上。開始下一步之前,你要確認在你的shell上是否可以執行docker命令,如果你使用的是boot2docker,在執行docker命令之前你需要先啟動boot2docker。

如何完成這篇教程

像大多數的Spring系列教程 Getting Started guides,你可以從頭開始,完成每一步,也可以跳過已經熟悉的基本構建步驟。 無論哪種方式,你都可以成功。

使用maven構建

首先你得安裝構建指令碼. 你可以使用你喜歡的構建系統去構建Spring應用,你可以前往

Maven官網來指導你安裝。 如果你對Maven不熟悉,請參閱使用Maven構建Java專案.

建立目錄結構

在你當前專案工作目錄中,建立如下子目錄:

1234 └── src └── main └── java └── hello

如在Linux系統下使用mkdir -p src/main/java/hello來建立。

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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.springframework</groupId>
    <artifactId>gs-spring-boot-docker</artifactId>
    <version>0.1.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
    </parent>
    <properties>
        <java.version>1.8</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
  • 它集中了classpath下的所有jar,並構建一個可執行的“uber-jar”,這樣可以更方便地執行和釋出服務。
  • 它查詢public static void main()方法並標記該類為可執行類。
  • 它提供了一個內建的依賴解析器,將應用與Spring Boot依賴的版本號進行匹配。你可以修改(override)成你希望的版本,但它預設為Spring Boot選擇的版本。

使用你的IDE構建

建立一個Spring Boot應用程式

現在你可以建立一個簡單的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);
    }
}

這個類使用@SpringBootApplication註解和@RestController註解標記,表示這個類已經準備好使用Spring MVC來處理web請求。@RequestMapping對映/home()方法上,這個方法返回Hello Docker World的響應。main()方法調SpringApplication.run()方法來啟動應用程式。

現在你可以在沒有Docker的情況下執行該應用程式。

如果你使用gradle構建的Spring Boot應用程式,執行:

./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檔案格式的檔案,並且使用指定的映象作為基礎映象。接下來我們去建立一個Dockerfile在Spring Boot應用程式中。

Dockerfile

12345 FROM openjdk:8-jdk-alpineVOLUME /tmpADD target/gs-spring-boot-docker-0.1.0.jar app.jarENV JAVA_OPTS=""ENTRYPOINT exec java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar

這個Dockerfile很簡單,但是已經包含了你執行這個Spring Boot應用程式的所有東西並且沒有多餘的東西:僅僅只有Java和一個Jar檔案。應用程式的jar檔案(檔名為app.jar)被新增到容器中,執行 ENTRYPOINT

我們增加了一個VOLUME指向”/tmp”,因為那是Spring Boot應用程式為Tomcat建立的預設工作目錄。作用是在你的主機”/var/lib/docker”目錄下建立一個臨時的檔案,並且連結到容器中的”/tmp”目錄。對於簡單程式這一步是可選的,但是對於其他想要真實寫入檔案系統的Spring Boot應用程式又是必選的。

我們增加了一個指向”/dev/urandom”的Tomcat系統屬性來縮小Tomcat的啟動時間。

如果你使用的是boot2docker,在你使用Docker命令或者使用構建工具構建(它執行在守護程序,在虛擬機器上為你工作)之前,你必須先啟動它。

構建Docker映象,你可以使用一些諸如Gradle或Maven的工具或者藉助社群(強烈感謝TransmodeSpotify提供這些工具)。

使用Maven構建Docker映象

在Maven的pom.xml中,你應該增加一個外掛,如下。(參閱the plugin documentation獲取更多資訊)。

pom.xml

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

配置指定了兩個東西:

  • 映象名字,最終會在springio/gs-spring-boot-docker
  • 可選,映象的標籤,未指定預設為latest,如果有需要的話,也可以指定artifact id

繼續下面的步驟之前(使用Docker CLI工具),輸入docker ps確保正常執行,如果有錯誤資訊,大概因為沒有設定其他什麼資訊。如果使用的Mac,在.bash_profile(或者是類似env-setting配置檔案)最後增加$(boot2docker shellinit 2> /dev/null)並重新整理你的shell,確保更改生效。

你可以使用下面的命令來構建Docker的映象:

1 $ ./mvnw install dockerfile:build

你可以使用./mvnw dockerfile:push命令釋出映象到Docker映象中心去。

你不用著急釋出你剛剛製作的映象,如果你不是”springio”組織的成員push命令會失敗。改變構建的配置和命令列中的使用者名稱為自己的而不是”springio”就可以正常工作。

你可以讓dockerfile:push自動執行在安裝或部署生命週期階段,通過將其新增到外掛配置中。

pom.xml

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

釋出之後

對你來說”Docker映象釋出”會失敗(除非你在Dockerhub中是”springio”組織的一員),但是如果你修改配置符合你自己的docker ID之後同樣會成功,你會有一個新的標籤,並且部署映象。

如果你沒有註冊docker,或者沒有釋出任何docker映象。但是你有一個本地的映象,你可以像這樣讓它執行起來:

1234 $ 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}並且重新構建執行)。

如果你使用mac的boot2docker,你通常在啟動時可以看到這樣的事情:

1234 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主機而不是本地主機的ip(localhost),在這種情況下,http://192.168.59.103:8080/,對於VM來說就是開發的ip。

當它正在執行,你可以在容器列表中看到:

123 $ docker psCONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES81c723d22865 springio/gs-spring-boot-docker:latest "java -jar /app.jar" 34 seconds ago Up 33 seconds 0.0.0.0:8080->8080/tcp goofy_brown

你可以使用docker stop加上容器的id來關閉它。

12 $ docker stop 81c723d2286581c723d22865

當然你喜歡你也可以刪除容器(它們都儲存在/var/lib/docker檔案目錄下)。

1 $ docker rm 81c723d22865

使用Spring Profiles

執行你新制作的映象使用Spring Profiles,和執行docker命令傳入一個環境變數一樣簡單。

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

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

在Docker容器中除錯應用程式

使用JPDA Transport可以除錯應用程式,所以我們可以視容器為一個伺服器,啟用此功能通過java設定JAVA_OPTS變數和代理的埠對映到本地主機在一個容器中執行。對於Docker for Mac由於有限制,我們不能通過IP訪問容器因為沒有black magic usage.

1 $ 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-docker

總結

恭喜你!剛剛為Spring Boot應用程式建立了Docker容器!Spring Boot應用程式在容器中執行預設埠8080對映到相同的宿主機埠使用”-p”引數。

另請參閱

以下教程也可能是有用的: