今天學習一下將 Spring Boot 項目一鍵打包到遠程 Docker 容器中,然後通過運行一個鏡像的方式來啓動一個 Spring Boot 項目。
首先準備Docker,我這裏用阿里的服務器演示
-
首先需要在 CentOS7 上安裝好 Docker,這個安裝方式網上很多,我就不多說了
-
Docker 安裝成功之後,我們首先需要修改 Docker 配置,開啓允許遠程訪問 Docker 的功能
vi /usr/lib/systemd/system/docker.service #編輯文件
-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock #在execStart=後面添加配置
配置完成後,保存退出,然後重啓 Docker
systemctl daemon-reload
service docker restart
接下來我們使用docker-maven-plugin GitHub地址 插件自動化的方式構建鏡像,該插件是基於maven插件,用來構建docker鏡像,當然也可以通過在系統中配置Dockerfile的方式構建鏡像。
在POM中聲明構建信息
在pom.xml
中添加下面這段配置
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- docker的maven插件,官網 https://github.com/spotify/docker-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<!--將Docker命令綁定到Maven階段,也就是使用maven的package命令打包時自動構建鏡像-->
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
<configuration>
<!--配置 Docker 的主機地址-->
<dockerHost>http://xxx.xxx.xxx.xxx:2375</dockerHost>
<imageName>${project.artifactId}:${project.version}</imageName>
<baseImage>java</baseImage>
<!--相當於Dokcerfile文件中的ENTRYPOINT ["java","-jar","/app.jar"]-->
<entryPoint>["java", "-jar","/${project.build.finalName}.jar"]</entryPoint>
<resources>
<resource>
<targetPath>/</targetPath>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
這個插件的配置不難理解:
-
configuration 中分別配置 Docker 的主機地址,鏡像的名稱,鏡像的 tags,其中 dockerDirectory 表示指定 Dockerfile 的位置。
-
imageName:鏡像的名稱,可以通過
${project.groupId}/${project.artifactId}:${project.version}
動態制定鏡像名稱,當然也可以在前面加上鏡像地址,比如127.0.0.1:5000,以聲明將構建好的鏡像存儲上傳到自己私服 -
baseImage: 基礎鏡像,這裏是相當於Dockerfile的FROM java
-
resources 下的配置:構建時會生成docker文件夾,這裏指生成文件夾的內容來源,包含了mvn clean package 之後的target的文件和生成的jar包。
-
execution 節點中配置當執行 mvn package 的時候,順便也執行一下 docker:build
以上配置會自動生成Dockerfile文件,可以在target/docker文件夾下看見如下圖所示
注: 打包過程會有點久,因爲還包含了鏡像的構建,第一次打包需要下載基礎鏡像,會更慢
運行容器測試
可以看到我們鏡像已經上傳完成了,我們創建容器運行測試一下。(至於爲什麼這麼大的話,因爲裏面包含Java環境)
我們在瀏覽器中來訪問一下
上面這種方式講述的是最簡單的方式直接在pom.xml中配置的方式,很多時候,我們還是要藉助Dockerfile
進行構建生成鏡像的,首先我們在src/main/docker
目錄下,建立文件Dockerfile文件
使用Dockerfile
要使用Dockerfile
,您必須指定dockerDirectory
元素。如果指定了 baseImage
,maintainer
,cmd
和entryPoint
元素將被忽略。的內容 dockerDirectory
將複製到中${project.build.directory}/docker
。使用resources
元素複製其他文件,例如服務的jar文件。
Dockerfile文件
FROM java
VOLUME /tmp
ADD docker_upload-0.0.1-SNAPSHOT.jar app.jar
RUN bash -c 'touch /app.jar'
EXPOSE 8080
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
注:${imageName} 爲pom.xml中配置的標籤
命令解析:
- FROM:表示基礎鏡像,即運行環境
- VOLUME:一個特別指定的目錄,用於存儲數據,該命令的作用是在/var/lib/docker創建一個名爲tmp的目錄
- ADD:拷貝文件並且重命名
- RUN: 構建鏡像時執行的命令
- EXPOSE: 指定於外界交互的端口
- ENTRYPOINT:容器啓動時運行的命令,相當於我們在命令行中輸入java -jar xxxx.jar,爲了縮短 Tomcat 的啓動時間,添加java.security.egd的系統屬性指向/dev/urandom作爲 ENTRYPOINT
pom.xml
文件
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- docker的maven插件,官網 https://github.com/spotify/docker-maven-plugin -->
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<version>0.4.13</version>
<configuration>
<!--配置 Docker 的主機地址-->
<dockerHost>http://xxx.xx.xxx.xx:2375</dockerHost>
<!-- 詳見:https://github.com/spotify/docker-maven-plugin Invalid repository name ... only [a-z0-9-_.] are allowed-->
<!--端口5000爲registry私有倉庫的訪問端口-->
<imageName>xxx.xx.xxx.xx:5000/${project.artifactId}:${project.version}</imageName>
<!-- 指定Dockerfile所在的路徑 -->
<dockerDirectory>${basedir}/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>
按照上面的配置之後,可以使用如下命令生成一個鏡像
mvn clean package docker:build
將生成的鏡像推送到私有倉庫,請指定pushImage
標籤
mvn clean package docker:build -DpushImage
如果推送指定tags 的鏡像,可使用pushImageTag
標籤
mvn clean package docker:build -DpushImageTag
爲了使上述的命令執行成功,需要在pom中配置imageTag
,可以配置多個imageTag
<build>
<plugins>
...
<plugin>
<configuration>
...
<imageTags>
<imageTag>${project.version}</imageTag>
<imageTag>latest</imageTag>
</imageTags>
</configuration>
</plugin>
...
</plugins>
</build>
如果你想強制docker在每次新的構建上覆蓋鏡像tags,可配置foreceTags
<build>
<plugins>
...
<plugin>
<configuration>
...
<!-- optionally overwrite tags every time image is built with docker:build -->
<forceTags>true</forceTags>
<imageTags>
...
</imageTags>
</configuration>
</plugin>
...
</plugins>
</build>
也可以在構建的命令行上添加上鏡像tags:
mvn ... docker:build -DpushImageTags -DdockerImageTags=latest -DdockerImageTags=another-tag
我使用的mvn clean package docker:build -DpushImage 命令
,不上傳則使用mvn clean package docker:build 命令構建鏡像
在構建成功之後進入宿主機就可以查看到已經創建的鏡像,並且已經上傳到私服當中