Docker應(yīng)用實(shí)踐:一個(gè)簡(jiǎn)單的Java EE&Docker示例
學(xué)習(xí)Docker的***辦法就是迅速在工作中應(yīng)用它,本文作者使用Docker部署了一個(gè)Java EE應(yīng)用,非常簡(jiǎn)單和方便。需要注意的是,由于作者寫(xiě)作時(shí)本地網(wǎng)絡(luò)有問(wèn)題,所以Dockerfile中很多的資源都沒(méi)有從網(wǎng)絡(luò)下載,你再實(shí)踐時(shí),可以嘗試修改。學(xué)習(xí)快樂(lè) :)
本文中,我們將會(huì)把Java EE和Docker結(jié)合,具體內(nèi)容如下:
- 創(chuàng)建、構(gòu)建并運(yùn)行一個(gè)Docker鏡像;
- 通過(guò)鏡像啟動(dòng)一個(gè)Wildfly服務(wù)器,并部署了一個(gè)JavaEE示例應(yīng)用;
- 展示一些常用的Docker命令;
- 啟動(dòng)多個(gè)容器,并讓同一應(yīng)用運(yùn)行于不同端口。
引言
在這里我不再介紹Docker,因?yàn)橐呀?jīng)有太多的介紹性的文章。寫(xiě)本文之前,我閱讀了如下教程:
- Docker用戶(hù)指南;
- 使用Docker鏡像;
- Docker***指南(譯者注:已翻譯);
- Arun Gupta的技術(shù)技巧:#39、#57、#61和#65。
前提條件
要完成本教程,你需要:
- 有一個(gè)運(yùn)行于宿主機(jī)上的Docker后臺(tái)進(jìn)程
- 安裝Docker后,在etc\default\docker文件中添加一行:DOCKER_OPTS="-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock
- 此后重啟機(jī)器并嘗試運(yùn)行這個(gè)命令:docker -H tcp://127.0.0.1:2375 –version,輸出應(yīng)該類(lèi)似這樣的:Docker version 1.4.1, build 5bc2ff8
- 一個(gè)Wildfly 8.2.0的安裝程序(解壓后的);
- jdk-8u25-linux-x64.tar.gz文件。(http://www.oracle.com/technetwork/java/javase/downloads/index.html)
- 下載 car-service.war。(https://github.com/rmpestano/javaee-docker-sample/blob/master/java_ee/car-service.war)
- 下載 Dockerfile。(https://github.com/rmpestano/javaee-docker-sample/blob/master/java_ee/Dockerfile)
創(chuàng)建Docker鏡像
Docker鏡像展現(xiàn)/描述了容器本身。由于我的網(wǎng)絡(luò)帶寬有限(手機(jī)3G),在這里我使用本機(jī)資源創(chuàng)建了一個(gè)鏡像。因此,這個(gè)鏡像只有在包含如下文件的目錄下構(gòu)建才能使用:
- wildfly-8.2.0.Final:應(yīng)用服務(wù)器
- car-service.war:要部署的應(yīng)用
- Dockerfile:描述容器的文件
- jdk-8u25-linux-x64.tar.gz:要在容器里安裝的java版本
注意:不推薦在Docker容器中使用本地資源,因?yàn)橹挥挟?dāng)所有文件都存在時(shí)鏡像才可以正常構(gòu)建。***的辦法是從頭安裝所有東西并下載必要的文件。
這是Dockerfile的內(nèi)容:
- FROM ubuntu
- MAINTAINER Rafael Pestano <rmpestano@gmail.com>
- setup WildFly
- COPY wildfly-8.2.0.Final /opt/wildfly
- install example app on wildfy
- COPY car-service.war /opt/wildfly/standalone/deployments/
- setup Java
- RUN mkdir /opt/java
- COPY jdk-8u25-linux-x64.tar.gz /opt/java/
- change dir to Java installation dir
- WORKDIR /opt/java/
- RUN tar -zxf jdk-8u25-linux-x64.tar.gz
- setup environment variables
- RUN update-alternatives --install /usr/bin/javac javac /opt/java/jdk1.8.0_25/bin/javac 100
- RUN update-alternatives --install /usr/bin/java java /opt/java/jdk1.8.0_25/bin/java 100
- RUN update-alternatives --display java
- RUN java -version
- Expose the ports we're interested in
- EXPOSE 8080 9990
- Set the default command to run on boot
- This will boot WildFly in the standalone mode and bind to all interface
- CMD ["/opt/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", "0.0.0.0"]
鏡像繼承自Ubuntu——一個(gè)安裝了Ubuntu操作系統(tǒng)的鏡像。Docker安裝教程中就安裝了Ubuntu鏡像。
接著,我們將服務(wù)器復(fù)制到容器的/opt/wildfly目錄。COPY是Dockerfile的一個(gè)指令。我們可以在這里找到所有命令。
我們隨后將應(yīng)用的war包復(fù)制到服務(wù)器中:
- COPY car-service.war /opt/wildfly/standalone/deployments/。
然后,我們將Java解壓安裝到容器的/opt/java目錄并設(shè)置一些環(huán)境變量。***的辦法是使用apt-get,不過(guò)這要求有互聯(lián)網(wǎng)接入,而我寫(xiě)作時(shí)不具備這個(gè)條件。我使用RUN命令來(lái)執(zhí)行java -version,(如果Java正確安裝的話(huà))它將在鏡像構(gòu)建時(shí)打印版本號(hào)。
之后,我使用EXPOSE 8080 9990來(lái)告訴Docker容器要暴露的端口號(hào)。容器其實(shí)是鏡像的實(shí)例,運(yùn)行鏡像(docker run)時(shí),我們可以指定允許宿主訪(fǎng)問(wèn)的端口。
***,我們指定了默認(rèn)命令:CMD ["/opt/wildfly/bin/standalone.sh", "-c", "standalone-full.xml", "-b", "0.0.0.0"]。每次容器啟動(dòng)時(shí)都會(huì)運(yùn)行這個(gè)命令。
構(gòu)建鏡像
在描述完鏡像之后,我們需要構(gòu)建它。在包含Dockerfile的父目錄運(yùn)行以下命令:
- docker -H tcp://127.0.0.1:2375 build -t javaee_sample java_ee/
- -H參數(shù)指定了Docker后臺(tái)地址(使用TCP與后臺(tái)通訊);
- build是命令本身;
- -t指定了用于識(shí)別鏡像的標(biāo)簽名稱(chēng)(這里是javaee_sample);
- java_ee/是包含用于描述鏡像的Dockerfile的目錄。
上述命令的輸出如下:
然后我們可以通過(guò)列出鏡像命令(譯者注:docker images命令)來(lái)確認(rèn)剛創(chuàng)建的鏡像:docker -H tcp://127.0.0.1:2375 images:
啟動(dòng)容器
使用這一命令啟動(dòng)容器:
- docker -H tcp://127.0.0.1:2375 run -p 8180:8080 javaee_sample
- -p指定容器端口到主機(jī)端口的映射;
- run是命令本身;
- javaee_sample是鏡像名。
容器啟動(dòng)過(guò)程中會(huì)輸出Wildfly啟動(dòng)日志,這是因?yàn)槲覀儗⑵湓O(shè)置為初始命令(CMD Dockerfile命令):
運(yùn)行多個(gè)容器
我們可以實(shí)例化多個(gè)容器,因?yàn)樗鼈兊亩丝谠谒拗魃喜粫?huì)發(fā)生沖突。我將再啟動(dòng)兩個(gè)容器并將8080端口分別暴露為8280和8380:
- docker -H tcp://127.0.0.1:2375 run -p 8280:8080 javaee_sample
- docker -H tcp://127.0.0.1:2375 run -p 8380:8080 javaee_sample
要列出啟動(dòng)的容器,我們可以使用命令:docker -H tcp://127.0.0.1:2375 ps,這是輸出結(jié)果:
- rmpestano@rmpestano-ubuntu:~/docker /images$ docker -H tcp://127.0.0.1:2375 ps
- CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
- 7b9079806e69 javaee_sample:latest "/opt/wildfly/bin/st 27 seconds ago Up 27 seconds 9990/tcp, 0.0.0.0:8280->8080/tcp suspicious_lovelace
- d4975e825751 javaee_sample:latest "/opt/wildfly/bin/st 28 seconds ago Up 28 seconds 9990/tcp, 0.0.0.0:8380->8080/tcp loving_hopper
- 96e58eb65126 javaee_sample:latest "/opt/wildfly/bin/st 42 seconds ago Up 42 seconds 9990/tcp, 0.0.0.0:8180->8080/tcp clever_cori
現(xiàn)在我們可以在瀏覽器中同時(shí)訪(fǎng)問(wèn)這三個(gè)應(yīng)用:
你可以通過(guò)容器的ID或名字來(lái)停止容器:
- docker -H tcp://127.0.0.1:2375 stop suspicious_lovelace
記住,在容器刪除時(shí)所有數(shù)據(jù)將消失。請(qǐng)使用Docker卷來(lái)持久化數(shù)據(jù)。