1. 程式人生 > >從零開始學習docker之在docker中執行springboot專案

從零開始學習docker之在docker中執行springboot專案

一、docker環境配置

首先需要一個安裝了docker的伺服器(本地或者雲伺服器),如果沒有請看上文,傳送門---https://www.cnblogs.com/wdfordream/p/12737389.html

我這裡是直接在雲伺服器上搭建了docker 

雲環境:CentOS 7.6 64位 

 

 

二、構建映象

1、 用DockerFile構建映象

通過DockerFile以及springboot.jar包構建映象。jar包可以通過本地打jar包上傳到伺服器也可以在伺服器上拉取程式碼通過maven打包。

這裡我是直接在雲伺服器上拉取github上的程式碼,利用maven打包成jar包的。程式碼傳送門---https://github.com/DreamsChaser/spring-boot-basic

具體步驟:

 (1) 從github上拉取spring-boot專案

git clone [email protected]:DreamsChaser/spring-boot-basic.git

 

 

 這個專案裡寫了一個簡單的rest用於測試

 (2) maven 打包

#進入專案根目錄
cd spring-boot-basic
#maven 打包
mvn clean package

BUILD SUCCESS顯示打包成功

(3)執行jar

#進入jar包所在目錄
cd spring-boot-basic-web/target/
#執行jar包(& 表示將啟動程序後臺執行 如果不用& 可以執行後ctrl + z 暫停返回命令列後 通過bg 後臺執行)
java -jar spring-boot-basic.jar &

 

 列印日誌 啟動成功 埠8080

(4)測試jar

通過curl命令或者直接在瀏覽器訪問呼叫rest介面

#curl呼叫
curl http://localhost:8080/spring-boot-basic/demo/test

 

直接在瀏覽器輸入 ip:port+訪問url 下面的ip是我雲伺服器的ip 埠就是啟動的埠

 

 到這裡說明jar是沒問題的 接下來通過docker建立映象啟動容器來執行jar

 (5)建立Dockerfile檔案

在專案根目錄新建Dockerfile 

#定製的映象都是基於 FROM 的映象(可以從docker hub上找)
FROM openjdk

#VOLUME ,VOLUME 指向了一個/tmp的目錄,由於Spring Boot使用內建的Tomcat容器,Tomcat 預設使用/tmp作為工作目錄
VOLUME /tmp

#拷貝並且重新命名(jar必須在dockerFile所在資料夾或者子資料夾 否則會報錯Forbidden path outside the build context)
ADD /spring-boot-basic-web/target/spring-boot-basic.jar spring-boot-basic.jar

#容器啟動命令 也可以用CMD 但CMD會被docker run的指令覆蓋
ENTRYPOINT ["java","-jar","/spring-boot-basic.jar"]

(6)建立映象

#建立映象 
#-t:映象的名字及標籤 -t name:tag或者 -t name
#-f :指定要使用的Dockerfile路徑 在Dockerfile所在目錄不需要指定
#最後有個 . docker build -t spring-boot-basic:1.0 .

 

 

 出現Step 1/4等表示正在構建 需要從docker hub拉取openjdk映象

(7)檢視映象

#檢視所有映象
docker image ls

 

 

 可以看到剛剛建立的 spring-boot-basic:1.0 映象 以及openjdk映象

 

2、利用maven外掛構建映象

maven外掛構建映象有兩種 一種是寫好dockerFile後再maven中配置dockerFile路徑,另一種是把dockerFile中相關配置按照一定屬性配置在maven。

(1)寫Dockerfile然後在pom中配置<dockerDirectory>

用這種方式的時候遇到了一個問題Error: Exception caught: xx/target does not exist 一開始我以為是路徑配置問題 因為我用的是pom自帶的一些屬性比如${basdir} 後來全部替換之後發現依然找不到

但是 只要我先執行mvn package 生成target之後在執行mvn clean package docker:build之後就能生成映象 但是會生成兩個映象 查看了一下輸出日誌後 我發現問題所在

我的spirng-boot專案配置了一個子module這個子module裡是我的rest服務並且打包型別是jar ,parent pom打包型別是pom 每次都會打一個pom和一個jar 我的maven docker配置是在父pom中 所以在打外層pom時也會build映象,而真正的jar包還沒生成索引失敗了,把配置移動到子module的pom中問題就解決了。

接下來講一下 配置方式 

在子module根目錄寫一份Dockerfile 

FROM openjdk
VOLUME ./tmp
#和上面的ADD不同 是因為我Dockerfile是在子module下的 ADD ./target/spring-boot-basic.jar spring-boot-basic.jar ENTRYPOINT ["java","-jar","/spring-boot-basic.jar"]

在子module spring-boot-basic-web 的pom.xml中配置

