1. 程式人生 > >將springBoot專案部署到docker入門例項

將springBoot專案部署到docker入門例項

由於springBoot專案的便捷性,再加上有了springCloud下的各種組合元件,可以很快的開發出微服務的系統。

docker作為一個開源的應用容器引擎,用它可以快速地實現微服務系統的部署。下文是我今天用docker+springBoot部署專案的一個記錄。

操作環境:

VM虛擬機器安裝的ubuntu(ubuntu-16.04.3-desktop-amd64)

[email protected]:/home/ping# uname -a
Linux ubuntu 4.10.0-28-generic #32~16.04.2-Ubuntu SMP Thu Jul 20 10:19:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

在ubuntu上安裝好了jdk以及maven,並設好了環境變數
export MAVEN_HOME=/usr/local/maven/apache-maven-3.5.0
export PATH=$PATH:$MAVEN_HOME/bin
export JAVA_HOME=/usr/local/jdk/jdk1.8.0_144
export PATH=$PATH:$JAVA_HOME/bin


docker安裝

為了方便,直接使用apt命令安裝即可
apt-get install docker.io -y

安裝完成前,為了使系統獲取到最新的軟體包,先執行apt-get update

安裝完成後,執行docker -v檢視下是否可以執行

[email protected]:/home/ping# docker -v
Docker version 1.12.6, build 78d1802

springBoot專案準備

為了測試方便,僅建立一個只有一個返回字串的controller.

/**
 * desc: 測試controller
 * author: haiyangp
 * date:   2017/8/24
 */
@RestController
@RequestMapping(value = "hello")
public class HelloController {

    @RequestMapping(value = "say")
    public String sayHello(){
        return "Hello boy.Welcome here!";
    }
}
在pom.xml中新增docker的外掛
<?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>com.haiyang.springboot</groupId>
	<artifactId>docker-study</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>docker-study</name>
	<description>Demo project for Spring Boot</description>

	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.6.RELEASE</version>
	</parent>

	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<docker.image.prefix>haiyang</docker.image.prefix> <!-- 在docker執行時要用的,只是一個字首而已,就像包名一樣,可自己任意定義此名稱 -->
		<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>
			<!-- docker 外掛 begin -->
			<plugin>
				<groupId>com.spotify</groupId>
				<artifactId>docker-maven-plugin</artifactId>
				<version>1.0.0</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>
			<!-- docker 外掛 end -->
		</plugins>
	<finalName>docker-study</finalName><!--打包後文件名稱-->
	</build>
</project>

在這裡面,主要用了docker-maven-plugin這個maven外掛

在此外掛的開源地址中,有關於外掛的一些介紹

Dockerfile配置

在上面的pom.xml中的docker外掛配置中有這樣的一條配置

<dockerDirectory>src/main/docker</dockerDirectory>
在裡面指定了dockfile的目錄,所以需要在專案的src/main下建立一個docker目錄,並在其目錄中配置Dockerfile檔案


在此專案中,這裡是這樣寫的

FROM frolvlad/alpine-oraclejdk8:slim
VOLUME /tmp
ADD docker-study.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

FROM 指定此docker需要依賴的docker image,由於這是一個spring boot專案,故要執行一個spring boot專案,必須得要有jdk,而上面寫的frolvlad/alpine-oraclejdk8:slim這個映象中包含了一套擁有jdk的環境,可以此環境中執行java程式

VOLUME 用來指定docker執行的臨時目錄。它將在主機 /var/lib/docker 目錄下建立了一個臨時檔案,並連結到容器的/tmp。/tmp目錄用來持久化到 Docker 資料資料夾,因為 Spring Boot 使用的內嵌 Tomcat 容器預設使用/tmp作為工作目錄

ADD 是將pom.xml中的targetPath下的docker-study.jar複製到容器中,並命名為app.jar

ENTRYPOINT 指定了容器啟動時要執行的命令。那麼這裡就是執行java -jar /app.jar的意思,意思就是去執行這個springBoot專案了

在網上看見許多地方都加入了-Djava.security.egd=file:/dev/./urandom這個命令,通過查閱網上資料才得知由於tomcat每個session的生成時會產生一個sessionId,這個id是一個隨機數,會呼叫系統的隨機演算法來產生……………………。看了文章後,終於也解決了我以前在一臺centos伺服器上跑springboot專案,啟動要差不多等1分鐘左右的時間才能啟動完畢的疑惑。而在開發時,啟動的速度又很快,差不多幾秒就啟動完成了,今天看了這篇文章後,終於豁然開朗了。感興趣的如不瞭解熵的可以也看看這篇文章:http://hongjiang.info/jvm-random-and-entropy-source/(JVM上的隨機數與熵池策略)以及百度百科的相關資料。

