使用 Dockerfile定製Java Web鏡像

1、前言

使用 Docker 搭建 Java Web 運行環境(利用 commit 理解鏡像構成  來源:黃勇 )博文的概括:php

一、啓動容器:java

docker run <相關參數> <鏡像 ID> <初始命令>

-i:表示以「交互模式」運行容器
-t:表示容器啓動後會進入其命令行
-v:表示須要將本地哪一個目錄掛載到容器中,格式:-v <宿主機目錄>:<容器目錄>

進入容器,配置環境,exitlinux

二、查看全部容器 : 
docker container ls -a      或者 docker ps -agit

三、docker commit 的語法格式爲:
docker commit [選項] <容器ID或容器名> [<倉庫名>[:<標籤>]]web

--author "wwx<wuweixiang.alex@gmail.com>" \
--message "修改了默認網頁" \

docker commit 57c312bbaad1 huangyong/javaweb:0.1docker

四、啓動容器:
docker run <相關參數> <鏡像 ID> <初始命令>shell

 

慎用 docker commit,利用 commit 鏡像構成,意味着全部對鏡像的操做都是黑箱操做,生成的鏡像也被稱爲黑箱鏡像。若是使用 docker commit 製做鏡像,以及後期修改的話,每一次修改都會讓鏡像更加臃腫一次,所刪除的上一層的東西並不會丟失,會一直如影隨形的跟着這個鏡像,即便根本沒法訪問到。這會讓鏡像更加臃腫。apache

2、使用 Dockerfile 定製Java Web鏡像

Ⅰ、Dockerfile回顧

《Docker學習——建立鏡像(四)》json

《Docker學習——Dockerfile 指令詳解(五)》centos

①Dockerfile簡介

Dockerfile 是一個文本文件,其內包含了一條條的指令(Instruction),每一條指令構建一層,所以每一條指令的內容,就是描述該層應當如何構建。

②Dockerfile指令詳解

#指定基礎鏡像 
FROM   

Dockerfile中必備指令,而且必須是第一條指令

FROM scratch   不以任何鏡像爲基礎,接下來的指令將做爲鏡像第一層開始存在

#指定維護者信息
MAINTAINER
格式: 
MAINTAINER <name>


#執行命令行命令
RUN  
定義每一層該如何構建(不是在寫 Shell 腳本) 每個 RUN = 啓動一個容器、執行命令、而後提交存儲層文件變動
兩行 RUN 命令的執行環境不一樣

格式:
1) shell 格式: RUN <命令>                                   #相似命令行輸入
2) exec  格式: RUN ["可執行文件", "參數1", "參數2"]           #相似函數調用

行尾 \ 換行
行首 # 註釋
&& 命令串聯

#複製文件
COPY 
格式: 
1) COPY <源路徑>... <目標路徑> 
2) COPY ["<源路徑1>",... "<目標路徑>"]

<源路徑> 能夠是多個,甚至能夠是通配符   #上下文路徑的相對路徑
<目標路徑> 能夠是容器內的絕對路徑,也能夠是相對於工做目錄的相對路徑(工做目錄能夠用 WORKDIR 指令來指定)

#更高級的複製文件
ADD
<源路徑> 能夠是一個 URL,
若是是gzip , bzip2 以及 xz 的狀況下,ADD 指令將會自動解壓縮這個壓縮文件到 <目標路徑> 去
全部的文件複製均使用COPY 指令,僅在須要自動解壓縮的場合使用 ADD

#容器啓動命令
CMD 
容器就是進程。 既然是進程,在啓動的時候,須要指定所運行的程序及參數。
CMD 指令就是用於指定默認的容器主進程的啓動命令

對於容器而言,其啓動程序就是容器應用進程,容器就是爲了主進程而存在的,主進程退出容器就失去了存在的意義,從而退出,其它輔助進程不是它須要關心的東西。

