Logo

新人日誌

首頁關於我部落格

新人日誌

Logo

網站會不定期發佈技術筆記、職場心得相關的內容,歡迎關注本站!

網站
首頁關於我部落格
部落格
分類系列文

© 新人日誌. All rights reserved. 2020-present.

初學者指南:什麼是 Dockerfile?—— 以實際範例解析

最後更新:2025年3月5日架構

本文為 Docker 進階介紹 系列文,第 6 篇:

  1. 初學者指南:深入了解 WSL 2(Windows Subsystem for Linux 2)
  2. 虛擬機器(VM)是什麼?完整入門指南
  3. 什麼是核心(Kernel)?初學者完整指南
  4. Docker vs. 虛擬機器(VM):初學者完整比較指南
  5. 如何在 WSL 2 + Docker 環境中開發 Django:安裝順序與最佳實踐
  6. 初學者指南:什麼是 Dockerfile?—— 以實際範例解析 👈進度
  7. Docker Compose 初學者指南:使用範例解析
  8. Docker Compose:up vs up -d 的差異與應用
  9. Linux 常見指令入門:從 sudo 到日常操作
  10. Linux 解決方案:VSCode 無法儲存檔案權限問題

閱讀本文前,建議先理解 Docker 基本介紹系列文 相關概念。

如果你剛開始學習 Docker,可能會聽到「Dockerfile」這個詞。

簡單來說,Dockerfile 是用來建立 Docker 映像檔(Image)的腳本,它定義了如何建構一個容器環境,使得應用程式能夠在任何環境中保持一致地運行。

本文將以一個 Dockerfile 實際範例來說明它的各個指令,並幫助初學者了解 Dockerfile 的運作方式。


Dockerfile 是什麼?

想像一下,你要在一台新的電腦上安裝一個應用程式,比如 Django 網站,你通常會做什麼?

你可能需要:

  1. 安裝作業系統(例如 Ubuntu)
  2. 設定時區、環境變數
  3. 安裝 Python、Django 和其他必需的工具
  4. 把你的應用程式的程式碼放到對應的目錄
  5. 安裝應用程式所需的套件
  6. 最後,啟動 Django 伺服器,讓網站跑起來

這些步驟如果要手動做,每次換電腦、換環境時都要重來一遍,非常麻煩。

而 Dockerfile 就是用來幫你 自動化這些步驟 的一個設定檔!

Dockerfile 是怎麼工作的?

Dockerfile 就像是一張 烹飪食譜,告訴 Docker 該如何一步步「製作」出一個能執行你應用程式的環境。

當你執行 docker build 這個指令時,Docker 會按照 Dockerfile 上的步驟,自動建立一個新的映像檔(Image)。

這個映像檔就像是安裝好所有必要環境的「模擬電腦」,之後你可以用它來快速啟動應用程式。

graph TD;
    A["開始"] --> B["撰寫 Dockerfile"]
    B --> C["執行 docker build"]
    C --> D["建立 Docker 映像檔 (Image)"]
    D --> E["執行 docker run 或 docker-compose up"]
    E --> F["啟動容器 (Container)"]
    F --> G["應用程式開始運作"]

Dockerfile 通常包含哪些內容?

在 Dockerfile 裡,我們會寫下一些「指令」,來讓 Docker 知道該做哪些事情,例如:

  1. 基礎映像(Base Image):要用什麼作業系統?(如 Ubuntu、Alpine、Debian)
  2. 執行環境設定:設定時區、環境變數
  3. 安裝必要套件:Python、Django、資料庫等
  4. 設定工作目錄:告訴 Docker 哪裡是應用程式的「家」
  5. 複製應用程式檔案:把你的專案程式碼放進 Docker 裡
  6. 安裝應用程式的套件:透過 pip 安裝 requirements.txt 內的套件
  7. 執行應用程式的指令:告訴 Docker 啟動 Django 伺服器

簡單來說,Dockerfile 就是讓你 一次寫好設定,之後自動建立環境,這樣就不用每次都手動設定環境了!

接下來,我們用一個 實際的 Dockerfile 來解析,讓你更容易理解。


Dockerfile 解析:以 Django 應用為例

以下是範例 Dockerfile 內容:

# 使用 Ubuntu 20.04 作為基礎映像
FROM ubuntu:20.04

# 環境變數:自動設定時區,避免 tzdata 提示交互式輸入
ENV TZ=Asia/Taipei
RUN apt update && apt install -y tzdata

# 安裝 Python 和必要套件
RUN apt update && apt install -y python3 python3-pip python3-venv

# 設定工作目錄
WORKDIR /app

# 複製專案檔案
COPY . .

# 安裝 Django 和依賴套件
RUN pip3 install --no-cache-dir -r requirements.txt

# 預設啟動 Django 伺服器
CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]

這個 Dockerfile 是用來建立一個 Ubuntu 20.04 環境,並運行 Django 應用程式的容器。

接下來我們會一行行解析這些指令。


Dockerfile 指令解析

接下來,我們將逐步拆解 Dockerfile 內的每一行指令,讓你能清楚了解它們的作用,並學會如何根據需求修改 Dockerfile。

指定基礎映像

FROM ubuntu:20.04
  • FROM 指令是 Dockerfile 的第一行,負責定義基礎映像(Base Image)。
  • 這行的意思是:我們的容器環境會以 Ubuntu 20.04 作為基礎,這代表我們的應用程式會運行在 Ubuntu 20.04 系統上。

🔹 為什麼要選擇基礎映像?

  • 基礎映像就像是作業系統的安裝包,例如 ubuntu:20.04、alpine:latest、python:3.9 等。
  • 選擇適當的映像可以減少我們需要手動安裝的套件,讓開發更輕鬆。

設定環境變數

ENV TZ=Asia/Taipei
RUN apt update && apt install -y tzdata

🔹 ENV 指令

ENV TZ=Asia/Taipei
  • ENV 指令用來設定環境變數,在這裡我們設定 TZ 為 Asia/Taipei,確保時區正確。
  • 這樣做可以避免 Docker 在安裝 tzdata 時出現手動選擇時區的交互操作。

🔹 RUN 指令

RUN apt update && apt install -y tzdata
  • RUN 指令執行 Linux 指令,在這裡用來安裝 tzdata(時區套件)。
  • apt update:更新 apt 軟體套件庫,確保我們安裝的是最新版本的套件。
  • apt install -y tzdata:自動安裝 tzdata,-y 參數代表自動同意安裝。

📌 這樣做的好處:

  1. 避免安裝 tzdata 時需要手動選擇時區,提升自動化程度。
  2. 確保容器內的時間與主機同步,對於需要時間資訊的應用(如 Django log)非常重要。

補充:APT 軟體套件庫是什麼?

什麼是 APT?

APT(Advanced Package Tool)是 Debian 和 Ubuntu 等 Linux 系統用來管理軟體套件的工具。它負責:

  • 下載 軟體
  • 安裝 軟體
  • 更新 軟體
  • 移除 軟體

在 Linux 中,我們不需要像 Windows 一樣手動去官網下載 .exe 檔案來安裝軟體,而是透過 APT 來自動處理這些事情。例如:

sudo apt install python3

這行指令會幫你下載並安裝 python3,而且還會自動處理所有它需要的其他依賴套件(dependencies)。

那「APT 軟體套件庫」是什麼?

APT 軟體套件庫(APT Package Repository)是一個 儲存軟體的雲端伺服器,APT 會從這裡下載所需的軟體。

可以把它想像成:

  • App Store 或 Google Play:當你要安裝 App 時,不是自己去找安裝檔,而是透過應用商店下載。
  • APT 軟體套件庫 就像 Linux 的應用商店,裡面有各種可以安裝的軟體,APT 會從這裡抓取最新版本的套件。

