目錄
Dockerfile 教學:把自己的程式打包成映像檔
Dockerfile 是一個純文字檔,裡面一行一行寫著「怎麼建立這個映像檔」。Docker 會照著這些步驟執行,產生一個映像檔。
範例專案
建立一個資料夾 hello-node,裡面放兩個檔案。
package.json:
{
"name": "hello-node",
"version": "1.0.0",
"scripts": { "start": "node server.js" }
}
server.js:
const http = require("http");
const server = http.createServer((req, res) => {
res.end("Hello from Docker!\n");
});
server.listen(3000, () => console.log("Listening on port 3000"));
撰寫 Dockerfile
在同一個資料夾建立名為 Dockerfile 的檔案(沒有副檔名):
# 1. 以官方 Node.js 映像檔為基礎
FROM node:22-alpine
# 2. 設定容器內的工作目錄
WORKDIR /app
# 3. 先複製套件清單並安裝相依套件
COPY package*.json ./
RUN npm install --omit=dev
# 4. 再複製其餘程式碼
COPY . .
# 5. 說明容器會使用的連接埠
EXPOSE 3000
# 6. 容器啟動時執行的指令
CMD ["npm", "start"]
建置與執行
docker build -t hello-node .
docker run -d -p 3000:3000 --name hello hello-node
curl http://localhost:3000
-t hello-node 是映像檔名稱,最後的 . 代表用目前資料夾當作建置內容(build context)。
常用指令說明
| 指令 | 作用 |
|---|---|
FROM | 指定基礎映像檔,Dockerfile 一定從它開始 |
WORKDIR | 設定之後指令的工作目錄,不存在會自動建立 |
COPY | 把建置內容中的檔案複製進映像檔 |
RUN | 建置時執行指令,例如安裝套件 |
ENV | 設定環境變數 |
EXPOSE | 標示容器使用的連接埠(只是說明,實際對應仍要用 -p) |
CMD | 容器啟動時預設執行的指令,可被 docker run 後面的指令覆蓋 |
ENTRYPOINT | 容器的主要執行檔,CMD 會變成它的參數 |
為什麼先複製 package.json
Dockerfile 的每一行都會產生一層,Docker 會快取這些層。只要某一行和它用到的檔案沒變,重新建置時就直接用快取。
如果一開始就 COPY . .,每次改一行程式碼,npm install 那層的快取就失效,得重新安裝所有套件。先只複製 package*.json 再安裝,只有套件清單改變時才需要重新安裝,建置會快很多。
.dockerignore
建置時,整個資料夾都會被送給 Docker。用 .dockerignore 排除不需要的檔案,可以加快建置,也避免把機密資料打包進去:
node_modules
.git
.env
*.log
小技巧
- 選擇
alpine或slim版本的基礎映像檔,可以大幅縮小映像檔大小。 - 固定基礎映像檔的版本,例如
node:22-alpine,不要只寫node。 CMD使用 JSON 陣列格式(["npm", "start"]),容器才能正確收到停止訊號。
下一步可以試著把你自己的專案寫成 Dockerfile,並用 docker build 建置看看。
更新於 2026年10月12日