# 筆記 - 為已完成的專案建立 Docker Image > 在開始指令之前,記得先開啟 `Docker Desktop`,Docker engine 才會啟動哦 接下來要做的步驟如下: 1. 在專案根目錄建立 `Dockerfile` 檔案  2. 建立 Docker Image --- ### 在專案根目錄建立 `Dockerfile` `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 忽略此目錄 ```dockerfile= node_modules ``` ### 建立 Docker Image ```bash= # -t: 標籤 # image name 建議可以長一點、容易記、不易混淆的名稱 # 最後一個 「.」 表示以當前目錄建立 image docker build -t docker-image-name . ``` ## Docker 常見指令 ##### 建立 image ```bash= docker build -t docker-image-name . ``` ##### 前景創建 Container 運行 image 當前視窗運行中,須另開 Terminal 停止 container ```bash= # -p: port # 3000(本地):3000(container) docker run -p 3000:3000 docker-image-name ``` ##### 背景運行 image 可在同一個 Terminal 停止 container ```bash= # -d: detached mode docker run -p 3000:3000 -d <docker-image-id> ``` ##### 列出所有 images ```bash= docker images ``` ##### 刪除 image ```bash= docker rmi <image-id> ``` ##### 列出運行中的 Container 程序 ```bash= docker ps # 包含運行失敗的 Container # Container 運行 image 失敗時,Container 不會顯示在 docker ps 中 docker ps -a ``` ##### 啟動 Container 程序 ```bash= docker start <container-id> ``` ##### 停止 Container 程序 ```bash= docker stop <container-id> ``` ##### 刪除 Container 程序 ```bash= # 運行失敗的 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 來優化 ```bash= docker run -p 3000:3000 -v $(pwd):/usr/src/app:cached -d <docker-image-name> ``` #### 使用 `docker-compose` 建立 `docker-compose.yml` ```yaml= 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 ```bash= docker-compose up --build ``` 這個指令會做三件事: 1. 創建 Docker image 等同於 `docker build` 指令 2. 啟動容器 等同於 `docker run` 指令 3. 處理環境變數、掛載 Volumn、設定 Port 用於確保開發環境一致 若 `image` 已存在,不需要變更 `Dockerfile` 或是 `package.json` 的狀況下,不需要使用 `--build` ```bash= docker-compose up ``` 若執行 `docker-compose up` 後卻斷開,可以試著加入兩個屬性解決問題 ```bash= services: app: stdin_open: true # 等同於執行指令時的 `-i` 標籤 tty: true # 等同於執行指令時的 `-t` 標籤 ``` #### 使用 docker ... prune 刪除所有未被 `Container` 使用的 `Image` ```= docker image prune -a ``` 刪除所有停止運行的 `Container` ```= docker container prune ``` ### 打包 及 載入 Image #### 打包 Image ```bash= # -o: output docker save -o my-app.tar my-app ``` #### 載入 Image ```bash= # -i: interactive mode # 如果没有 -i,指令會執行到一半退出 docker load -i my-app.tar ```
×
Sign in
Email
Password
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