# Docker 第三週 本週課程要點: - Volume - Docker Compose - GitHub Action ## 回顧 - 如何在本地端運行 Node.js 並與 MongoDB 連線 - 如何在本地端運行 Node.js 容器,並與 MongoDB 連線 ## Docker Volume ### 關於 Volume Docker 容器重置後,資料則會移除,除非指定一個實體空間作為資料持久化 Docker 提供以下幾種方式: 1. **Bind Mounts**:系統指定路徑 1. 優點:直接就能看到,直覺 2. 缺點:不安全,Docker 可以直接存取系統檔案 2. **Volumes**:由 Docker 管理 1. 優點:統一由 Docker 管理 2. 缺點:需要使用指令操作,較不直覺 ### 1. Bind Mounts - 假設容器檔案路徑為 `/usr/local/app/dist` - 本機路徑範例 - linux: **/home/username/projects/myproject/dist** - windows: /c/Users/username/projects/myproject/dist - Mac: **/Users/username/projects/myproject/dist** - 顯示本機路徑:pwd - 套用指令:`-v <host-path>:<container-path>` - `-v /Users/casper/Project/Hexschool/培訓班/2024_Node/Docker/課程範例/week2/express-sample-mongo/dist2:/usr/local/app/dist` ```docker docker run -d -p 3000:3000 -v /Users/casper/Project/Hexschool/培訓班/2024_Node/Docker/課程範例/week2/express-sample-mongo/dist2:/usr/local/app/dist -e MONGODB_URL=mongodb://my-mongodb/mydatabase --network my-network casper723/2024-node-course-express-mongo ``` - 驗證 - 直接到資料夾去找 - 使用 exec 進入容器,也可看到相同結果 - 關閉容器,重啟後結果不變 ### 2. Volume - 關閉 MongoDB 後,重啟,會發現資料不見了 - 查看官方文件:https://hub.docker.com/_/mongo 可以看到資料路徑在 `/data/db` - 建立一個新的 Volume 儲存 - docker volume create mongodbdata - 刪除 mongoDB CONTAINER 後,重新創建 - docker run -d --name my-mongodb -v mongodbdata:/data/db --network my-network mongo:latest - docker run -d -p 3000:3000 -v /Users/casper/Project/Hexschool/培訓班/2024_Node/Docker/課程範例/week2/express-sample-mongo/dist2:/usr/local/app/dist -e MONGODB_URL=mongodb://my-mongodb/mydatabase --network my-network casper723/2024-node-course-express-mongo - 關閉 DB 重新啟動,可以發現容器內的資料還在 ## Docker Compose 上面的建構流程是不是很複雜呢? 使用 Docker compose 來統一管理吧 Docker 參考範例:https://github.com/docker/awesome-compose 可以參考其中 Express、React:https://github.com/docker/awesome-compose/blob/master/react-express-mongodb/compose.yaml - 建立一個新的檔案 docker-compose.yml,注意:docker compose 的檔案路徑,會影響之後的指令運作 - 在 linux 環境中,建議把 docker compose 放在:/usr/local/bin Docker Compose 說明 ``` version: "3.8" # 現在不需要加入版本號 services: # 容器 servicename: # 服務名字,這個名字也是內部 bridge 網絡可以使用的 DNS name image: # image 的名字 command: # 可選,如果設置,則會覆蓋預設 image 裡的 CMD 命令 environment: # 可選,相當於 docker run 裡的 --env volumes: # 可選,相當於 docker run 裡的 -v networks: # 可選,相當於 docker run 裡的 --network ports: # 可選,相當於 docker run 裡的 -p servicename2: # 第二個服務名字 volumes: # 可選,相當於 docker volume create networks: # 可選,相當於 docker network create ``` ### Docker Compose 常用命令 1. 啟動和停止服務 - **`docker-compose up`:啟動所有在 `docker-compose.yml` 文件中定義的服務。如果添加 `d` 參數,則會在後台運行。** - **`docker-compose down`:停止並移除所有服務,網絡,以及默認情況下定義的匿名卷。** 2. 管理服務 - `docker-compose start`:啟動已經創建但停止的服務。 - `docker-compose stop`:停止正在運行的服務,但不移除它們。 - **`docker-compose restart`:重啟服務。** 3. 查看服務狀態和日誌 - **`docker-compose ps`:列出所有服務的狀態。** - **`docker-compose logs`:查看服務的輸出日誌。添加 `f` 參數可以跟蹤日誌輸出。** 4. 執行一次性命令 - `docker-compose run`:在指定的服務上運行一次性命令。例如,`docker-compose run app bash` 會在 `app` 服務的容器中開啟一個 bash 會話。 5. 構建和重建服務 - `docker-compose build`:根據 `docker-compose.yml` 中的配置重新構建服務。可以指定特定服務。 6. 查看服務配置 - `docker-compose config`:檢查配置。這個命令可以用來確保 `docker-compose.yml` 文件中的語法是正確的。 其他說明: - docker-compose up -d:採用 distach 的模式連接 - docker container ls,可以看到全部服務,但不會知道跟 docker compose 的關聯性 - docker-compose ps ,當前的 docker compose - **注意:當離開當前的目錄(沒有 docker-compose.yml 時),就無法列出當前的 docker-compose** ### Docekr Compose 中使用本地端環境變數 #### 雲服務安裝 Docker Compose 1. 安裝 docker compose 1. https://docs.docker.com/compose/install/linux/ 2. sudo apt-get install docker-compose-plugin 3. docker compose version → 有版本代表安裝成功 2. 建立相關檔案 1. cd /usr/local/bin 2. 建立 .env 3. 建立 docker-compose.yml .env 檔案加入環境變數 ```docker COMPOSE_DB_URL=mongodb://my-mongodb/mydatabase ``` docker compose yml 調整 ```docker environment: MONGODB_URL: ${COMPOSE_DB_URL} # 套用的環境變數 : .env 檔案設定的環境變數 ``` ### 其他說明 - 如果有要順便 build 可以加入: ```docker build: context: . # 對應路徑 dockerfile: Dockerfile # 對應檔案 ``` - 確認遠端主機 Docker 有開啟 ```docker sudo systemctl start docker ``` ## GitHub Action 打包上傳 範例專案:https://github.com/Wcc723/docker-express-sample-mongo ### 準備流程 1. 準備好 DockerHub Key,登入 Docker Hub 後在 [MyAccount > Security](https://hub.docker.com/settings/security) 可以建立 2. 準備 GitHub 儲存庫建立 Repository secrets,在 儲存庫 > Settings > Actions 中可以找到 1. Environment secrets 與 Repository secrets 1. **Repository secrets 對整個儲存庫中的所有工作流程可見。** 2. Environment secrets 僅對特定環境中的工作流程可見。 2. Secrets 與 Variables 1. Secrets:用於存儲機密資訊,如 API 密鑰、憑證、密碼等,這些資料應該保密並且不應該被洩露。 2. Variables:用於存儲非機密資訊,如環境配置、常數值、參數等。這些資料不需要特別保密,可以是公開的配置信息。 3. 在專案中建立 `.github/workflows/docker-image.yml` yml 檔案可自行命名 - 加入以下程式碼: ```docker name: Build and Push Docker Image # 當推送符合 'v*' 模式的標籤時觸發此工作流程 on: push: tags: - 'v*' jobs: build: runs-on: ubuntu-latest # 使用最新的 Ubuntu 作業系統運行此工作流程 steps: - name: Checkout repository # 儲存庫程式碼 uses: actions/checkout@v2 - name: Set up Docker Buildx # 設置 Docker Buildx 環境 uses: docker/setup-buildx-action@v1 - name: Login to DockerHub # 登入 Docker Hub uses: docker/login-action@v2 with: username: ${{ secrets.DOCKER_HUB_USERNAME }} # 使用儲存在 Secrets 中的 Docker Hub 使用者名稱 password: ${{ secrets.DOCKER_HUB_TOKEN }} # 使用儲存在 Secrets 中的 Docker Hub 訪問令牌 - name: Build and push # 建置並推送 Docker image uses: docker/build-push-action@v3 with: context: . # 設定建置上下文為當前目錄 push: true # 在建置完成後推送映像到 Docker Hub platforms: linux/amd64,linux/arm64 # 目標平台為 AMD64 和 ARM64 tags: | # 設定 Docker 映像的標籤 ${{ secrets.DOCKER_HUB_USERNAME }}/2024-node-course-express-mongo:latest ${{ secrets.DOCKER_HUB_USERNAME }}/2024-node-course-express-mongo:${{ github.ref_name }} - name: Logout from DockerHub # 從 Docker Hub 登出 run: docker logout ``` 4. 將專案 push 至 GitHub 上 5. 將儲存庫加入 Tag,在 GitHub 上可以直接在 Release 頁面中加入 6. 在 Action 流程中檢視運行狀態(失敗率高,可多加嘗試 7. 回到 Docker Hub 檢視推送狀態 ### 補充說明: - GitHub Action 是付費服務,有提供部分的免費額度,可以在以下網站檢視剩餘額度:https://github.com/settings/billing/summary - GitHub Action 中的 uses,有許多套件可以做使用,可以在以下網站找到:https://github.com/marketplace?type=actions - 本範例所使用的 uses 1. **actions/checkout@v2** - **來源**:官方行動,由 **`actions`** 組織提供。 - **用途**:用來檢出(checkout)儲存庫中的代碼,以便後續步驟可以訪問和操作這些代碼。 2. **docker/setup-buildx-action@v1** - **來源**:由 Docker 提供和維護,放在 **`docker`** 組織下。 - **用途**:設置 Docker Buildx 環境,這是 Docker 的一個 CLI 插件,用於構建多平台映像。 3. **docker/login-action@v2** - **來源**:由 Docker 提供和維護,放在 **`docker`** 組織下。 - **用途**:用來登錄 Docker Hub,以便後續步驟可以推送映像到 Docker Hub。 4. **docker/build-push-action@v3** - **來源**:由 Docker 提供和維護,放在 **`docker`** 組織下。 - **用途**:建置並推送 Docker 映像。這個行動能夠建置多平台映像並推送到 Docker Hub。 ## 六角的 Docker 架構 ![image](https://hackmd.io/_uploads/SkWYdXlr0.png) ## 其他資源 ### **1. 20 分鐘入門 Docker,建立屬於你自己的 Docker Image** 影片連結:https://youtu.be/RsY5cCc9RGM 補充文件:[連結](https://www.casper.tw/development/2023/10/07/docker-container/) ### **2. 運行 Docker 在 Ubuntu 環境|從本地端上傳 Docker Image 至 Ubuntu 伺服器** > 本範例是使用 .tar 的方式,直接透過本地端傳入 Ubuntu 環境 > 影片連結:https://youtu.be/JocSDHOFNzw 補充文件:[連結](https://www.casper.tw/development/2023/10/08/ubuntu-docker/) ### **3. 超容易!10 分鐘透過 Docker hub 部署 image** 影片連結:https://youtu.be/hxX5MIohy1Q ### **4. Docker 搭配 GitHub Action,git push 達成自動化部屬** > 本範例是在透過 GitHub Action 上傳時,直接包含 ssh 登入虛擬主機,並且啟用 Docker 服務的手法 > 影片連結:https://youtu.be/NXhTMrlooic 範例程式碼:https://github.com/Wcc723/node-ironman-sample-2023/blob/feature/action-docker/.github/workflows/deploy-docker-vps.yml ### **5. Docker Compose 神器:一行指令部署 MongoDB 和 Node.js!** 影片連結:https://youtu.be/Bxr0A3tdgMc ### **6. 使用 Portainer 的 GUI 管理伺服器 Docker 服務** > 進階,使用 GUI 介面管理 Docker 服務 > 影片連結:https://youtu.be/o7ZPkruxRbg 補充文件:[連結](https://www.casper.tw/development/2023/10/11/portainer/) ### **7. Docker Compose 搭配 GitHub Action,一鍵部署到底的自動化服務** 影片連結:https://youtu.be/LJZ9YQOgu2w ### **8. 使用 Traefik 進行反向代理|單一伺服器綁定多網域** > 包含 Docker Network、CloudFlare、DNS 設定、HTTPS 等各項操作 影片連結:https://youtu.be/CV3pi8KQEy0 補充文件:[連結](https://www.casper.tw/development/2023/10/14/traefik/)