當你執行:

sudo apt update

這個指令的意思就是:「去看看 Linux 軟體倉庫裡,有沒有軟體的新版本!」

當你執行:

sudo apt install vim

這個指令的意思是:「從 Linux 軟體倉庫下載並安裝 vim 這個軟體。」

為什麼 apt update 很重要?

在 Dockerfile 或 Linux 系統中,你常會看到:

RUN apt update && apt install -y python3

這裡 apt update 是用來更新 APT 軟體套件庫的索引,確保安裝的軟體是最新的。

如果沒有先 apt update,可能會遇到:

  1. 安裝到舊版本的軟體,因為系統還在用舊的索引檔案。
  2. 找不到軟體,因為新的軟體可能已經更新了,但系統不知道。

所以,良好的習慣是在安裝軟體前,先執行:

sudo apt update

這樣可以確保你下載的是最新的版本。

安裝 Python 和相關套件

RUN apt update && apt install -y python3 python3-pip python3-venv

這行指令的作用是安裝 Python 3 及其相關工具。

  • apt update:先更新 apt 軟體套件庫,確保能安裝最新的軟體版本。
  • apt install -y python3 python3-pip python3-venv
    • python3:安裝 Python 3,讓我們能夠執行 Python 程式。
    • python3-pip:安裝 pip,這是 Python 的套件管理工具,方便安裝 Django 及其他依賴。
    • python3-venv:安裝 venv,這是 Python 的虛擬環境管理工具,可用來管理專案內的 Python 套件,避免與系統套件衝突。

📌 為什麼要安裝 python3-venv?

  • venv 可用來建立獨立的 Python 環境,確保應用程式的 Python 版本與依賴不會與系統環境混淆。
  • 但在 Docker 容器中,由於容器本身已經是獨立的環境,venv 通常不是必要的,但如果你的應用需要它,還是可以安裝。

設定工作目錄

WORKDIR /app
  • WORKDIR 指令用來指定容器內的工作目錄。
  • 這行指令表示之後所有的指令(如 COPY、RUN、CMD)都會在 /app 這個目錄內執行。
  • 這樣可以讓檔案的組織更清楚,避免散落在容器內的不同目錄。

📌 為什麼要設定 WORKDIR?

  1. 讓開發者知道應用程式的根目錄在哪裡。
  2. 確保 COPY 和 RUN 指令執行時在正確的目錄內,避免找不到檔案的問題。

複製應用程式到容器

COPY . .
  • COPY 指令負責將本機端的檔案複製到容器內的目標目錄。
  • COPY . . 代表將當前目錄(包含所有應用程式的檔案)複製到 /app(因為我們前面已經設定了 WORKDIR /app)。

📌 這樣做的目的:

  • 把應用程式的程式碼和設定檔案複製到容器中,讓容器能夠執行我們的應用程式。

安裝 Django 及相關依賴

RUN pip3 install --no-cache-dir -r requirements.txt
  • pip3 install -r requirements.txt:使用 pip3 安裝 requirements.txt 中列出的所有 Python 套件。
  • --no-cache-dir:避免儲存快取,減少 Docker 映像的大小,確保容器不會留下不必要的安裝檔案。

📌 這樣做的目的:

  • requirements.txt 內通常會列出 Django 和其他依賴的套件,例如:
django>=3.2,<4.0
djangorestframework
gunicorn
  • 這樣就能確保應用程式在 Docker 容器內的 Python 環境與本機相同。

設定預設啟動指令

CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"]
  • CMD 指令用來指定容器啟動時執行的命令。
  • 這行指令等同於執行:
python3 manage.py runserver 0.0.0.0:8000
  • 它會啟動 Django 內建的開發伺服器,並監聽 0.0.0.0:8000,允許外部存取。

