映象就是包含了應用程式、程式執行的系統函數庫、執行設定等檔案的檔案包。構建映象的過程其實就是把上述檔案打包的過程。
我們要從0部署一個Java應用,大概流程是這樣:
準備Linux執行環境(java專案並不需要完整的作業系統,僅僅是基礎執行環境即可)
安裝並設定JDK
拷貝jar包
設定啟動指令碼
映象檔案不是隨意堆放的,而是按照操作的步驟分層疊加而成,每一層形成的檔案都會單獨打包並標記一個唯一id,稱為Layer(層)。這樣,如果我們構建時用到的某些層其他人已經制作過,就可以直接拷貝使用這些層,而不用重複製作。
例如,第一步中需要的Linux執行環境,通用性就很強,所以Docker官方就製作了這樣的只包含Linux執行環境的映象。我們在製作java映象時,就無需重複製作,直接使用Docker官方提供的CentOS或Ubuntu映象作為基礎映象。然後再搭建其它層即可,這樣逐層搭建,最終整個Java專案的映象結構如圖所示:
由於製作映象的過程中,需要逐層處理和打包,比較複雜,所以Docker就提供了自動打包映象的功能。我們只需要將打包的過程,每一層要做的事情用固定的語法寫下來,交給Docker去執行即可。
而這種記錄映象結構的檔案就稱為Dockerfile,其對應的語法可以參考官方檔案:
https://docs.docker.com/engine/reference/builder/
其中的語法比較多,比較常用的有:
指令 | 說明 | 範例 |
---|---|---|
FROM | 指定基礎映象 | FROM centos:7 |
ENV | 設定環境變數,可在後面指令使用 | ENV key value |
COPY | 拷貝本地檔案到映象的指定目錄 | COPY ./xx.jar /tmp/app.jar |
RUN | 執行Linux的shell命令,一般是安裝過程的命令 | RUN yum install gcc |
EXPOSE | 指定容器執行時監聽的埠,是給映象使用者看的; 但是後面還是需要-p來做埠對映的 |
EXPOSE 8080 |
ENTRYPOINT | 映象中應用的啟動命令,容器執行時呼叫 | ENTRYPOINT java -jar xx.jar |
例如,要基於Ubuntu映象來構建一個Java應用,其Dockerfile內容如下:
# 指定基礎映象
FROM ubuntu:16.04
# 設定環境變數,JDK的安裝目錄、容器內時區
ENV JAVA_DIR=/usr/local
ENV TZ=Asia/Shanghai
# 拷貝jdk和java專案的包
COPY ./jdk8.tar.gz $JAVA_DIR/
COPY ./docker-demo.jar /tmp/app.jar
# 設定時區
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 安裝JDK
RUN cd $JAVA_DIR \
&& tar -xf ./jdk8.tar.gz \
&& mv ./jdk1.8.0_144 ./java8
# 設定環境變數
ENV JAVA_HOME=$JAVA_DIR/java8
ENV PATH=$PATH:$JAVA_HOME/bin
# 指定專案監聽的埠
EXPOSE 8080
# 入口,java專案的啟動命令
ENTRYPOINT ["java", "-jar", "/app.jar"]
以後我們會有很多java專案需要打包為映象,它們都需要Linux系統環境、JDK環境這兩層,只有上面的3層不同(因為jar包不同)。如果每次製作java映象都重複製作前兩層映象,是很麻煩的。
所以,就有人提供了基礎的系統加JDK環境,我們在此基礎上製作java映象,就可以省去JDK的設定了:
FROM openjdk:11.0-jre-buster
# 設定時區
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷貝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
在/root/demo目錄下有如下兩個檔案
其中docker-demo.jar是Java專案;Dockerfile如下:
# 基礎映象
FROM openjdk:11.0-jre-buster
# 設定時區
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 拷貝jar包
COPY docker-demo.jar /app.jar
# 入口
ENTRYPOINT ["java", "-jar", "/app.jar"]
然後,執行命令,構建映象:
# 進入映象目錄
cd /root/demo
# 開始構建
docker build -t docker-demo:1.0 .
docker build
: 就是構建一個docker映象
-t docker-demo:1.0
:-t
引數是指定映象的名稱(repository
和tag
)
.
: 最後的點是指構建時Dockerfile所在路徑,由於我們進入了demo目錄,所以指定的是.
代表當前目錄,也可以直接指定Dockerfile目錄:
# 直接指定Dockerfile目錄
docker build -t docker-demo:1.0 /root/demo
如果沒有指定Dockerfile的名字,就必須叫Dockerfile。
執行結果如下:
檢視映象
可以看到多了一個docker-demo的映象;
嘗試執行:
docker run -d --name dd -p 8080:8080 docker-demo:1.0