Create a Image with Dockerfile
Ubuntu: 18.04
Docker: 18.09
在很多狀況下,Docker Hub 上面的 Image
,可能都不太符合我們的使用需求,因此我們就會需要自己客製一個屬於自己的 Docker Image
,但如果先隨便建一個 Container
再慢慢裝自己想要的東西,一來指令跟裝的東西不好控管、二來是時間成本太高,這時候就需要 Dockerfile 來幫忙了。
Dockerfile
是一個設置你 Docker Image
的文件,根據文件內容再搭配 Docker build
指令就可以產生出 Docker Image
。
Dockerfile
在開始之前,先介紹一下在 Dockerfile
中可以使用的指令。
Name | Description |
---|---|
FROM | 指定 Image 。格式為 FROM <image> 或 FROM <image>:<tag> 。 |
LABEL | 用來指定維護者的資訊,可以用 docker inspect 指令查詢 。 |
RUN | 執行指令,通常用來操作細部動作,例如安裝套件、處理檔案等等。 格式有兩種: - RUN <command> - RUN ["executable", "param1", "param2"] (使用 exec 執行)若指令太長可以使用 \ 來換行。 |
CMD | 執行指令,每個 Dockerfile 只能有一條 CMD 命令,通常用在 啟動服務 的指令。有三種使用格式:- CMD ["executable","param1","param2"] (使用 exec 執行)- CMD command param1 param2 (使用 /bin/sh 執行)- CMD ["param1","param2"] (為 ENTRYPOINT 指定參數) |
ENTRYPOINT | 執行指令,不會被 docker run 的參數覆蓋,且一定會執行;每個 Dockerfile 只能有一條 ENTRYPOINT 命令,通常用在把該 Image 當成一個 執行檔 時使用。有兩種使用格式: - ENTRYPOINT ["executable", "param1", "param2"] (使用 exec 執行)- ENTRYPOINT command param1 param2 (使用 /bin/sh 執行) |
EXPOSE | 用來紀錄該服務使用 port 及 protocol 的 文件 (實際綁定還是需要依靠 docker run -p )。 |
ENV | 設定一個環境變數,使其可以在 RUN 的指令中使用。 |
ADD | 複製指定的目錄到Container 中。其中目錄也可以是遠端的檔案(URL),ADD 指令也會自動將 .tar 解壓縮。 |
COPY | 複製本機的目錄到 Container 中。 |
VOLUME | 建立一個將本機目錄掛載進 Container 中的掛載點。 |
USER | 切換到指定的用戶,接下來執行的指令皆由該用戶身份執行。 |
WORKDIR | 指定 Container 執行起來時的預設目錄位置。 |
ONBUILD | 格式為 ONBUILD [INSTRUCTION] 。當這個 Image 做為其他人的 Base Image 時所執行的指令。 |
Usage
一般來說,一個完整的 Dockerfile
至少會有幾個區塊:Base Image
、Maintainer 資訊
、Container 指令操作
、服務啟動
。
Dockerfile
# This is a test image
# Base image
FROM ubuntu:19.04
# Maintainer information
LABEL owner="JohnsonLu" version="1.0" description="This is a test service of Apache httpd"
# Command to update the image
RUN apt-get update && apt-get install -y apache2
# Commands when creating a new container
CMD apachectl -DFOREGROUND
在 Dockerfile
撰寫完成之後,可以透過 docker build 建立 Image
。
Create Image
; 將特定目錄建置成 Docker Image
; -t 設定 name:tag
; --no-cahce 為不使用 cache 建立 Image
docker build -t johnsonlu/httpd:1.0 --no-cache .
Notice: 該指令會根據該目錄底下的
Dockerfile
檔案進行建置。如果想要指定Dockerfile
,可以使用-f
參數。
建立完成之後,接著就可以建立 Container
了。
Build Container
; 將本機的 8080 port 綁定到 Container 的 80 port
docker run -d --name apache -p 8080:80 johnsonlu/httpd:1.0
Performance
由於 Docker Image
儲存的方式是以 Layers
的方式儲存,所以會把每個指令之間的紀錄都保存下來,如果在撰寫 Dockerfile
時,冗長的指令太多,就很有可能會導致 Docker Image
肥大。
ADD
在 Docker 文件 中有提到,雖然 ADD
指令可以下載遠端檔案,但如果用 RUN
搭配 curl
和 pipeline
會更節省空間。
ADD 用法
ADD http://example.com/big.tar.xz /usr/src/things/
RUN tar -xJf /usr/src/things/big.tar.xz -C /usr/src/things
RUN make -C /usr/src/things all
curl用法
RUN mkdir -p /usr/src/things \
&& curl -SL http://example.com/big.tar.xz \
| tar -xJC /usr/src/things \
&& make -C /usr/src/things all