格式: 
1) shell 格式:  CMD <命令>
2) exec  格式:  CMD ["可執行文件", "參數1", "參數2"...]
通常推薦使用 exec 格式,這類格式在解析時會被解析爲 JSON 數組,所以必定要使用雙引號 " ,而不要使用單引號

CMD echo $HOME 在實際執行中,會將其變動爲: CMD [ "sh", "-c", "echo $HOME" ]

#入口點
ENTRYPOINT 
和 CMD 同樣,都是在指定容器啓動程序及參數

實際執行時,將變爲: <ENTRYPOINT> "<CMD>"   #啓動時,可再對可執行文件進行傳參

ENTRYPOINT ["docker-entrypoint.sh"]      #應用運行前的準備工做,指定了 ENTRYPOINT 爲 docker-entrypoint.sh 腳本,而且可在鏡像啓動時候傳入參數來服務腳本

#設置環境變量
ENV 
格式: 
1) ENV <key> <value> 
2) ENV <key1>=<value1> <key2>=<value2>...

#構建參數
ARG 
和 ENV 所不一樣的是, ARG 所設置的構建環境的環境變量,在未來容器運行時不會存在這些環境變量的。
格式: 
ARG <參數名>[=<默認值>]

能夠在構建命令docker build 中用 --build-arg <參數名>=<值> 來覆蓋

#定義匿名卷
VOLUME 

爲了防止運行時用戶忘記將動態文件所保存目錄掛載爲卷(volume),指定某些目錄掛載爲匿名卷,這樣在運行時若是用戶不指定掛載,應用也能夠正常運行,不會向容器存儲層寫入大量數據

格式: 
1) VOLUME <路徑>
2) VOLUME ["<路徑1>", "<路徑2>"...] 

VOLUME /data 
這裏的 /data 目錄就會在運行時自動掛載爲匿名卷,任何向 /data 中寫入的信息都不會記錄進容器存儲層

-v mydata:/data
mydata 這個命名卷掛載到了 /data 這個位置,替代了Dockerfile 中定義的匿名卷的掛載配置

#聲明端口
EXPOSE 
聲明運行時容器提供服務端口

#指定工做目錄
WORKDIR 
改變之後各層的工做目錄
格式:
WORKDIR <工做目錄路徑> 

至關於 cd  

...
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd

則最終路徑爲 /a/b/c

#指定當前用戶
USER 
USER 指令和 WORKDIR 類似,都是改變環境狀態並影響之後的層
USER 只是幫助你切換到指定用戶而已,這個用戶必須是事先創建好的,不然沒法切換。

#健康檢查
HEALTHCHECK 
格式: 
1) HEALTHCHECK [選項] CMD <命令>          #設置檢查容器健康情況的命令 
2) HEALTHCHECK NONE                      #若是基礎鏡像有健康檢查指令,使用這行能夠屏蔽掉其健康檢查指令

HEALTHCHECK 支持下列選項:
--interval=<間隔> :兩次健康檢查的間隔,默認爲 30 秒;
--timeout=<時長> :健康檢查命令運行超時時間,若是超過這個時間,本次健康檢查就被視爲失敗,默認 30 秒;
--retries=<次數> :當連續失敗指定次數後,則將容器狀態視爲 unhealthy ,默認 3次。和 CMD , ENTRYPOINT 同樣, HEALTHCHECK 只能夠出現一次,若是寫了多個,只有最後一個生效。

HEALTHCHECK --interval=5s --timeout=3s \ 
CMD curl -fs http://localhost/ || exit 1

#爲他人作嫁衣裳
ONBUILD 
當以當前鏡像爲基礎鏡像,去構建下一級鏡像的時候纔會被執行
格式: 
ONBUILD <其它指令> 

作一個基礎鏡像,基礎鏡像更新,各個項目不用同步 Dockerfile 的變化,從新構建後就繼承了基礎鏡像的更新

③構建鏡像

#構建鏡像 
docker build [選項] <指定上下文路徑/URL/-> 

