在Docker容器中執行Spring Boot應用
Spring Boot簡化了Spring應用的開發過程,遵循約定優先配置的原則提供了各類開箱即用(out-of-the-box)的框架配置。另一方面,Spring Boot還具備將程式碼直接構建為可執行jar包的能力,這個jar包是一個可以獨立執行的部署單元。基於以上特性,現在普遍認為Spring Boot提供了一種快速構造微服務(Micro-Service)的能力。
Docker與Spring Boot
Docker是一種Linux容器的實現,Linux容器是基於程序的輕量級資源隔離技術,每一個容器對應作業系統中的一個程序,但是它又會有自己的網路空間、檔案系統、PID等。Docker除了實現Linux容器,還使得容器具有“社會化”的功能,使用者可以將容器映象釋出在
Spring Boot應用通常被構建為一個可單獨執行的jar包,通過java -jar ...
執行,但是框架本身並沒有提供以服務形式執行在後臺的方法,通常需要藉助Systemd, Supervisord等程序管理工具來實現。另一方面,雖然應用執行環境非常的簡單,但是將他們容器化為Docker容器映象並執行,對於自動化部署、運維都是非常有利的。
本文將以一個最簡單的Spring Boot開發的Web應用為例,講解如何將其容器化執行。本文的重點是構建Docker映象、執行Docker容器,關於Spring Boot開發Web應用可以參考
構建並Spring Boot應用
在應用程式碼編寫完成後,可以直接將其打包並執行:
- Maven:
mvn package && java -jar target/spring-boot-docker-0.1.0.jar
- Gradle:
gradle build && java -jar build/libs/gs-spring-boot-docker-0.1.0.jar
Dockerfile構建映象
Docker提供了Dockerfile格式的檔案來構建應用映象,現在開始建立一個Spring Boot應用的Dockerfile:
FROM java:8 VOLUME /tmp ADD spring-boot-docker-0.1.0.jar app.jar RUN bash -c 'touch /app.jar' ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
java:8
是指Docker Hub上官方提供的java映象,版本號是8也就是jdk1.8,有了這個基礎映象後,Dockerfile可以通過FROM
指令直接獲取它的狀態——也就是在容器中java
是已經安裝的,接下來通過自定義的命令來執行Spring Boot應用:
VOLUME /tmp
建立/tmp目錄並持久化到Docker資料資料夾,因為Spring Boot使用的內嵌Tomcat容器預設使用/tmp
作為工作目錄ADD spring-boot-docker-0.1.0.jar app.jar
將應用jar包複製到/app.jar
ENTRYPOINT
表示容器執行後預設執行的命令
Dockerfile非常的簡單,編輯完成後執行docker構建映象命令:
docker build -t tmy/spring-boot-app .
然後執行Docker容器:
docker run -d -p 8080:8080 --name sample-app tmy/spring-boot-app
其中-d
表示後臺執行容器,這也就自然地解決的Spring Boot不支援後臺執行應用程式的問題。-p 8080:8080
表示將容器內部的8080埠對映到宿主機器的8080埠,這樣就可以通過宿主機器直接訪問應用。--name sample-app
給容器取一個容易記住的名字方便日後管理。
使用Maven/Gradle建立Docker映象
為了方便Java開發者建立Docker映象,Maven/Gradle都提供了響應的外掛。
Maven
<properties>
<docker.image.prefix>springio</docker.image.prefix>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.2.3</version>
<configuration>
<imageName>${docker.image.prefix}/${project.artifactId}</imageName>
<dockerDirectory>src/main/docker</dockerDirectory>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
上述pom.xml
包含了docker-maven-plugin
的配置:
imageName
指定了映象的名字dockerDirectory
指定Dockerfile的位置resources
是指那些需要和Dockerfile放在一起,在構建映象時使用的檔案,一般應用jar包需要納入
經過以上配置後,執行下列命令可以在本地Docker中建立一個映象:
$ mvn package docker:build
Gradle
Gradle同樣也有支援Docker的外掛:
buildscript {
...
dependencies {
...
classpath('se.transmode.gradle:gradle-docker:1.2')
}
}
group = 'springio'
...
apply plugin: 'docker'
task buildDocker(type: Docker, dependsOn: build) {
push = true
applicationName = jar.baseName
dockerfile = file('src/main/docker/Dockerfile')
doFirst {
copy {
from jar
into stageDir
}
}
}
上述配置和Maven基本類似,執行以下命令構建映象:
$ gradle build buildDocker