Kai Chen
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # 六角鼠年鐵人賽 Week 5 - Build a suitale Image by DockerFile ==大家好,我是 "為了拿到金角獎盃而努力著" 的文毅青年 - Kai== ### 夜歸鹿門山歌 孟浩然 :::info 山寺鐘鳴晝已昏,漁梁渡頭爭渡喧。 人隨沙岸向江村,餘亦乘舟歸鹿門。 鹿門月照開煙樹,忽到龐公棲隱處。 巖扉鬆徑長寂寥,惟有幽人自來去。 ::: ## DockerFile 介紹 DockerFile 是建置一個 Image 的源頭,負責定義底層映像檔、支援操作指令、加入維護者、容器啟動指令等內容。 上述的說明很難懂,可以把它想成 DockerFile 是一個設計圖,而經由 DockerFile 建置出的 Image 就是工廠,可以生產出許多的 Container。今天如果工廠想要生產不同的東西,DockerFile 只要更動部分的設計,如同工廠增刪不同的配備,就可以開始生產其他產品。 DockerFile 作為 Docker Image 的源頭,其帶來的優勢有以下幾點: ### 文字檔方便攜帶 DockerFile 僅是由一行一行的指令整理而成的文字檔,因此它幾乎不占用任何資源,檔案輕巧方便攜帶與交換。 ### 提供建置訊息 DockerFile本身是個可閱讀的檔案,由許多操作指令一行一個動作的方式寫成,當然這跟Linux操作有很大的關聯。 除了用來建置成 Image 外,也因其獨特的格式而成為了很好的文件,開發者可以透過 DockerFile 了解該 Image 完整的建置流程,避免掉無謂的動作而損耗資源。 雖然在 Docker Hub 上挑選公開且評分高的 Image,基本上不會遇到胡亂搞的設計,但如果今天拿到一個不知來源的 Image,或者對其在建置上有不確定性時,DockerFile 就是個很重要的說明文件。 而對於一般常用 word、excel 紀錄環境佈署過程的工程師來說,一份 DockerFile 既省了開發的工,也省了寫文件的工(愉悅~)。 ### 客製化 從網路上直接抓 Image 的方式好處是方便、快速,但在專案上卻不一定能夠完全滿足需求,而透過建置專屬 DockerFile 的方式,便可輕鬆建置完全媒合專案的 Image。 ## DockerFile Commands #### 建立 DockerFile ```xml touch [DockerFile Name] Kai 的操作指令為 touch testDockerFile_1 ``` :::info 使用 Linux 指令 touch 建立空檔案 **P.S. touch 另外的功能為變更檔案或目錄的時間戳記** ::: --- #### 編譯檔案 ``` vim [DockerFile Name] {I},{O},{A},{R} (Edit...) {ESC} :wq ``` ![](https://i.imgur.com/EIP3p97.png) :::info 使用 Linux 指令 vim 開啟編譯文檔的視窗 按下 i,o,a (插入),r (取代) 隨意一個按鍵開啟編輯模式 (編輯...) 按下 ESC 離開編輯模式 輸入 :w(寫入) q(離開) 離開 vim 回到主畫面 ::: ``` # 我只是註解 # DockerFile 開頭必須是 FROM 指定一個底層映像檔 FROM tomcat:7.0.100-jdk8-corretto # 映像檔維護者, 可以當成作者 MAINTAINER KAI # LABEL 設定映像檔的 Metadata LABEL description="Kai's example" version="1.0" owner="Kai" ``` ![](https://i.imgur.com/mqVsA4w.png) :::info **#** 在 DockerFile 中為註解符號,使用在句子最前頭,可以讓後續輸入的文字僅保留訊息功能,而不會被編譯器讀取為須執行的程式碼 **FROM [Docker Image Name:TAG]** DockerFile 開頭第一句必須是此指令,指定該 DockerFile 的底層映像檔,而後續的操作就會在該映像檔上的寫入層進行處理,包含建立各個 Layer 等動作 **MAINTAINER [Editor Name]** 為描述此映像檔的維護者名稱 **LABEL [<key>=value]** 設定映像檔的 Metadata 資訊,有許多種的<key>可選用,可在這部分寫入較多關於此 DockerFile 的訊息 ::: --- #### RUN - Build 時的指令 :::info **RUN <shell commands>** **RUN ["executable","param","param"...]** 在 build Image 時的指令,可以使用一般常見的 shell 指令和 exec 指令兩種下法讓開發者建置環境 想了解其中差異的人可以參考官網 [**Run 的解說**](https://docs.docker.com/engine/reference/builder/#run) 簡單來說 EXEC 的指令下法可以避免一些預設的 shell 指令,而選擇想要的 shell 指令進行操作,此外還須注意 EXEC 執行的程式碼,必須使用 **雙引號** 的格式框住指令 以下分享一些小技巧與觀念: 1. 使用 \ 符號進行換行,避免過長的文字影響閱讀 2. 使用 && 串聯 多個 RUN 指令,因為每一個 RUN 都會建立一個 Layer,使用 && 可以避免建置過多 Layer ::: --- #### CMD - 執行 Container 時的指令 :::info **CMD ["executable","param","param"]** **CMD <shell commands>** **CMD ["param","param"]** 在 Container 建立時要下的指令,官方推薦使用 EXEC 的方式進行操作,另注意第三種為有使用 ENTRYPOINT 參數時適用的指令 ::: :::danger - CMD 在 DockerFile 中只能存在一行,若有多行不影響運行,但只有最後一行 CMD 指令會生效 - ENTRYPOINT 可設定預留參數在 Image 中,若有 CMD 指令,可透過執行後的 CMD 指令改變它 ::: --- #### ENTRYPOINT - 執行 Container 時的指令 :::info **ENTRYPOINT ["param","param"...]** 在 Container 建立時要下的指令,可設定預留參數在 Image 中,待啟動 Container 時執行,若有 CMD 參數,則會自動用 CMD 參數取代原有參數 ::: :::danger - 與 CMD 一樣,在 DockerFile 中只能存在一行,若有多行不影響運行,只有最後一行 ENTRYPOINT 指令會生效 ::: :::warning **CMD 與 ENTRYPOINT 範例** 若在 DockerFile 中寫入下列指令 ``` ENTRYPOINT ["/bin/echo", "Hello"] CMD ["World"] ``` 而在啟動時,若我們輸入下列指令會有不同的結果 ``` docker run -it <image> return: Hello World docker run -it <image> Docker return: Hello Docker ``` ::: --- #### ADD 和 COPY - 增加與複製檔案 :::info **COPY [--chown=<user>:<group>] <src>,<src>,... <dest>** **COPY [--chown=<user>:<group>] ["<src>","<src>",... "<dest>"]** **ADD [--chown=<user>:<group>] <src>,<src>,... <dest>** **ADD [--chown=<user>:<group>] ["<src>","<src>",... "<dest>"]** 兩個指令都是用來將檔案放置到指定位置的指令,不同在於: - ADD 支援 URL 路徑 - 檔案為壓縮檔時,使用 ADD 會在放置後自動解壓縮,COPY 則不會 (一般建議以 COPY 為搬運指令) ::: --- #### EXPOSE - 監聽 port :::info **EXPOSE <port>/<protocol>,<port>/<protocol>,...** 設定用來監聽 port 的指令,預設為 TCP,可手動更正為 UDP 定義的 port 並不會在 Container 啟動時一併啟用連接埠,須使用 -p 或 -P 參數啟用 使用大寫 -P 會在啟用時,啟動所有 EXPOSE 定義連接埠號,並且動態、隨機關連到主機的連接埠號 ``` docker run -P [Docker Image] ``` -p 小寫可在啟用時,自行設定與主機關聯的連接埠號 ``` docker run -p 8080:8081/tcp -p 8080:8081/udp [Docker Image] ``` ::: --- #### ENV - 環境指令 :::info **ENV <key> <value>** **ENV <key>=<value>** 用來設置環境變數的指令,兩種寫法都可以,且在 Container 建立後亦可使用 ::: --- #### VOLUME - 掛載目錄指令 :::info **VOLUME ["/data"]** VOLUME 值可以是 JSON 也可以是純粹的文字,要注意是無法指定本機對應目錄,目錄為自動生成,可以使用 docker inspect VOLUME 查詢目錄資訊 ::: --- #### WORKDIR - 設定工作目錄指令 :::info **WORKDIR /path/work_dir** 設定工作目錄路徑,設定好後,前頭提到的 RUN、CMD、ENTRYPOINT、COPY、ADD 就會在此路徑下執行操作 ::: --- ### USER - 運行 Container 時的使用者名稱或ID :::info **USER <user>** **USER <UID>** 設定 USER 後,後續的操作便會以該名 USER 的權限進行操作,若 USER 的 權限不足以操作某些指令,會造成執行中錯誤。 若 USER 不存在,則在運行時的指定會因失敗而停止 ::: --- #### ARG - 在建置映像檔時可傳入的參數 :::info **ARG <name>** 提供 build Image 時的參數,無法在運行 Container 時執行,這是與 ENV 最大的不同 ::: --- #### ONBUILD - Base Image Build Trigger :::info 這個設置可以讓你 build 出來的 Image 在被別人當作 底層映像檔時,執行完 FROM 之後會優先執行你寫入的 ONBUILD 指令,後續才是他人寫的指令 ::: ## Build Image 在介紹了許多會寫入 DockerFile 中的指令後,終於要來講如何用 DockerFile 建置 Image了 (累) ``` docker build [DockerFile Name] docker build -t [Image Name:TAG] docker build -f [path] -t [Image Name:TAG] ``` :::info -t 的參數為寫入 Image Name 和 TAG -f 的參數為指定 Image 建置完成後放置的位置 ::: Image 建置好後,就可以開始使用 Image 產出許多 Container 來運行了! ## 結語 :::danger DockerFile 的內部指令基本就上述這些,詳細的一些內容可能 Kai 這邊也還沒學到,等後續學到了,我會再特別開一篇新的或是更新舊內容的方式做回饋~ 下篇將會分享 **使用 DockerFile 編寫建置 Tomcat + MySQL 環境** 的學習心得 [六角鼠年鐵人賽 Week 6 - 使用 DockerFile 建置 Tomcat + MySQL 環境](/csz4vaWTTgGbnw_5QmQrjQ) ::: 首頁 [Kai 個人技術 Hackmd](/2G-RoB0QTrKzkftH2uLueA) ###### tags: `Docker`,`w3HexSchool`

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully