Try   HackMD

筆記 - 為已完成的專案建立 Docker Image

在開始指令之前,記得先開啟 Docker Desktop,Docker engine 才會啟動哦

接下來要做的步驟如下:

  1. 在專案根目錄建立 Dockerfile 檔案
    image
  2. 建立 Docker Image

在專案根目錄建立 Dockerfile

Dockerfile 設置重點

# 1. 專案使用的 `Node.js` 版本 # Terminal 查詢指令: `node -v` FROM node: 22.14.0 # 2. 專案在 Container 內運行的目錄 # 常見預設為 `/usr/src/app` WORKDIR /usr/src/app # 3. 複製初始化專案所需的檔案 # e.g. `package.json`, `package-lock.json`, `yarn.lock` COPY package*.json . # 4. 初始化專案套件 # e.g. `npm install`, `yarn install` RUN npm install # 完成專案套件安裝後 # 將所有專案目錄及檔案複製到 Container # 包含所有 env, config 相關的設置檔 COPY . . # 設定應用程式運行的 Port EXPOSE 3000 # 運行專案:可從 package.json 查看專案運行指令 CMD ['npm', 'run', 'dev']

若運行過程有需要事先安裝的項目,則在適當的步驟加入 RUN 指令執行安裝
如:安裝 yarn, 產生 swagger-output.json

專案根目錄建立 .dockerignore

由於 dockerfile 其中一個流程會將所有目錄和檔案進行複製,而通常專案初始化過後,已有 node_modules/,此目錄會在 npm install 之後自動產生,因此需讓 docker 忽略此目錄

node_modules

建立 Docker Image

# -t: 標籤 # image name 建議可以長一點、容易記、不易混淆的名稱 # 最後一個 「.」 表示以當前目錄建立 image docker build -t docker-image-name .

Docker 常見指令

建立 image
docker build -t docker-image-name .
前景創建 Container 運行 image

當前視窗運行中,須另開 Terminal 停止 container

# -p: port # 3000(本地):3000(container) docker run -p 3000:3000 docker-image-name
背景運行 image

可在同一個 Terminal 停止 container

# -d: detached mode docker run -p 3000:3000 -d <docker-image-id>
列出所有 images
docker images
刪除 image
docker rmi <image-id>
列出運行中的 Container 程序
docker ps # 包含運行失敗的 Container # Container 運行 image 失敗時,Container 不會顯示在 docker ps 中 docker ps -a
啟動 Container 程序
docker start <container-id>
停止 Container 程序
docker stop <container-id>
刪除 Container 程序
# 運行失敗的 Container 不被視為運行中程序,無法使用 stop 停止 docker rm <container-id>
  • 若 Container 程序運行中,是無法刪除 image 的,必須先刪除 Container 程序
  • 若只是要更新 image,不需要刪除 Container,重新 build image 就會更新內容

同步 image 中專案的程式碼

由於 docker run 預設不會同步程式碼變更,所以即使專案使用 Vite,本身有 HMR,或是 TailwindCSS 使用 JIT,在無法同步 image 中的程式碼的狀況下,運行的頁面還是不會更新內容。

那就會讓開發和運行過程繁瑣-每次變更程式碼就要重新 build 一次 image。

有兩種方式能夠在運行的過程中,同步程式碼變更:

  1. 掛載 Volume
  2. 使用 docker-compose

掛載 Volumn

docker run -p 3000:3000 -v $(pwd):/usr/src/app -d <docker-image-name>
  • Windows 可能需要使用完整路徑,例如 C:/Users/,或用 WSL ($(pwd)) 來避免掛載問題
  • 某些系統(特別是 macOS)Volume 掛載效能較差,可以加 :cached 來優化
docker run -p 3000:3000 -v $(pwd):/usr/src/app:cached -d <docker-image-name>

使用 docker-compose

建立 docker-compose.yml

version: '3' services: app: image: node:22.14.0 container_name: <docker-image-name> working_dir: /app volumes: - .:/app:delegated ports: - "3000:3000" command: npm run dev

:delegated

能夠優先保證 Container 的讀取速度,適合建構或運行代碼

:cached

本機同步的速度快,但 Container 不會立刻讀取最新內容,適合靜態文件

啟動 docker container

docker-compose up --build

這個指令會做三件事:

  1. 創建 Docker image
    等同於 docker build 指令
  2. 啟動容器
    等同於 docker run 指令
  3. 處理環境變數、掛載 Volumn、設定 Port
    用於確保開發環境一致

image 已存在,不需要變更 Dockerfile 或是 package.json 的狀況下,不需要使用 --build

docker-compose up

若執行 docker-compose up 後卻斷開,可以試著加入兩個屬性解決問題

services: app: stdin_open: true # 等同於執行指令時的 `-i` 標籤 tty: true # 等同於執行指令時的 `-t` 標籤

使用 docker prune

刪除所有未被 Container 使用的 Image

docker image prune -a

刪除所有停止運行的 Container

docker container prune

打包 及 載入 Image

打包 Image

# -o: output docker save -o my-app.tar my-app

載入 Image

# -i: interactive mode # 如果没有 -i,指令會執行到一半退出 docker load -i my-app.tar