使用Docker部署SpringBoot

前言

搭建一個(gè)簡(jiǎn)單的Spring Boot項(xiàng)目與Docker技術(shù)進(jìn)行整合,使用Maven來(lái)構(gòu)建Docker鏡像并推送至本地Docker Registry,最后對(duì)項(xiàng)目進(jìn)行部署時(shí)只需根據(jù)鏡像啟動(dòng)相應(yīng)的容器即可.

環(huán)境搭建

  • JDK1.8
  • Spring Boot 1.5.7
  • Maven 3.3.9
  • Docker

1.使用IDEA新建一個(gè)Spring Boot項(xiàng)目,在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>hello</groupId>
    <artifactId>hello-api</artifactId>
    <version>1.0.0</version>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.7.RELEASE</version>
        <relativePath/>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.4.13</version>
        </dependency>
    </dependencies>
    <build>
        <finalName>hello</finalName>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <filtering>true</filtering>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

我們使用了spring-boot-maven-plugin插件來(lái)打包生成一個(gè)可直接運(yùn)行的hello.jar包.
2.新建一個(gè)HelloApplication類.

package hello;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloApplication.class, args);
    }
}

3.新建一個(gè)控制類HelloController,用于接收Http請(qǐng)求.

package hello.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    @RequestMapping(value = "/hi", method = RequestMethod.GET)
    public String hello() {
        return "hi";
    }
}

4.然后使用mvn package命令開(kāi)始對(duì)spring boot項(xiàng)目進(jìn)行打包構(gòu)建,生成對(duì)應(yīng)的target目錄.

image.png

cd到此目錄下執(zhí)行java -jar hello.jar啟動(dòng)項(xiàng)目,開(kāi)啟瀏覽器訪問(wèn)http://localhost:8080/hi,頁(yè)面返回:hi說(shuō)明spring boot項(xiàng)目配置運(yùn)行正常.
5.開(kāi)始為項(xiàng)目添加Docker支持.
Maven規(guī)范要求所有的資源文件都應(yīng)放在src/main/resources目錄下,我們?cè)趹?yīng)用的resources目錄下創(chuàng)建一個(gè)空白的文件Dockerfile,用來(lái)說(shuō)明如何構(gòu)建docker 鏡像,打開(kāi)Dockerfile文件編寫(xiě)以下指令:

FROM java:8
MAINTAINER "william"<952408421@qq.com>
ADD hello.jar app.jar
EXPOSE 8080
CMD java -jar app.jar

以上指令使用了Jdk8環(huán)境為基礎(chǔ)鏡像,通過(guò)ADD指令將生成的hello.jar包復(fù)制到docker容器中,并重命名為app.jar,應(yīng)用將開(kāi)啟8080端口,最后使用java -jar指令執(zhí)行jar包.
6.使用Maven來(lái)構(gòu)建Docker鏡像.
接下來(lái)我們要使用maven讀取Dockerfile文件來(lái)構(gòu)建鏡像并推送到注冊(cè)中心去,由于Docker默認(rèn)的鏡像注冊(cè)中心為Docke Hub(地址是docker.io),當(dāng)使用docker push命令推送鏡像時(shí),實(shí)際上都是推送到了docker.io的地址上的,如果需要推送到本地自己搭建的鏡像注冊(cè)中心,則鏡像名稱需要添加前綴ip:port,因?yàn)槲覀冎耙呀?jīng)搭好了本地Registry了,所以在pom.xml文件中添加properties:

    <properties>
        <docker.registry>192.168.56.101:5000</docker.registry>
    </properties>

然后再添加maven plugin到pom.xml文件中:

            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>0.4.10</version>
                <configuration>
                    <imageName>${docker.registry}/${project.groupId}/${project.artifactId}:${project.version}</imageName>
                    <dockerDirectory>${project.build.outputDirectory}</dockerDirectory>
                    <resources>
                        <resource>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