<build>
        <finalName>spring-boot-basic</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- docker plugin -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!-- docker config -->
                <configuration>
                    <!-- image name -->
                    <imageName>${project.build.finalName}</imageName>
                    <dockerDirectory>${project.basedir}</dockerDirectory>
                </configuration>
            </plugin>
        </plugins>
    </build>

在專案根目錄中執行 mvn clean package docker:build 

 

 

 可以看到構建完成 可以通過docker image ls檢視映象

(2)不用Dockerfile

省略Dockerfile把Dockerfile中的相關配置 按照pom裡的一些標籤進行配置

在子module spring-boot-basic-web的pom中配置

<build>
        <finalName>spring-boot-basic</finalName>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- docker plugin -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!-- docker config -->
                <configuration>
                    <!-- image name -->
                    <imageName>${project.build.finalName}</imageName>

                    <!-- Dockerfile配置路徑
                    <dockerDirectory>${project.basedir}</dockerDirectory>
                    -->

                    <!-- 非Dockerfile配置-->
                    <workdir>/tmp</workdir>
                    <baseImage>openjdk</baseImage>
                    <entryPoint>["java", "-jar", "/spring-boot-basic.jar"]</entryPoint>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>


                </configuration>
            </plugin>
        </plugins>
    </build>

注意這裡resource複製的時候複製到了/ 所以在entryPoint 寫java啟動命令時對應的jar要在/下

 

三、啟動容器

 1、啟動容器

#啟動容器
#引數1 --name 指定容器名
#引數2 -d 以後臺方式執行
#最後是 映象name:tag/name
docker run --name test -d spring-boot-basic:1.0

2、檢視容器

#檢視所有容器(包括關閉的)
docker ps -a

 

 

 

顯示剛剛執行中 Up

3、進入容器

#進入容器(以容器id或者name都可以進入)
#/bin/bash 進入後開啟bash命令列 docker exec -it 2de6fd561c9a /bin/bash

 

 

進入之後可以命令列輸入 

4、測試jar是否正常

(1)通過容器ip和埠訪問 

進入容器命令列後 檢視容器ip

 

 

找到ip是 172.18.0.2

離開容器 容器bash命令列輸入 exit

 

 

通過容器ip和埠訪問rest介面

#curl
curl http://172.18.0.2:8080/spring-boot-basic/demo/test

 

 

請求成功,返回hello world。

這種方式只能在部署docker的伺服器上才能請求成功,在其他機器無法訪問,這時候需要做埠對映。

(2)通過埠對映訪問

關閉並刪除之前啟動的容器

#關閉容器(id name都可以)
docker stop 2de6fd561c9a
#刪除容器(id name都可以)
docker rm 2de6fd561c9a

 

 

docker ps -a後發現容器已經刪除

以埠對映方式啟動容器

#-p設定埠 本地埠:容器埠
docker run --name test -d -p 7001:8080 spring-boot-basic:1.0

 

啟動完成之後 通過docker ps -a檢視啟動的容器 埠做了對映處理 可以通過本機(雲伺服器)埠訪問到 容器內部埠

通過curl測試 

 

 通過本機7001埠請求成功 返回hello world

同時在其他伺服器通過訪問docker所在伺服器的ip 和對映埠可以訪問容器內部的服務

 

122.51.103.239是我雲伺服器的公網ip,請求成功,返回hello world

 

 

四、異常彙總

[ERROR] No plugin found for prefix 'docker' in the current project 
and in the plugin groups [org.sonatype.plugins, org.apache.maven.plugins, org.codehaus.mojo] available from the repositories

解決:在maven配置檔案 setting.xml中配置

<pluginGroups>

  <pluginGroup>com.spotify</pluginGroup>

</pluginGroups>

 

[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:1.0.0:build (default-cli) on project spring-boot-basic: Exception caught: 
java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException:
org.apache.http.conn.HttpHostConnectException: Connect to localhost:2375 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1]
failed: Connection refused: connect -> [Help 1]

這個異常是我在window10構建映象的時候出現的 需要修改docker配置

 

這個地方選中 然後重啟就可以了 

 

 

五、常用命令彙總

1、映象相關

#檢視所有映象
docker image ls
#刪除映象 id或者name刪除
docker image rm 'id'/'name'
#構建映象 tag可以不填 預設latest
docker build -t 'name':'tag' .

2、容器相關

#檢視所有容器
docker ps -a
#關閉容器
docker stop 'id'/'name'
#重啟容器
docker restart 'id'/'name'
#進入容器 並開啟bash命令列
docker exec -it 'id' /bin/bash #啟動容器 -d後臺執行 -p埠對映
docker run --name 'name' -d -p 'port1':'port2' 'imageName':'imageTag'

&n