📌 為什麼 CMD 這麼重要?

  • CMD 定義了「當容器啟動時,應該做什麼」。
  • 如果沒有 CMD,容器可能會在啟動後立刻結束,因為沒有任何進程在執行。

📌 為什麼要監聽 0.0.0.0?

  • 0.0.0.0 代表「監聽所有網路介面」,這樣我們才能從本機(localhost)或其他裝置存取 Django 應用程式。

如何使用這個 Dockerfile

現在我們已經了解 Dockerfile 的內容,接下來我們要實際使用它來 建立 Docker 映像檔(Image)並啟動容器(Container)。

請按照以下步驟來運行 Django 應用程式。

建立 Docker 映像檔(Image)

在 Dockerfile 所在的目錄,打開終端機(Terminal)或命令提示字元(Command Prompt),執行:

docker build -t my-django-app .

指令解析

  • docker build:告訴 Docker 要建立一個新的映像檔。
  • -t my-django-app:給這個映像檔取名為 my-django-app,讓我們之後可以方便管理。
  • -t 代表 tag(標籤),用來給 Docker 映像檔取一個名字,讓我們之後可以更容易管理和使用這個映像檔。
  • .(點):代表 Dockerfile 所在的目錄,Docker 會在這個目錄內尋找 Dockerfile,並根據其中的指令來建立映像。

執行後會發生什麼?

  1. Docker 會讀取 Dockerfile,並依照其中的指令 一步步 建立映像檔:
    • 下載 Ubuntu 20.04 基礎映像
    • 安裝 Python 3、pip 等工具
    • 設定時區
    • 複製應用程式到容器
    • 安裝 requirements.txt 中的 Python 套件
  2. 當這些步驟完成後,Docker 會產生一個名為 my-django-app 的映像檔,這是一個可以運行 Django 應用的完整環境。

🔹 你可以用以下指令查看已建立的映像檔:

docker images

你應該會看到類似這樣的輸出:

REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
my-django-app     latest    abc12345       5 minutes ago    500MB

這代表 my-django-app 映像檔已經建立完成!

啟動 Docker 容器(Run Container)

當我們有了映像檔後,就可以使用它來啟動一個新的容器,讓 Django 伺服器運行起來。執行:

docker run -p 8000:8000 my-django-app

指令解析

  • docker run:這是用來啟動容器的指令。
  • -p 8000:8000:將本機的 8000 端口映射到容器內的 8000 端口,這樣我們就能從瀏覽器訪問 Django 應用程式。
  • my-django-app:這是我們剛剛建立的映像檔名稱,Docker 會根據這個映像檔來建立並啟動一個容器。

容器內的 8000 端口跟本機的 8000 端口之間的關係?

當你啟動一個 Docker 容器時,它是在一個獨立的環境內運行的,類似於一台虛擬機。

因此,容器內部的端口 預設是無法直接被外部(你的電腦)存取的,這時候我們就需要使用 -p 參數來進行端口映射。

-p 8000:8000 是什麼意思?

當你執行:

docker run -p 8000:8000 my-django-app

它的作用是:

  • 左邊的 8000(本機端口):這是你電腦(Host)上的端口。
  • 右邊的 8000(容器內端口):這是容器內部的端口。

這樣做的結果是 把你的本機 8000 端口,映射到容器內的 8000 端口,所以當你在瀏覽器打開:

http://localhost:8000

瀏覽器會請求 本機的 8000 端口,而這個端口已經被映射到容器內部的 8000,因此請求會成功傳遞到容器內部的 Django 伺服器,然後返回結果。

如果不用 -p 8000:8000,會發生什麼事?

假設你直接執行:

docker run my-django-app

這樣不會對外開放任何端口,所以即使 Django 伺服器在容器內的 8000 端口運行,你的本機完全無法連線。

🔹 測試方式 如果你這樣運行:

docker run my-django-app

然後試著打開:

