在 Docker 中構建鏡像最常用的方式就是使用 Dockerfile。Dockerfile 是一個用來構建鏡像的文本文件。 官方文檔:https://docs.docker.com/engine/reference/builder/ 一、Dockerfile常用命令 對官方文檔的一個翻譯: 1.1 ...
在 Docker 中構建鏡像最常用的方式就是使用 Dockerfile。Dockerfile 是一個用來構建鏡像的文本文件。
官方文檔:https://docs.docker.com/engine/reference/builder/
一、Dockerfile常用命令
對官方文檔的一個翻譯:
1.1 FROM
語法:FROM <image>:<tag>
指明構建的新鏡像是來自於那個基礎鏡像,如果沒有選擇tag,那麼預設為 Latest。
FROM centos:7
如果不以任何鏡像為基礎,那麼 寫法為:FROM scratch
。scratch 鏡像是一個空鏡像,可以用於構建 busybox 等超小鏡像,可以說是真正的從零開始構建屬於自己的鏡像。
1.2 LABEL
語法:LABEL <key>=<value> <key>=<value> <key>=<value> ...
功能是為鏡像指定標簽。也可以使用 LABEL 來指定鏡像作者。
LABEL maintainer="xxx.com"
1.3 RUN
語法:RUN <command>
構建鏡像時運行的 Shell 命令,比如構建的新鏡像中想在 /usr/local 目錄下創建一個 Java 目錄。
RUN mkdir -p /usr/local/java
1.4 ADD
語法:ADD <src>... <dest>
拷貝文件或目錄到鏡像中。src 可以是一個本地文件或者是一個本地壓縮文件,壓縮文件會自動解壓。還可以是一個 url ,如果把 src 寫成一個url,那麼 ADD 就類似於 wget 命令,然後自動下載和解壓。
ADD jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java
1.5 COPY
語法:COPY <src>... <dest>
拷貝文件或目錄到鏡像中。用法和 ADD 一樣,只是不支持自動下載和解壓。
COPY jdk-11.0.6_linux-x64_bin.tar.gz /usr/local/java
1.6 EXPOSE
語法:EXPOSE <port> [<port>/<protocol>...]
暴露容器運行時的監聽埠給外部,可以指定埠是監聽 TCP 還是 UDP,如果未指定協議,則預設為 TCP。
EXPOSE 80 443 8080/tcp
1.7 ENV
語法:ENV <key> <value>
添加單個,ENV <key>=<value> ...
添加多個。
設置容器內環境變數。
ENV JAVA_HOME /usr/local/java/jdk-11.0.6/
1.8 CMD
語法:
CMD ["executable", "param1", "param2"]
- 示例:
CMD ["/usr/local/tomcat/bin/catalina.sh", "run"]
- 示例:
CMD ["param1", "param2"]
- 示例:
CMD ["echo", "$JAVA_HOME"]
- 示例:
CMD command param1 param2
- 示例:
CMD echo $JAVA_HOME
- 示例:
啟動容器時執行的 Shell 命令,在 DOckerfile 中只能有一條 CMD 命令,如果設置了多條 CMD,只有最後一條 CMD 會生效。
CMD echo $JAVA_HOME
如果創建容器的時候指定了命令,則 CMD 命令會被替代。
假如鏡像叫
centos:7
,創建容器時命令是:docker run -it --name centos7 centos:7 echo "helloworld"
或者docker run -it --name centos7 centos:7 /bin/bash
,就不會輸出$JAVA_HOME
的環境變數信息了,應為 CMD 命令被echo "helloworld"
、/bin/bash
覆蓋了。
1.9 ENTRYPOINT
語法:
ENTRYPOINT ["executable", "param1", "param2"]
- 示例:
ENTRYPOINT ["/usr/local/tomact/bin/catalina.sh", "run"]
- 示例:
ENTRYPOINT command param1 param2
- 示例:
ENTRYPOINT echo $JAVA_HOME
- 示例:
啟動容器時執行的 Shell 命令,同 CMD 類似,不會被 docker run 命令指定的參數所覆蓋,在Dockerfile 中只能有一條 ENTRYPOINT 指令,如果設置了多條 ENTRYPOINT,只有最後一條 ENTRYPOINT 會生效。
ENTRYPOINT ehco $JAVA_HOME
如果在 Dockerfile 中同時寫了 ENTRYPOINT 和 CMD,並且 CMD 指令不是一個完整的可執行命令,那麼 CMD 指定的內容將會作為 ENTRYPOINT 的參數;
如果在 Dockerfile 中同時寫了 ENTRYPOINT 和 CMD,並且 CMD 是一個完整的指令,那麼它兩會互相覆蓋,誰在最後誰生效;
1.10 WORKDIR
語法:WORKDIR /path/to/workdir
為 RUN、CMD、ENTRYPOINT 以及 COPY 和 AND 設置工作目錄。
WORKDIR /usr/local
1.11 WOLUME
指定容器掛載點到宿主機自動生成的目錄或其他容器,一般的使用場景為需要持久化存儲數據時。
# 容器的 /var/lib/mysql 目錄會在運行時自動掛載為匿名捲,匿名捲在宿主機的 /var/lib/docker/volumes 目錄下
VOLUME ["/var/lib/mysql"]
一般不會在 Dockerfile 中用到,更常見的還是在 docker run 的時候通過 -v 指定數據捲。
二、構建鏡像
Dockerfile 文件編寫好了以後,真正構建鏡像時需要通過 docker build
命令。
docker build
命令用於使用 Dockerfile
創建鏡像。
# 使用當前目錄的 Dockerfile 創建鏡像
docker build -t mycentos:7
# 通過 -f Dockerfile 文件的位置創建鏡像
docker build -f /usr/local/dockerfile/Dockerfile -t mycentos:7 .
-f
:指定要使用的 Dockerfile 路徑;--tag, -t
:鏡像的名字及標簽,可以在一次構建中為一個鏡像設置多個標簽。
在使用
docker build
命令的去構建鏡像時,通常都會看到命令最後會有一個.
號,多數人認為它是用來指定Dockerfile
文件所在位置的,但其實-f
才是。當使用
docker build
命令構建鏡像的時候,如果在Dockerfile
中使用了一些ADD
等指令來操作文件,為了使Docker
引擎獲取到這些文件,當在構建的時候,就會由用戶指定構建鏡像時的上下文路徑,docker build
會將這個路徑下所有的文件都打包上傳給Docker 引擎
,從而獲取到文件。可以理解為傳入這個路徑拼接上 Dockerfile 文件中需要操作文件的路徑,
.
代表當前路徑,也就是說當前路徑拼接到需要操作的文件路徑從而拿到絕對路徑。(只是個比喻)
三、Dockerfile 實踐
通過基礎鏡像 centos:7
,在該鏡像中安裝 jdk 和 Tomcat 以後製作為一個新的鏡像。
創建目錄
mkdir -p /usr/local/dockerfile
編寫 Dockerfile 文件
vi Dockerfile
Dockerfile 文件內容如下:
# 指明構建鏡像是來自於 centos:7 基礎鏡像
FROM centos:7
# 通過鏡像標簽聲明作者信息
LABEL maintainer="xiaoyang.com"
# 設置工作目錄
WORKDIR /usr/local
# 新鏡像構建成功後創建指定目錄
RUN mkdir -p /usr/local/java && mkdir -p /usr/local/tomcat
## 拷貝文件到鏡像中並解壓
ADD jdk-11.0.7_linux-x64_bin.tar.gz /usr/local/java
ADD apache-tomcat-9.0.39.tar.gz /usr/local/tomcat
# 暴露容器運行時的 8080 監聽埠給外部
EXPOSE 8080
# 設置容器內 JAVA_HOME 環境變數
ENV JAVA_HOME /usr/local/java/jdk-11.0.7/
ENV PATH $PATH:$JAVA_HOME/bin
# 啟動容器時啟動 Tomcat
CMD ["/usr/local/tomcat/apache-tomcat-9.0.39/bin/catalina.sh", "run"]
構建鏡像
docker build -f /usr/local/dockerfile/Dockerfile -t mycentos:7 /root/
查看鏡像構建歷史
docker history 鏡像名稱:標簽|ID
docker history mycentos:7
使用構建的鏡像創建容器
# 創建容器
docker run -id --name mycentos7 -p 8080:8080 mycentos:7
# 進入容器
docker exec -it mycentos7 /bin/bash
# 測試 Java 環境變數
[root@a12ceba19e75 ~]# java -version
java version "11.0.7" 2020-04-14 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.7+8-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.7+8-LTS, mixed mode)
訪問 http://192.168.88.131:8080/ 看到頁面說明環境正常!
學習之旅