用容器重新定義 Java 虛擬化部署實(shí)戰(zhàn)案例

兩天前小希和大家分享了《用容器定義 Java 虛擬化部署》俭驮,估計(jì)有些小伙伴早已按耐不住著急的心情了吧回溺。今天希云就和大家分享在容器里部署 Java 應(yīng)用的實(shí)戰(zhàn)案例。

Dockerfiles

Dockerfile 包含了一系列指令混萝,告訴容器如何去構(gòu)建一個(gè)鏡像遗遵,它指定了鏡像的基點(diǎn),以及配置鏡像的每個(gè)細(xì)節(jié)逸嘀。以下是一個(gè) Dockerfile 示例车要,是 CentOS 鏡像的 Dockerfile 。

代碼清單 1. CentOS Dockerfile

sh FROM scratch

MAINTAINER The CentOS Project <cloud-ops@centos.org> - ami_creator

ADD centos-7-20150616_1752-docker.tar.xz /

Volumes for systemd

VOLUME ["/run", "/tmp"]

Environment for systemd

ENV container=docker

For systemd usage this changes to /usr/sbin/init

Keeping it as /bin/bash for compatibility with previous

CMD ["/bin/bash"]

大部分內(nèi)容是注釋崭倘,主要有四句命令:

FROM scratch:所有 Dockerfile 都要從一個(gè)基礎(chǔ)鏡像繼承翼岁,在這個(gè)例子中类垫,CentOS 鏡像是繼承于" scratch "鏡像,這個(gè)鏡像是所有鏡像的根琅坡。這個(gè)配置是固定的悉患,表明了這個(gè)是容器的根鏡像之一。

MAINTAINER ...MAINTAINER指令指明了鏡像的所有者榆俺,這個(gè)例子中所有者是 CentOS Project购撼。

ADD centos...tar.xzADD指令告訴容器把指定文件上傳到鏡像中,如果文件是壓縮過的谴仙,會(huì)把它解壓到指定路徑迂求。這個(gè)例子中,容器會(huì)上傳一個(gè) CentOS 操作系統(tǒng)的 Gzip 包晃跺,并解壓到系統(tǒng)的根目錄揩局。

CMD ["/bin/bash"]:最后,CMD指令告訴容器要執(zhí)行什么命令掀虎,這個(gè)例子中凌盯,最后會(huì)進(jìn)入 Bourne Again Shell (bash) 終端。

這個(gè)架構(gòu)未必如你想象中那么簡(jiǎn)單烹玉,但我們接下來會(huì)慢慢學(xué)習(xí)它驰怎,其實(shí)它是非常有邏輯的。上邊已經(jīng)提過所有 Dockerfile 的根是 scratch二打,接下來指定的是 debian:jessie 鏡像县忌,這個(gè)官方鏡像是基于標(biāo)準(zhǔn)鏡像構(gòu)建的,容器不需要重復(fù)發(fā)明輪子继效,每次都創(chuàng)建一個(gè)新鏡像了症杏,只要基于一個(gè)穩(wěn)定的鏡像來繼續(xù)構(gòu)建新鏡像即可,在這個(gè)例子中瑞信, debian:jessie 是一個(gè)官方 Debian Linux 鏡像厉颤,就像上邊的 CentOS 一樣,它只有三行指令凡简。

代碼清單 2. debian:jessie Dockerfile

sh FROM scratch

ADD rootfs.tar.xz /

CMD ["/bin/bash"]

在上圖中我們還見到有安裝兩個(gè)額外的鏡像逼友,CURL 和 Source Code Management,鏡像buildpack-deps:jessie-curl的Dockerfile 如清單 3 所示秤涩。

代碼清單 3. buildpack-deps:jessie-curl Dockerfile

sh FROM debian:jessie

RUN apt-get update && apt-get install -y --no-install-recommends \

ca-certificates \

curl \

wget \