鏡像並不是在本地構建,而是在服務端,也就是鏡像是在 Docker 引擎中構建的。那麼在這種客戶端/服務端的架構中,如何才能讓服務端得到本地文件呢? 
構建候,用戶會指定構建鏡像上下文的路徑, docker build 命令得知這個路徑會將路徑下的全部內容打包,而後上傳給 Docker 引擎。
這樣Docker 引擎收到這個上下文包後,展開就會得到構建鏡像所需的一切文件 

初學者常常會問的爲何COPY ../package.json /app 或者 COPY /opt/xxxx /app 沒法工做的緣由,由於這些路徑已經超出了上下文的範圍Docker 引擎沒法得到這些位置的文件。 

例如:COPY ./package.json /app/  是複製 上下文(context) 目錄下的package.json   #COPY 這類指令中的源文件的路徑上下文路徑的相對路徑 

-f ../Dockerfile.php 參數指定某個文件做爲Dockerfile 
其它 docker build 的用法 
直接用 Git repo 進行構建:Docker 就會本身去 git clone 這個項目、切換到指定分支、並進入到指定目錄後開始構建 
用給定的 tar 壓縮包構建:Docker 引擎會下載這個包,並自動解壓縮,以其做爲上下文,開始構建

Ⅱ、Dockerfile的編寫

1.0.0 Dockerfile

# 版本信息
FROM centos:7
MAINTAINER wuweixiang <wuweixiang.alex@gmail.com>
# 設置工做目錄
WORKDIR /var/
# 添加jdk、tomcat
ADD jdk-8u191-linux-x64.tar.gz .
#ADD http://mirrors.hust.edu.cn/apache/tomcat/tomcat-8/v8.5.35/bin/apache-tomcat-8.5.35.tar.gz .
ADD apache-tomcat-8.5.35.tar.gz .

# 設置環境變量
ENV JAVA_HOME /var/jdk1.8.0_191
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/bin
ENV TIME_ZONE Asia/Shanghai

# 更改時區
RUN set -x \
&& echo "${TIME_ZONE}" > /etc/timezone \
&& ln -sf /usr/share/zoneinfo/${TIME_ZONE} /etc/localtime

# 開啓內部服務端口
EXPOSE 8080

# 啓動tomcat服務器
CMD ["/var/apache-tomcat-8.5.35/bin/catalina.sh","run"] && tail -f /var/apache-tomcat-8.5.35/logs/catalina.out

Ⅲ、構建方式(鏡像已push,此步可忽略)

①linux安裝git

sudo yum install git

②克隆項目源碼

git clone https://gitee.com/wuweixiang/javaweb-docker.git

③構建鏡像

進入到/javaweb-docker/dockerfile-java8-tomcat8目錄下:

docker build -t  [<倉庫名>[:<標籤>]] .  #建立鏡像 


倉庫名:常常以 兩段式路徑 形式出現,好比 wuweixiang/javaweb:1.0.0,前者Docker帳號用戶名,後者則每每是對應的軟件名。
    
標籤:指定所需哪一個版本的鏡像,默認latest。

Ⅳ、使用方式

 一、新購買的服務器,安裝docker,執行如下指令:

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

 二、建立/var/webapps/目錄,並將war包放入該目錄下

 三、運行如下命令,便可實現部署。

docker run -d -p 80:8080 \
-v /var/webapps/:/var/apache-tomcat-8.5.35/webapps/ \
--name <容器名>  \
wuweixiang/javaweb:1.0.0

 注意: 

  掛載路徑 /var/webapps/  爲當前war上傳位置

Ⅴ、使用示例

一、下載一個war包到掛載路徑/var/webapps/下:

可見,war包自動完成解壓。

二、便可訪問http://112.74.185.172/finder-web-2.4.9

Ⅵ、總結

  該部署方式與以前的部署方式上,省去了jdk、tomcat環境的配置過程,只要上傳war包便可。

相關文章
相關標籤/搜索