簡(jiǎn)要說(shuō)明一下configuration的配置:

  • imageName:用于指定鏡像的完整名稱,其中{docker.registry}為注冊(cè)中心地址,{project.groupId}為倉(cāng)庫(kù)名稱,{project.artifactId}為鏡像名稱,${project.version}為鏡像標(biāo)簽名.
  • dockerDirectory:用于指定Dockerfile文件所在的目錄.
  • resources.resource.directory:用于指定需要復(fù)制的根目錄,${project.build.directory}表示target目錄.
  • resources.resource.include:用于指定需要復(fù)制的文件,${project.build.finalName}.jar表示生成的jar包.

7.使用docker build命令來(lái)構(gòu)建鏡像.

 mvn docker:build

執(zhí)行后發(fā)現(xiàn)構(gòu)建鏡像不成功,報(bào)異常localhost:2375 Connection refused :

[INFO] Building image 192.168.56.101:5000/hello/hello-api:1.0.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.102 s
[INFO] Finished at: 2018-07-30T15:56:40+08:00
[INFO] Final Memory: 26M/218M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:0.4.10:build (default-cli) on project hello-api: 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]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

網(wǎng)上搜索了很久找到了一種解決Connect to localhost:2375的問(wèn)題的方法:在pom.xml文件的configuration中添加一行dockerHost.

                <configuration>
                    <imageName>${docker.registry}/${project.groupId}/${project.artifactId}:${project.version}</imageName>
                    <dockerDirectory>${project.build.outputDirectory}</dockerDirectory>
                    <dockerHost>http://192.168.56.101:2375</dockerHost>
                    ......
                </configuration>

我們?cè)賮?lái)執(zhí)行mvn docker:build試試,這一次同樣是報(bào)Connection refused的錯(cuò),錯(cuò)誤信息由localhost變成了192.168.56.101:

[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10.086 s
[INFO] Finished at: 2018-07-30T16:13:36+08:00
[INFO] Final Memory: 27M/302M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal com.spotify:docker-maven-plugin:0.4.10:build (default-cli) on project hello-api: Exception caught: java.util.concurrent.ExecutionException: com.spotify.docker.client.shaded.javax.ws.rs.ProcessingException: org.apache.http.conn.HttpHostConnectException: Connect to 192.168.56.101:2375 [/192.168.56.101] failed: Connection refused: connect -> [Help 1]
[ERROR] 
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR] 
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException

繼續(xù)網(wǎng)上搜索,發(fā)現(xiàn)在默認(rèn)情況下Docker守護(hù)進(jìn)程Unix socket(/var/run/docker.sock)來(lái)進(jìn)行本地進(jìn)程通信,而不會(huì)監(jiān)聽(tīng)任何端口,因此只能在本地使用docker客戶端或者使用Docker API進(jìn)行操作.如果想在其他主機(jī)上操作Docker主機(jī),就需要讓Docker守護(hù)進(jìn)程打開(kāi)一個(gè)HTTP Socket,這樣才能實(shí)現(xiàn)遠(yuǎn)程通信.我們是在windows上打包構(gòu)建的,所以需要讓centos7上的docker服務(wù)開(kāi)啟遠(yuǎn)程訪問(wèn).
8.開(kāi)啟docker遠(yuǎn)程服務(wù),執(zhí)行vi命令:

vi /usr/lib/systemd/system/docker.service

在[Service]部分的最下面添加下面兩行:

ExecStart=
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock

然后讓docker重新讀取配置文件,并重啟docker服務(wù).

systemctl daemon-reload
systemctl restart docker

查看docker進(jìn)程,發(fā)現(xiàn)docker守護(hù)進(jìn)程在已經(jīng)監(jiān)聽(tīng)2375的tcp端口了.