Linux核心採用熵來描述資料的隨機性。熵(entropy)是描述系統混亂無序程度的物理量,一個系統的熵越大則說明該系統的有序性越差,即不確定性越大。在資訊學中,熵被用來表徵一個符號或系統的不確定性,熵越大,表明系統所含有用資訊量越少,不確定度越大。
計算機本身是可預測的系統,因此,用計算機演算法不可能產生真正的隨機數。但是機器的環境中充滿了各種各樣的噪聲,如硬體裝置發生中斷的時間,使用者點選滑鼠的時間間隔等是完全隨機的,事先無法預測。Linux核心實現的隨機數產生器正是利用系統中的這些隨機噪聲來產生高質量隨機數序列。
核心維護了一個熵池用來收集來自裝置驅動程式和其它來源的環境噪音。理論上,熵池中的資料是完全隨機的,可以實現產生真隨機數序列。為跟蹤熵池中資料的隨機性,核心在將資料加入池的時候將估算資料的隨機性,這個過程稱作熵估算。熵估算值描述池中包含的隨機數位數,其值越大表示池中資料的隨機性越好。

打包與構建docker映象

我這裡為了測試方便,是將程式碼直接壓縮,然後再上傳到linux上,再進行解壓,獲取出項目程式碼的。在實際開發中,應該通過專門的構建工具來完成,如jenkins之類的。 進入到專案後,直接執行打包構建docker命令即可.
mvn clean package docker:build
這個命令可以此maven外掛的github專案介紹中找到 ,如下:

Usage

You can build an image with the above configurations by running this command.

mvn clean package docker:build

To push the image you just built to the registry, specify the pushImage flag.

mvn clean package docker:build -DpushImage

To push only specific tags of the image to the registry, specify the pushImageTag flag.

mvn clean package docker:build -DpushImageTag

我在linux上執行的命令如下:
[email protected]:/home/ping/Desktop/dockerTest/docker-study# ll
total 48
drwxr-xr-x 4 root root 4096 Aug 24  2017 ./
drwxrwxr-x 4 ping ping 4096 Aug 24 02:14 ../
-rw-r--r-- 1 root root 6164 Aug 24  2017 docker-study.iml
-rw-r--r-- 1 root root  249 Aug 24  2017 .gitignore
drwxr-xr-x 3 root root 4096 Aug 24  2017 .mvn/
-rw-r--r-- 1 root root 6468 Aug 24  2017 mvnw
-rw-r--r-- 1 root root 4994 Aug 24  2017 mvnw.cmd
-rw-r--r-- 1 root root 2204 Aug 24  2017 pom.xml
drwxr-xr-x 4 root root 4096 Aug 24  2017 src/
[email protected]:/home/ping/Desktop/dockerTest/docker-study# mvn package docker:build

當執行完成後,會打印出如下的結果資訊
Downloaded: https://repo.maven.apache.org/maven2/com/spotify/docker-client/8.7.1/docker-client-8.7.1-shaded.jar (7.4 MB at 157 kB/s)
[INFO] Using authentication suppliers: [ConfigFileRegistryAuthSupplier]
[INFO] Copying /home/ping/Desktop/dockerTest/docker-study/target/docker-study.jar -> /home/ping/Desktop/dockerTest/docker-study/target/docker/docker-study.jar
[INFO] Copying src/main/docker/Dockerfile -> /home/ping/Desktop/dockerTest/docker-study/target/docker/Dockerfile
[INFO] Building image haiyang/docker-study
Step 1 : FROM frolvlad/alpine-oraclejdk8:slim
 ---> 60a1d51a971c
Step 2 : VOLUME /tmp
 ---> Using cache
 ---> 4d543a55947f
Step 3 : ADD docker-study.jar app.jar
 ---> 1db2e0bda70e
Removing intermediate container 0470cb282ae4
Step 4 : ENTRYPOINT java -jar /app.jar
 ---> Running in eff27a78c88e
 ---> 4e5275716856
Removing intermediate container eff27a78c88e
Successfully built 4e5275716856
[INFO] Built haiyang/docker-study
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 05:15 min
[INFO] Finished at: 2017-08-24T02:21:51-07:00
[INFO] Final Memory: 37M/89M
[INFO] ------------------------------------------------------------------------
[email protected]:/home/ping/Desktop/dockerTest/docker-study# 
這樣就表示此專案打包與構建docker image成功了!

執行docker image

執行前先檢視剛剛構建的那個docker image是否存在,執行docker images命令即可

[email protected]:/home/ping/Desktop/dockerTest/docker-study# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED             SIZE
haiyang/docker-study         latest              4e5275716856        12 minutes ago      181 MB
frolvlad/alpine-oraclejdk8   slim                60a1d51a971c        3 weeks ago         166.5 MB
[email protected]:/home/ping/Desktop/dockerTest/docker-study# 

看見有haiyang/docker-study這個容器,證明是成功的

接下來,直接執行即可

docker run -p 8080:8080 -t haiyang/docker-study


docker run -p 8080:8080 -t haiyang/docker-study 這行命令的意思是執行haiyang/docker-study這個容器,-p引數意思是把容器裡的8080埠轉到linux的8080埠上, -t是返回一個終端

然後趕緊在瀏覽器裡執行測試下

OK!執行成功了!

如要關閉此容器,指定 docker ps -a 獲取出CONTAINER ID

再執行docker stop 加ID即可