--- title: Docker 學習 Dockerfile 製作 tags: Docker,CMD --- Docker 學習 Dockerfile 製作 === ###### tags: `Docker` `CMD` --- ## :memo: Docker File 常用指令 <div class="dockerfile-description"> | 指令 | 描述 | |:----------- |:---------------------------------------- | | ADD | 添加本地或遠端的檔案和目錄。 | | ARG | 於建置時所產生的變數。 | | CMD | 指定預設命令。 | | COPY | 複製檔案和目錄。 | | ENTRYPOINT | 指定執行時預設指令檔。 | | ENV | 設定環境變數。 | | EXPOSE | 描述應用程式正在監聽的埠號。 | | FROM | 從基礎映像檔創建新的建置階段。 | | HEALTHCHECK | 在啟動時檢查容器的健康狀態。 | | LABEL | 向映像檔添加元數據。 | | MAINTAINER | 指定映像檔的作者。 | | ONBUILD | 指定映像檔用於建置時的指令。 | | RUN | 執行建置指令。 | | SHELL | 設定映像檔的預設 Shell。 | | STOPSIGNAL | 指定退出容器時的系統呼叫信號。 | | USER | 設定使用者和群組 ID。 | | VOLUME | 創建卷掛載。 | | WORKDIR | 變更工作目錄,建立後都由該資料夾進行建置 | </div> --- ## :pushpin: 什麼是Docker? > Docker 是一塊開放式平台,目的是為了在**開發上可以達到快速部屬/測試/執行** > 在Docker Hub上,由於 Docker 可拆分為前、中、後台程式專案及相關功能 > 可使用已存在的環境進行下載建置,已達到可重複且耦合性低的搭建手段 **Docker 其實也是 Virtual Machine 的一種,但不同於IIS伺服器架設** :arrow_right: Docker 可以說是取代 VM 的功能,更為輕巧,簡便的使用架設服務 為什麼呢? 因為 VM 是可執行的Operation System,可創建虛擬平台**供使用者進行頁面操作** 但如果僅需要運行 IIS / HTTP 等架設網站需求服務,使用龐大的VM環境就顯得臃腫龐大 Docker 的好處就是<font color=red>**僅操作 Operation System 部份需求功能**</font> 針對所需使用的操作系統,無須浪費空間及大量的資源在用不到的功能上 --- ## :rocket: 簡易DockerFile 撰寫 - DockerFile ``` ARG NODE_VERSION=20.11.1-alpine FROM node:${NODE_VERSION} LABEL description="A website about ANCO dessert" version="1.0.0" owner="MorgaYeh" email="a123a14795@gmail.com" ENV PORT=3010 ENV WORK_PLACE=/ANCO WORKDIR ${WORK_PLACE} COPY public/ $WORK_PLACE/public COPY src/ $WORK_PLACE/src COPY package.json $WORK_PLACE/ COPY tailwind.config.js $WORK_PLACE/ RUN npm install ENTRYPOINT ["npm", "run"] CMD ["start"] ``` :pushpin: 根據以下步驟**可大略寫出所需的Dockerfile步驟**: 1. 確認專案程式環境,並使用FROM將其取得建置 2. 設定ENV變數,以利建置資料能統一參照使用 3. 選定WORKDIR位置,將環境建置起的需求文檔設定目錄於此 4. COPY環境建置須要的文件檔案至指定的WORKDIR位置 5. 執行/建立 RUN 指令(command),獲得須要的 package/jar... 等安裝包 6. 設定CMD執行指令,在docker build container時可預設建置,方便簡化建置流程 --- ## :goal_net: 常用指令差別 ### :dango: ADD v.s. COPY <div class="docker-add-copy-compare"> | | COPY | ADD | |:--------:|:----------------:|:----------------------:| | **支援** | 複製建置平台資料 | HTTPS / Git URLS | | **動作** | 僅複製至指定位置 | 可針對Wget/tar檔解壓縮 | </div> 今天若有一檔案須<font color=red>**透過Http下載,且檔案為wget/tar副檔**</font>,則會建議使用ADD進行處理 若僅僅是在建置平台上,則會建議使用COPY方式操作 ### :dango: ARG v.s. ENV ARG 與 ENV 兩者皆為參數建置,**前者為runtime建置參數,後者為enviroment變數** :arrow_down: **ENV的靈活度遠大於ARG的使用範圍** <div class="docker-arg-env-compare"> | | ENV | ARG | |:--------:|:-------------------------------------------------------------------------------:|:----:| | 使用範圍 | ADD, COPY, ENV, EXPOSE, FROM, LABEL, STOPSIGNAL, USER, VOLUME, WORKDIR, ONBUILD | FROM | </div> 若是想於 container建置時輸入指定參數,可使用 **ARG** 方式取得 ``` ARG username USER $username ... ------------------------------------------ $ docker build --build-arg username=MorgaYeh ``` 另外,若想要建置時可輸入特定資料,或是不輸入資料以預設值方式帶出,可搭配 ARG/ENV 同時使用 ``` #VERSION_1 ARG CONT_IMG_VER ENV CONT_IMG_VER=v1.0.0 RUN echo %CONT_IMG_VER #VERSION_2 ARG CONT_IMG_VER ENV CONT_IMG_VER=${CONT_IMG_VER:-v1.0.0} RUN echo %CONT_IMG_VER ------------------------------------------ $ docker build --build-arg CONT_IMG_VER v2.0.8 ``` :::info **無輸入** ARG 參數,會以 **v1.0.0** 作為default參數使用 **有輸入** ARG 參數,會以輸入的值使用,如畫面上 **v2.0.8** 參數使用 ::: --- ## :rocket: 進階練習:Docker Compose Build ### :clock1: 建置 SQL Server ```csharp services: db: image: "mcr.microsoft.com/mssql/server" ports: - 8999:1433 volumes: - sqlserverdata:/docker-entrypoint-initdb.d environment: SA_PASSWORD: "yarashi920!" ACCEPT_EULA: "Y" volumes: sqlserverdata: driver: local ``` - image : 基礎映像檔環境,可根據相對應版本, - ports : &lt;Outer Ports&gt; : &lt;Inner Ports&gt;,用法同build container一樣 - environment : 環境變數設定 - volumes : 資料儲存放置位置,當Container重啟即將資料刷新,若含有volume可直接讀取使用 ### :clock2: 建置 Front-End WebSite (待完成) ```csharp services: front-end: volumes: ``` --- ## :computer: 連結 <div class="link-Table"> | 參考網站 | 連結 | |:-------------------- |:------------------------------:| | Dockerfile reference | [:link:][Dockerfile reference] | | Docker V.S. IIS | [:link:][Docker V.S. IIS] [Dockerfile reference]: https://docs.docker.com/reference/dockerfile/ [Docker V.S. IIS]: https://stackoverflow.com/questions/30357679/difference-between-containers-docker-and-iis </div> <style> div.link-Table > table th:nth-of-type(1) { width: 90vw; } div.link-Table > table th:nth-of-type(2) { width: 10vw; } div.dockerfile-description > table th:nth-of-type(1){ width: 30vw; } div.dockerfile-description > table th:nth-of-type(2){ width: 70vw } div.docker-arg-env-compare > table th:nth-of-type(1){ width: 10vw } div.docker-arg-env-compare > table th:nth-of-type(2){ width: 45vw } div.docker-arg-env-compare > table th:nth-of-type(3){ width: 45vw } div.docker-add-copy-compare > table th:nth-of-type(1){ width: 10vw } div.docker-add-copy-compare > table th:nth-of-type(2){ width: 45vw } div.docker-add-copy-compare > table th:nth-of-type(3){ width: 45vw } </style>