現代化小白也要嘗試的容器手札 - Dockerfile 語法深入探討

 Day12. Dockerfile 語法深入探討

認真!Dockerfile本身是由一行行命令句所組成,並支援以#開頭的註解行
本身Dockerfile區分為四個部份:

  1. 基底映像檔資訊。
  2. 維護者資訊。
  3. 映像檔操作指令。
  4. 容器啟動時執行指令。

呼應上篇入門範例

FROM ubuntu >> 基本映像檔,必須要先參照指定的基底而跑的指令
MAINTAINER Gary mosbbs2@gmail.com >> 維護人員(建議但非必要)
RUN apt-get update && apt-get install -y nginx >> 更新映像檔指令
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
CMD /usr/sbin/nginx >> 建立新容器所需執行的指令

當然實際上遠比現行的範例複雜多的多,但至少透過簡單的示範讓初學者可以慢慢進入狀況不在認為遙不可及,以下是更多的指令動作來搭配組合一個更完整的dockerfile來實踐更多樣的自動化動作。

  • FROM:映像檔基底設定,在build image時,一定需要指定一個image來源。可以是FROM 不指定就抓取目前DockerHub上最新版本或是直接指定FROM :
  • RUN:build時會執行你的指令,然後commit結果,而結果會被Dockerfile下個步驟所使用。
  • CMD:run容器需要執行的指令,需注意這個跟RUN的區別,CMD是指當你使用docker run時,容器一旦建起來該跑什麼指令。
    1. CMD ["executable","param1","param2"]使用exec執行。
    2. CMD command param1 param2在/bin/sh中執行,使用在給需要互動的指令。
    3. CMD ["param1","param2"] 提供給ENTRYPOINT的預設參數。
  • LABEL:標籤會以key=value形式來定義。你可以用LABEL記錄一些映像檔資訊如:版本號、作者等訊息。官方建議用LABEL來定義多組識別提高效率。
  • EXPOSE:Container在執行時需要監聽哪個port。EXPOSE本身並非直接開放port給外部存取,要在docker run啟動容器時需要透過 -P,Docker會在分配一個埠轉發到指定的埠。
  • ENV:環境變數設定。
  • ADD:將檔案加到images內,檔案來源可以是URL或context內的檔案。
  • COPY:將檔案加到images內,檔案來源是context內的檔案,跟ADD類似,但大多都推崇此一複製檔案的方式進行。
  • ENTRYPOINT:執行container時要跑的指令,可以和CMD混搭,CMD被視為初始參數做使用。
  • VOLUME:掛載目錄用。
  • USER:可指定使用者為何?此指令過後的Dockerfile執行的指令都會用此使用者身分來執行。
  • WORKDIR:會將指定的目錄設定為當前的工作目錄。

Dockerfile

Use an official Python runtime as a parent image
FROM python:3.7.3-stretch

  • 建置環境時大多會從Docker Image開始,一般都直接會從DockerHub找到自己適合的映像環境作為基底,做為後續部署客製化環境的基底映像。
  • From 這字本身會先從本機來找尋符合的Image,假如找不到則從DockerHub來下載。

Set the working directory to /app

  • WORKDIR /app 將指定的目錄設定為當前的工作目錄App,如果此目錄不存在則WORKDIR會自動被建立。
  • RUN、CMD、ENTRYPOINT、COPY等都會參照此路徑目錄。

Install any needed packages specified in requirements.txt

COPY requirements.txt ./
COPY gunicorn.py ./
  • 將所需的檔案requirement.txt, gunicorn.py複製到docker中。
  • COPY [--chown=:] ... (可以是容器絕對路徑或WORKDIR 的相對路徑。)
  • 使用COPY會保留來源資料相關屬性如:讀寫權限、文檔變更…等。
  • ADD可作為COPY加強版本,允許Source Path是一個URL,假設下載的是壓縮檔則會自動解壓縮。
RUN pip install --trusted-host pypi.python.org -r requirements.txt \
    && python3 -O -m compileall -b ./app \
    && find ./app -name "*.py"|xargs rm -rf \
    && python3 -O -m compileall -b ./config.py \
    && rm ./config.py
  • 用來執行Shell指令如此範例就是透過RUN調用pip安裝python的相關套件。
  • Dockerfile每個指令都是啟動一個容器並執行命令後,以Commit方式提交修改,直到完成整個映像檔。

Make port 5000 available to the world outside this container
EXPOSE 5000

  • 程式碼內宣告開放5000的連接埠。
  • 運行容器所用的 -p <host port>:<container port> 是把兩邊的連接埠做映射,而宣告容器使用哪個連接埠並不會自動映射到主機上。

Define environment variable
ENV NAME World

  • 設置環境變數,格式 或= =。

Run app.py when the container launches
CMD ["gunicorn", "-c", "gunicorn.py", "run:app"]

  • 設定容器啟動時所要執行的指令。

留言

這個網誌中的熱門文章

<重要> 加密貨幣 Token 投資警示分享

對於跑者膝患部發炎,使用微波,向量干擾與低能雷射,分別是有哪些復原功效

現代化小白也要嘗試的容器手札 - Docker Swarm 新手上路