&& rm -rf /var/lib/apt/lists/*

這個(gè) Dockerfile 中使用 apt-get 去安裝 curlwget帜乞,使這個(gè)鏡像能從其他服務(wù)器下載軟件。RUN 指令讓Docker在運(yùn)行的實(shí)例中執(zhí)行具體的命令溉仑,這個(gè)例子中挖函,它會(huì)更新所有庫 (apt-get update),然后執(zhí)行 apt-get install 去安裝 curlwget

buildpack-deps:jessie-scp 的 Dockerfile 如清單 4 所示怨喘。

代碼清單 4. buildpack-deps:jessie-scp Dockerfile

sh FROM buildpack-deps:jessie-curl

RUN apt-get update && apt-get install -y --no-install-recommends \

bzr \

git \

mercurial \

openssh-client \

subversion \

&& rm -rf /var/lib/apt/lists/*

這個(gè)Dockerfile會(huì)安裝源碼管理工具津畸,例如 Git,Mercurial必怜,和 Subversion肉拓。

Java 的Dockerfile會(huì)更加復(fù)雜些,如清單 5 所示梳庆。

代碼清單 5. Java Dockerfile

sh FROM buildpack-deps:jessie-scm

A few problems with compiling Java from source:

1. Oracle. Licensing prevents us from redistributing the official JDK.

2. Compiling OpenJDK also requires the JDK to be installed, and it gets

really hairy.

RUN apt-get update && apt-get install -y unzip && rm -rf /var/lib/apt/lists/*

RUN echo 'deb http://httpredir.debian.org/debian jessie-backports main' > /etc/apt/sources.list.d/jessie-backports.list

Default to UTF-8 file.encoding

ENV LANG C.UTF-8

ENV JAVA_VERSION 8u66

ENV JAVA_DEBIAN_VERSION 8u66-b01-1~bpo8+1

see https://bugs.debian.org/775775

and https://github.com/docker-libr ... 46872

ENV CA_CERTIFICATES_JAVA_VERSION 20140324

RUN set -x \

&& apt-get update \

&& apt-get install -y \

openjdk-8-jdk="$JAVA_DEBIAN_VERSION" \

ca-certificates-java="$CA_CERTIFICATES_JAVA_VERSION" \

&& rm -rf /var/lib/apt/lists/*

see CA_CERTIFICATES_JAVA_VERSION notes above

RUN /var/lib/dpkg/info/ca-certificates-java.postinst configure

If you're reading this and have any feedback on how this image could be

improved, please open an issue or a pull request so we can discuss it!

簡(jiǎn)單來說暖途,這個(gè) Dockerfile 使用了安全參數(shù)去執(zhí)行 apt-get install -y openjdk-8-jdk 去下載安裝 Java,而 ENV 指令配置系統(tǒng)的環(huán)境變量膏执。

最后驻售,清單 6 是 Tomcat 的Dockerfile

代碼清單 6. Tomcat Dockerfile

sh FROM java:7-jre

ENV CATALINA_HOME /usr/local/tomcat

ENV PATH $CATALINA_HOME/bin:$PATH

RUN mkdir -p "$CATALINA_HOME"

WORKDIR $CATALINA_HOME

see https://www.apache.org/dist/tomcat/tomcat-8/KEYS

RUN gpg --keyserver pool.sks-keyservers.net --recv-keys \

05AB33110949707C93A279E3D3EFE6B686867BA6 \

07E48665A34DCAFAE522E5E6266191C37C037D42 \

47309207D818FFD8DCD3F83F1931D684307A10A5 \

541FBE7D8F78B25E055DDEE13C370389288584E7 \

61B832AC2F1C5A90F0F9B00A1C506407564C17A3 \

79F7026C690BAA50B92CD8B66A3AD3F4F22C4FED \

9BA44C2621385CB966EBA586F72C284D731FABEE \

A27677289986DB50844682F8ACB77FC2E86E29AC \

A9C5DF4D22E99998D9875A5110C01C5A2F6059E7 \

DCFD35E0BF8CA7344752DE8B6FB21E8933C60243 \

F3A04C595DB5B6A5F1ECA43E3B7BBB100D811BBE \

F7DA48BB64BCB84ECBA7EE6935CD23C10D498E23

ENV TOMCAT_MAJOR 8

ENV TOMCAT_VERSION 8.0.26

ENV TOMCAT_TGZ_URL https://www.apache.org/dist/tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz

RUN set -x \

&& curl -fSL "$TOMCAT_TGZ_URL" -o tomcat.tar.gz \

&& curl -fSL "$TOMCAT_TGZ_URL.asc" -o tomcat.tar.gz.asc \

&& gpg --verify tomcat.tar.gz.asc \

&& tar -xvf tomcat.tar.gz --strip-components=1 \

&& rm bin/*.bat \

&& rm tomcat.tar.gz*

EXPOSE 8080

CMD ["catalina.sh", "run"]

嚴(yán)格來說,Tomcat使用了Java 7的父級(jí)Dockerfile(默認(rèn)的最新Java版本是8)更米。這個(gè)Dockerfile設(shè)置了CATALINA_HOMEPATH環(huán)境變量欺栗,然后用mkdir命令新建了CATALINA_HOME目錄,WORKDIR指令把當(dāng)前工作路徑更改為CATALINA_HOME征峦,然后RUN指令執(zhí)行了同一行中一系列的命令:

下載Tomcat壓縮包迟几。

下載文件校驗(yàn)碼。

驗(yàn)證下載的文件正確栏笆。

解壓Tomcat壓縮包类腮。

刪除所有批處理文件(我們是在Linux上運(yùn)行)。

刪除壓縮包文件蛉加。

把這些命令寫在同一行蚜枢,對(duì)應(yīng)容器來說就是一條命令,最后容器會(huì)把執(zhí)行的結(jié)果緩存起來七婴,容器有個(gè)策略是檢測(cè)鏡像何時(shí)需要重建祟偷,以及驗(yàn)證構(gòu)建過程中的指令是否正確察滑。當(dāng)一條指令會(huì)使鏡像更改打厘,容器會(huì)把每個(gè)步的結(jié)果緩存起來,容器能把最上一個(gè)正確指令產(chǎn)生的鏡像啟動(dòng)起來贺辰。

EXPOSE 指令會(huì)讓容器啟動(dòng)一個(gè)容器時(shí)暴露指定的端口户盯,正如之前我們啟動(dòng)時(shí)那樣,我們需要告訴容器哪個(gè)物理端口會(huì)被映射到容器上(-p 參數(shù))饲化,EXPOSE 的作用就是這個(gè)定義容器端口莽鸭。最后 Dockerfile 使用 catalina.sh 腳本啟動(dòng) Tomcat。

簡(jiǎn)單回顧

用 Dockerfile 從頭開始構(gòu)建 Tomcat 是一個(gè)漫長的過程吃靠,我們總結(jié)一下目前為止的步驟:

安裝 Debian Linux硫眨。

安裝 curl 和 wget。

安裝源碼管理工具巢块。

下載并安裝 Java礁阁。

下載并安裝Tomcat巧号。

暴露容器實(shí)例的 8080 端口。

用 catalina.sh 啟動(dòng) Tomcat姥闭。

現(xiàn)在你應(yīng)該成為一個(gè) Dockerfile 專家了丹鸿,下一步我們將嘗試構(gòu)建一個(gè)自定義容器鏡像。

部署自定義應(yīng)用到容器

因?yàn)楸酒改现饕P(guān)注點(diǎn)是如何在容器中部署 Java 應(yīng)用棚品,而不是應(yīng)用本身靠欢,我會(huì)構(gòu)建一個(gè)簡(jiǎn)單的 Hello World servlet。你可以從GitHub獲取到這個(gè)項(xiàng)目铜跑,源碼并無任何特別门怪,只是一個(gè)輸出" Hello World! "的 servlet 。更加有趣的是相應(yīng)的Dockerfile锅纺,如清單 7 所示薪缆。

代碼清單 7. Hello World servlet 的 Dockerfile

sh FROM tomcatADD deploy /usr/local/tomcat/webapps

可能看起來不大一樣,但你應(yīng)該能理解以上代碼的作用是:

* FROM tomcat 指明這個(gè) Dockerfile 是基于 Tomcat 鏡像構(gòu)建伞广。

* ADD deploy 告訴容器把本地文件系統(tǒng)中的" deploy "目錄拣帽,復(fù)制到 Tomcat 鏡像中的 /usr/local/tomcat/webapps 路徑 。

在本地使用 maven 命令編譯這個(gè)項(xiàng)目:

sh mvn clean install

這樣將會(huì)生成一個(gè) war 包嚼锄,target/helloworld.war减拭,把這個(gè)文件復(fù)制到項(xiàng)目的 docker/deploy 目錄(你需要先創(chuàng)建好),最后你要使用上邊的 Dockerfile 構(gòu)建容器鏡像区丑,在項(xiàng)目的 docker 目錄中執(zhí)行以下命令:

sh docker build -t lygado/docker-tomcat.

這個(gè)命令讓容器從當(dāng)前目錄(用點(diǎn)號(hào).表示)構(gòu)建一個(gè)新的鏡像拧粪,并用" -t "打上標(biāo)簽 lygado/docker-tomcat,這個(gè)例子中沧侥,lygado 是我的 DockerHub 用戶名可霎, docker-image 是鏡像名稱(你需要替換成你自己的用戶名)。查看是否構(gòu)建成功你可以執(zhí)行以下命令:

sh $ docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

lygado/docker-tomcat latest ccb455fabad9 42 seconds ago 849.5 MB

最后宴杀,你可以用以下命令加載這個(gè)鏡像:

sh docker run -d -p 8080:8080 lygado/docker-tomcat

這個(gè)實(shí)例啟動(dòng)之后 癣朗,你可以用以下URL訪問(請(qǐng)把 URL 中的 IP 替換成你虛擬機(jī)的 IP ):

sh http://192.168.99.100:8080/helloworld/hello

還是那樣,你可以用容器的 ID 來終止這個(gè)實(shí)例旺罢。

Docker push

一旦你構(gòu)建并測(cè)試過了你的容器鏡像旷余,你可以把這個(gè)鏡像推送到你 DockerHub 的賬號(hào)中:

sh docker push lygado/docker-tomcat

這樣,你的鏡像就能被全世界訪問到了扁达,當(dāng)然正卧,為了隱私起見,你也可以推送到私有的容器倉庫跪解。下面炉旷,我們將把容器集成到應(yīng)用的構(gòu)建過程,目標(biāo)是在構(gòu)建應(yīng)用完成后,會(huì)產(chǎn)出一個(gè)包含應(yīng)用的容器鏡像窘行。

把容器集成到 Maven 構(gòu)建過程

在前邊的部分骏啰,我們創(chuàng)建了一個(gè)自定義的 Dockerfile,并把 WAR 包部署到它里邊抽高。這樣意味著把 WAR 包從項(xiàng)目的 target 目錄判耕,復(fù)制到 docker/deploy 目錄下,并且從命令行中運(yùn)行docker翘骂。這并沒花多少功夫壁熄,但如果你需要頻繁的改動(dòng)并測(cè)試代碼,你會(huì)發(fā)現(xiàn)這個(gè)過程很煩瑣碳竟。而且草丧,如果你需要在一個(gè) CI 服務(wù)器上構(gòu)建應(yīng)用,并產(chǎn)出一個(gè)容器鏡像莹桅,那你需要弄明白怎樣把容器和 CI 工具整合起來昌执。

現(xiàn)在我們嘗試一種更有效的方法,使用 Maven 和 Maven Docker 插件來構(gòu)建一個(gè)容器鏡像诈泼。

我的用例有這些:

1. 能創(chuàng)建基于 Tomcat 的容器鏡像懂拾,以用于部署我的應(yīng)用。

2. 能在測(cè)試中自行構(gòu)建铐达。

3. 能整合到前期集成測(cè)試和后期集成測(cè)試岖赋。

docker-maven-plugin 能滿足這些需求,而且易于使用和理解瓮孙。

關(guān)于 Maven Docker插件

這個(gè)插件本身有良好的文檔唐断,這里特別說明一下兩個(gè)主要的組件:

在 POM.xml 中配置容器鏡像的構(gòu)建和運(yùn)行。

描述哪些文件要包含在鏡像中杭抠。

清單 8 是 POM.xml 中插件的配置脸甘,定義了鏡像的構(gòu)建和運(yùn)行的配置。

代碼清單 8. POM 文件的 build 小節(jié)偏灿, Docker Maven plug-in 配置

xml <build>

<finalName>helloworld</finalName>

<plugins>

<plugin>

<groupId>org.jolokia</groupId>

<artifactId>docker-maven-plugin</artifactId>

<version>0.13.4</version>

<configuration>

<dockerHost>tcp://192.168.99.100:2376</dockerHost> <certPath>/Users/shaines/.docker/machine/machines/default</certPath>

<useColor>true</useColor>

<images>

<image>

<name>lygado/tomcat-with-my-app:0.1</name>

<alias>tomcat</alias>

<build>

<from>tomcat</from>

<assembly>

<mode>dir</mode

<basedir>/usr/local/tomcat/webapps</basedir

<descriptor>assembly.xml</descriptor>

</assembly>

</build>

<run>

<ports>

<port>8080:8080</port>

</ports>

</run>

</image>

</images>

</configuration>

</plugin>

</plugins>

</build>

正如你所見丹诀,這個(gè)配置相當(dāng)簡(jiǎn)單,包含了以下元素:

Plug-in 定義

groupId, artifactIdversion 這些信息指定要用哪個(gè)插件菩混。

全局設(shè)置

dockerHostcertPath 元素忿墅,定義了容器主機(jī)的位置,這些配置會(huì)用于啟動(dòng)容器沮峡,以及指定容器證書。容器證書的路徑在DOCKER_CERT_PATH 環(huán)境變量中能看到亿柑。

鏡像設(shè)置

build 元素下的所有 image 元素都定義在images 元素下邢疙,每個(gè) image 元素都有鏡像相關(guān)的配置,與buildrun 的配置一樣,主要的配置是鏡像的名稱疟游,在這個(gè)例子中呼畸,是我的 DockerHub 用戶名 (lygado),鏡像的名稱 (tomcat-with-my-app) 和鏡像的版本號(hào) ( 0.1 )颁虐。你也可以用 Maven 的屬性來定義這些值蛮原。

鏡像構(gòu)建配置

一般構(gòu)建鏡像時(shí),我們會(huì)使用 docker build 命令另绩,以及一個(gè) Dockerfile 來定義構(gòu)建過程儒陨。Maven Docker 插件也允許你使用 Dockerfile,但在例子中笋籽,我們使用一個(gè)運(yùn)行時(shí)生成在內(nèi)存中的 Dockerfile 來構(gòu)建蹦漠。因此,我們?cè)?from 元素中定義父級(jí)鏡像车海,這個(gè)例子中是 tomcat笛园,然后在 assembly 中作其他配置。

使用 Maven 的 maven-assembly-plugin侍芝,可以定義一個(gè)項(xiàng)目的輸出內(nèi)容研铆,指定包含依賴,模塊州叠,文檔蚜印,或其他文件到一個(gè)獨(dú)立分發(fā)的包中。docker-maven-plugin 繼承了這個(gè)標(biāo)準(zhǔn)留量,在這個(gè)例子中窄赋,我們選擇了 dir 模式,也就是說定義在 src/main/docker/assembly.xml 中的文件會(huì)被拷貝到容器鏡像中的 basedir 中楼熄。其他模式還有 tar忆绰,tgzzipbasedir 元素中定義了放置文件的路徑可岂,這個(gè)例子中是Tomcat 的 webapps 目錄错敢。

最后,descriptor 元素指定了 assembly 文件缕粹,這個(gè)文件位于 basedir 中定義的 src/main/docker 中稚茅。以上是一個(gè)很簡(jiǎn)單的例子,我建議你通讀一下相關(guān)文檔平斩,特別地亚享,可以了解 entrypointcmd 元素,這兩個(gè)元素可以指定啟動(dòng)容器鏡像的命令绘面,env元素可以指定環(huán)境變量欺税,runCmds 元素類似 Dockerfile 中的RUN 指令侈沪,workdir 元素可以指定工作路徑,volumes 元素可以指定要掛載的磁盤卷晚凿。簡(jiǎn)言之亭罪,這個(gè)插件實(shí)現(xiàn)了所有Dockerfile 中所需要的語法,所以前面所用到的 Dockerfile 指令都可以在這個(gè)插件中使用歼秽。

鏡像運(yùn)行配置

啟動(dòng)容器鏡像時(shí)會(huì)用到 docker run 命令应役,你可以傳一些參數(shù)給容器。這個(gè)例子中燥筷,我們要用 docker run -d -p 8080:8080 lygado/tomcat-with-my-app:0.1 這個(gè)命令啟動(dòng)鏡像箩祥,所以我們只需要指定一下端口映射。

run 元素可以讓我們指定所有運(yùn)行時(shí)參數(shù)荆责,所以我們指定了把容器中的 8080 映射到容器宿主機(jī)的 8080滥比。另外,還可以在 run 這節(jié)中指定要掛載的卷(使用volumes)做院,或者要鏈接起來的容器(使用links)盲泛。docker:start在集成測(cè)試中很常用,在 run 小節(jié)中键耕,我們可以使用 wait 參數(shù)來指定一個(gè)時(shí)間周期寺滚,這樣就可以等待到某個(gè)日志輸出,或者一個(gè) URL 可用時(shí)屈雄,才繼續(xù)執(zhí)行下去村视,這樣就可以保證在集成測(cè)試開始前鏡像已經(jīng)運(yùn)行起來了。

加載依賴

src/main/docker/assembly.xml 文件定義了哪些文件需要復(fù)制到容器鏡像中酒奶,如清單 9 所示:

清單 9. assembly.xml

xml <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 http://maven.apache.org/xsd/assembly-1.1.2.xsd">

<dependencySets>

<dependencySet>

<includes>

<include>com.geekcap.vmturbo:hello-world-servlet-example</include>

</includes>

<outputDirectory>.</outputDirectory>

<outputFileNameMapping>helloworld.war</outputFileNameMapping>

</dependencySet>

</dependencySets>

</assembly>

在清單 9 中蚁孔,我們可以看到包含 hello-world-servlet-example 在內(nèi)的一個(gè)依賴集合,以及復(fù)制的目標(biāo)路徑惋嚎,outputDirectory 這個(gè)路徑是相對(duì)于前面提到的 basedir 的杠氢,也就是 Tomcat 的 webapps 目錄。

這個(gè)插件有以下幾個(gè) Maven targets:

1. docker:build: 構(gòu)建鏡像

2. docker:start: 啟動(dòng)鏡像

3. docker:stop: 停止鏡像

4. docker:push: 把鏡像推送到鏡像倉庫另伍,如DockerHub

5. docker:remove: 本地刪除鏡像

6. docker:logs: 輸出容器日志

構(gòu)建鏡像

你可以從GitHub中獲取源碼鼻百,然后用下邊的命令構(gòu)建:

sh mvn clean install

用以下命令構(gòu)建容器鏡像:

sh mvn clean package docker:build

一旦鏡像構(gòu)建成功,你可以在 docker images 的返回結(jié)果中看到:

sh $ docker images

REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE

lygado/tomcat-with-my-app 0.1 1d49e6924d19 16 minutes ago 347.7 MB

可以用以下命令啟動(dòng)鏡像:

sh mvn docker:start

現(xiàn)在可以在docker ps中看到已經(jīng)啟動(dòng)了摆尝,然后可以通過以下URL訪問:

sh http://192.168.99.100:8080/helloworld/hello

最后温艇,可以用以下命令停止容器:

sh mvn docker:stop

總結(jié)

容器是一種使進(jìn)程虛擬化的容器技術(shù),它提供了一系列容器客戶端命令來調(diào)用容器守護(hù)進(jìn)程堕汞。在 Linux 上勺爱,容器守護(hù)進(jìn)程可以直接運(yùn)行于 Linux 操作系統(tǒng),但是在 Windows 和 Mac 上臼朗,需要有一個(gè) Linux 虛擬機(jī)來運(yùn)行容器守護(hù)進(jìn)程邻寿。容器鏡像包含了一個(gè)輕量級(jí)的操作系統(tǒng)蝎土,還額外包含了應(yīng)用運(yùn)行的依賴庫视哑。容器鏡像由 Dockerfile 定義绣否,可以在 Dockerfile 中包含一系列配置鏡像的指令。

在這個(gè)開源 Java 項(xiàng)目指南中挡毅,我介紹了容器的基礎(chǔ)蒜撮,講解了 CentOS、Java跪呈、Tomcat 等鏡像的 Dockerfile 細(xì)節(jié)段磨,并演示了如何用 Tomcat 鏡像來構(gòu)建新的鏡像。最后耗绿,我們使用 docker-maven-plugin 來把容器集成到 Maven 的構(gòu)建過程中苹支。通過這樣,使得測(cè)試更加簡(jiǎn)單了误阻,還可以把構(gòu)建過程配置在 CI 服務(wù)器上部署到生產(chǎn)環(huán)境债蜜。

本文中的示例應(yīng)用非常簡(jiǎn)單,但是涉及的構(gòu)建步驟同樣可以用在更復(fù)雜的企業(yè)級(jí)應(yīng)用中究反。好好享受容器帶給我們的樂趣吧敷钾。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末组底,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌蓖宦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,496評(píng)論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件弦悉,死亡現(xiàn)場(chǎng)離奇詭異矾湃,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)惊完,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,407評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門僵芹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人专执,你說我怎么就攤上這事淮捆。” “怎么了本股?”我有些...
    開封第一講書人閱讀 162,632評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵攀痊,是天一觀的道長。 經(jīng)常有香客問我拄显,道長苟径,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,180評(píng)論 1 292
  • 正文 為了忘掉前任躬审,我火速辦了婚禮棘街,結(jié)果婚禮上蟆盐,老公的妹妹穿的比我還像新娘。我一直安慰自己遭殉,他們只是感情好石挂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,198評(píng)論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著险污,像睡著了一般痹愚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蛔糯,一...
    開封第一講書人閱讀 51,165評(píng)論 1 299
  • 那天拯腮,我揣著相機(jī)與錄音,去河邊找鬼蚁飒。 笑死动壤,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淮逻。 我是一名探鬼主播琼懊,決...
    沈念sama閱讀 40,052評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼弦蹂!你這毒婦竟也來了肩碟?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,910評(píng)論 0 274
  • 序言:老撾萬榮一對(duì)情侶失蹤凸椿,失蹤者是張志新(化名)和其女友劉穎削祈,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體脑漫,經(jīng)...
    沈念sama閱讀 45,324評(píng)論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡髓抑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,542評(píng)論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了优幸。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片吨拍。...
    茶點(diǎn)故事閱讀 39,711評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖网杆,靈堂內(nèi)的尸體忽然破棺而出羹饰,到底是詐尸還是另有隱情,我是刑警寧澤碳却,帶...
    沈念sama閱讀 35,424評(píng)論 5 343
  • 正文 年R本政府宣布队秩,位于F島的核電站,受9級(jí)特大地震影響昼浦,放射性物質(zhì)發(fā)生泄漏馍资。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,017評(píng)論 3 326
  • 文/蒙蒙 一关噪、第九天 我趴在偏房一處隱蔽的房頂上張望鸟蟹。 院中可真熱鬧乌妙,春花似錦、人聲如沸建钥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,668評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锦针。三九已至荠察,卻和暖如春置蜀,著一層夾襖步出監(jiān)牢的瞬間奈搜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,823評(píng)論 1 269
  • 我被黑心中介騙來泰國打工盯荤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留馋吗,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,722評(píng)論 2 368
  • 正文 我出身青樓秋秤,卻偏偏與公主長得像宏粤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子灼卢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,611評(píng)論 2 353

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