http://localhost:8000

你會發現 連不上,因為容器內的 8000 端口並沒有對外開放。

這時候,你可以用以下方式來確認容器內的服務是否真的有在 8000 端口運行:

docker exec -it <CONTAINER_ID> netstat -tulnp

如果 8000 端口有開啟,代表 Django 伺服器是有在運行的,只是我們的本機無法連線。

執行後會發生什麼?

  1. Docker 會根據 my-django-app 映像檔來建立一個新的容器。
  2. 容器會執行 CMD ["python3", "manage.py", "runserver", "0.0.0.0:8000"],啟動 Django 伺服器。
  3. 因為我們使用了 -p 8000:8000,所以可以透過 localhost:8000 訪問這個應用程式。

🔹 查看目前運行中的容器 如果你想確保容器已經成功啟動,可以執行:

docker ps

你應該會看到類似這樣的輸出:

CONTAINER ID   IMAGE           COMMAND                  STATUS          PORTS                    NAMES
abcd1234       my-django-app   "python3 manage.py ..." Up 5 minutes    0.0.0.0:8000->8000/tcp   determined_torvalds

這表示容器已經成功運行,並且 8000 端口已經對外開放。


測試應用程式

現在你的 Django 應用應該已經在 Docker 容器內運行了,讓我們來測試看看。

方式 1:使用瀏覽器

  1. 打開瀏覽器,輸入: http://localhost:8000
  2. 如果 Django 成功啟動,你應該會看到 Django 的歡迎畫面或你的應用首頁。

方式 2:使用 cURL 測試

如果你的應用程式是 API,可以執行:

curl http://localhost:8000

如果返回了 HTML 或 JSON 內容,代表應用成功啟動。

停止與刪除容器

如果你想停止目前運行中的容器,可以執行:

docker ps

找到對應的 CONTAINER ID,然後執行:

docker stop <CONTAINER_ID>

例如:

docker stop abcd1234

如果你想刪除這個容器(停止後才能刪除),執行:

docker rm <CONTAINER_ID>

例如:

docker rm abcd1234

使用 Docker Compose 啟動 Django

如果你的 Django 應用程式還需要資料庫(如 PostgreSQL、MySQL),你可能會需要 docker-compose.yml 來管理多個容器。這時候可以用:

docker-compose up -d

這樣就可以同時啟動 Django 伺服器和資料庫,讓你的應用更完整!


總結

這篇文章解析了 Dockerfile 的基本概念,並透過一個 Django 應用的 Dockerfile 來說明各個指令的作用。我們學到了:

  • FROM 指定基礎映像
  • ENV 設定環境變數
  • RUN 執行指令(安裝套件等)
  • WORKDIR 設定工作目錄
  • COPY 複製檔案到容器
  • CMD 設定預設啟動指令

透過 Dockerfile,我們能快速建立一致的開發與部署環境,讓應用程式更容易維護和擴展。

如果你是 Docker 初學者,建議你親自動手試試這個 Dockerfile,會對 Docker 的運作方式有更深刻的理解! 🚀

目前還沒有留言,成為第一個留言的人吧!

發表留言

留言將在審核後顯示。

架構

目錄

  • Dockerfile 是什麼?
  • Dockerfile 是怎麼工作的?
  • Dockerfile 通常包含哪些內容?
  • Dockerfile 解析:以 Django 應用為例
  • Dockerfile 指令解析
  • 指定基礎映像
  • 設定環境變數
  • 安裝 Python 和相關套件
  • 設定工作目錄
  • 複製應用程式到容器
  • 安裝 Django 及相關依賴
  • 設定預設啟動指令
  • 如何使用這個 Dockerfile
  • 建立 Docker 映像檔(Image)
  • 啟動 Docker 容器(Run Container)
  • 測試應用程式
  • 停止與刪除容器
  • 使用 Docker Compose 啟動 Django
  • 總結