[root@bogon ~]# ps -ef|grep docker
root      1956     1  3 16:32 ?        00:00:00 /usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock
root      1959  1956  0 16:32 ?        00:00:00 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --metrics-interval=0 --start-timeout 2m --state-dir /var/run/docker/libcontainerd/containerd --shim docker-containerd-shim --runtime docker-runc
root      2056  1956  0 16:32 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 5000 -container-ip 172.17.0.2 -container-port 5000
root      2062  1959  0 16:32 ?        00:00:00 docker-containerd-shim ffac4cc26314b42610071b521cbd9c39e00618f4277ca967c1fee31193ff4041 /var/run/docker/libcontainerd/ffac4cc26314b42610071b521cbd9c39e00618f4277ca967c1fee31193ff4041 docker-runc
root      2075  2062  2 16:32 ?        00:00:00 registry serve /etc/docker/registry/config.yml
root      2103  1259  0 16:32 pts/0    00:00:00 grep --color=auto docker

最后我們?cè)賮?lái)執(zhí)行mvn docker:build命令:

[INFO] Building image 192.168.56.101:5000/hello/hello-api:1.0.0
Step 1/5 : FROM java:8
 ---> d23bdf5b1b1b
Step 2/5 : MAINTAINER "zhangzhongwu"<952408421@qq.com>
 ---> Running in 3b331db3b81b
 ---> bae408e908a0
Removing intermediate container 3b331db3b81b
Step 3/5 : ADD hello.jar app.jar
 ---> 3cc7f118a38c
Removing intermediate container 9a3bf9971e98
Step 4/5 : EXPOSE 8080
 ---> Running in 7b5c1dccbd4e
 ---> 5a0c6401e95a
Removing intermediate container 7b5c1dccbd4e
Step 5/5 : CMD java -jar app.jar
 ---> Running in 3ba012d83276
 ---> 68bbcea2575f
Removing intermediate container 3ba012d83276
Successfully built 68bbcea2575f
Successfully tagged 192.168.56.101:5000/hello/hello-api:1.0.0
[INFO] Built 192.168.56.101:5000/hello/hello-api:1.0.0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23.931 s
[INFO] Finished at: 2018-07-30T16:33:49+08:00
[INFO] Final Memory: 28M/272M
[INFO] ------------------------------------------------------------------------

好了,我們可以看到鏡像已經(jīng)構(gòu)建成功了.
9.接下來(lái)就是把已經(jīng)構(gòu)建好的鏡像推送到Docker Registry了.
我們執(zhí)行mvn docker:build docker:push命令
然后打開(kāi)linux終端,輸入命令docker images查看所有的鏡像:

[root@bogon ~]# docker images
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
192.168.56.101:5000/hello/hello-api   1.0.0               68bbcea2575f        2 minutes ago       673MB
nginx                                 latest              c82521676580        5 days ago          109MB
registry                              latest              b2b03e9146e1        3 weeks ago         33.3MB
java                                  8                   d23bdf5b1b1b        18 months ago       643MB
[root@bogon ~]# 

可以看到"192.168.56.101:5000/hello/hello-api"這個(gè)鏡像,說(shuō)明我們已經(jīng)把鏡像成功推送到注冊(cè)中心了.
10.最后一步就是運(yùn)行該鏡像,啟動(dòng)容器并將容器的8080端口綁定到宿主機(jī)的58080端口上:

[root@bogon ~]# docker run -d -p 58080:8080 192.168.56.101:5000/hello/hello-api:1.0.0
9d9363d1213df621c3f610b3466d265332ef42600461ae3e50ff25418b751b65
[root@bogon ~]# 

執(zhí)行以下命令驗(yàn)證服務(wù)是否啟動(dòng)成功:

[root@bogon /]# curl -XGET http://192.168.56.101:58080//hello/hi
hi[root@bogon /]# 

返回字符串"hi",說(shuō)明已經(jīng)成功使用Docker部署Spring Boot項(xiàng)目了.
參考資料:
https://blog.csdn.net/qq_27808181/article/details/78421134
https://blog.csdn.net/faryang/article/details/75949611
https://www.cnblogs.com/zqifa/p/linux-docker-3.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子枪孩,更是在濱河造成了極大的恐慌珠移,老刑警劉巖坛掠,帶你破解...
    沈念sama閱讀 216,591評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件擎勘,死亡現(xiàn)場(chǎng)離奇詭異霉涨,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)餐茵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,448評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)述吸,“玉大人忿族,你說(shuō)我怎么就攤上這事◎蛎” “怎么了道批?”我有些...
    開(kāi)封第一講書(shū)人閱讀 162,823評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)入撒。 經(jīng)常有香客問(wèn)我隆豹,道長(zhǎng),這世上最難降的妖魔是什么茅逮? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,204評(píng)論 1 292
  • 正文 為了忘掉前任璃赡,我火速辦了婚禮簿煌,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘鉴吹。我一直安慰自己姨伟,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,228評(píng)論 6 388
  • 文/花漫 我一把揭開(kāi)白布豆励。 她就那樣靜靜地躺著夺荒,像睡著了一般。 火紅的嫁衣襯著肌膚如雪良蒸。 梳的紋絲不亂的頭發(fā)上技扼,一...
    開(kāi)封第一講書(shū)人閱讀 51,190評(píng)論 1 299
  • 那天,我揣著相機(jī)與錄音嫩痰,去河邊找鬼剿吻。 笑死,一個(gè)胖子當(dāng)著我的面吹牛串纺,可吹牛的內(nèi)容都是我干的丽旅。 我是一名探鬼主播,決...
    沈念sama閱讀 40,078評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼纺棺,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼榄笙!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起祷蝌,我...
    開(kāi)封第一講書(shū)人閱讀 38,923評(píng)論 0 274
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茅撞,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后巨朦,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體米丘,經(jīng)...
    沈念sama閱讀 45,334評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,550評(píng)論 2 333
  • 正文 我和宋清朗相戀三年糊啡,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拄查。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,727評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悔橄,死狀恐怖靶累,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情癣疟,我是刑警寧澤挣柬,帶...
    沈念sama閱讀 35,428評(píng)論 5 343
  • 正文 年R本政府宣布,位于F島的核電站睛挚,受9級(jí)特大地震影響邪蛔,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜扎狱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,022評(píng)論 3 326
  • 文/蒙蒙 一侧到、第九天 我趴在偏房一處隱蔽的房頂上張望勃教。 院中可真熱鬧,春花似錦匠抗、人聲如沸故源。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,672評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)绳军。三九已至,卻和暖如春矢腻,著一層夾襖步出監(jiān)牢的瞬間门驾,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,826評(píng)論 1 269
  • 我被黑心中介騙來(lái)泰國(guó)打工多柑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留奶是,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,734評(píng)論 2 368
  • 正文 我出身青樓竣灌,卻偏偏與公主長(zhǎng)得像聂沙,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子帐偎,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,619評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理逐纬,服務(wù)發(fā)現(xiàn),斷路器削樊,智...
    卡卡羅2017閱讀 134,652評(píng)論 18 139
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 46,806評(píng)論 6 342
  • 入門(mén) 介紹 Spring Boot Spring Boot 使您可以輕松地創(chuàng)建獨(dú)立的、生產(chǎn)級(jí)的基于 Spring ...
    Hsinwong閱讀 16,881評(píng)論 2 89
  • 很晚了兔毒,但是還是決定打開(kāi)電腦記錄下最近一段時(shí)間遇到的問(wèn)題漫贞。事情是這樣的,前段時(shí)間公司一個(gè)同事ZM休婚假育叁,我就接手了...
    jarvan4dev閱讀 6,509評(píng)論 0 5
  • 18歲豪嗽,是很久遠(yuǎn)的事情了谴蔑。 18歲以前,過(guò)生日比過(guò)年還要喜歡龟梦,有蛋糕吃隐锭,可以為所欲為,每次都期待著计贰,期待著快快長(zhǎng)大...
    唐翁閱讀 1,078評(píng)論 1 3