紀錄工作經驗、相關知識,解決技術相關問題。

網站相關, 資訊相關

Synology Docker Container Manager 容器化環境架設與資料持久化實作教學

Synology Docker Container Manager 容器化環境架設與資料持久化實作教學 特色圖片

Synology Docker Container Manager 是 DSM 上用來建立與管理容器的套件,本篇整理它的 Docker Compose 專案設定、資料持久化與權限對應。

部署前如果需要確認 NAS 的區域網路或對外 IP,可以先參考 如何查詢自己的IP地址(電腦IP/對外IP)。

一、 核心語法速查與規格對照

在 Synology NAS 的 Container Manager 中,可以用 Project 功能上傳或編輯 docker-compose.yml 來部署容器。以下是一份 Compose 範本,路徑、連接埠與數值請依自己的環境調整:

services:
  app:
    image: nginx:latest
    container_name: sample-nginx
    restart: unless-stopped
    ports:
      - "8080:80"
    environment:
      - TZ=Asia/Taipei
    volumes:
      - /volume1/docker/nginx/html:/usr/share/nginx/html
    deploy:
      resources:
        limits:
          cpus: '0.50'
          memory: 512M
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    networks:
      - app-net

networks:
  app-net:
    driver: bridge

範本沒有寫頂層的 version。Docker 官方文件指出,這個屬性只供參考,使用時會收到已過時(obsolete)的警告。

TZ 用來設定時區:Synology 的容器文件說明,多數容器的預設時區是 UTC,可以用環境變數 TZ 更改。

Synology Container Manager 與 Docker 核心配置規格對照

配置維度Docker CLI 原生指令Container Manager 介面Docker Compose 對應參數
容器啟動策略--restart unless-stopped容器的「設定」可編輯自動重新啟動restart: unless-stopped
資料夾掛載-v /host/path:/container/path建立容器精靈進階設定的 Volume(指定掛載路徑)volumes: 區塊設定
資源限制--memory=512m --cpus=0.5建立容器精靈的資源限制選項deploy.resources.limits
網路--network app-netNetwork 頁面(bridge 與 host 兩種驅動)networks: 與 driver: bridge

二、 關鍵機制與跨情境細部拆解

1. Container Manager 與 Docker Compose 專案

Synology 的發行說明寫明,Container Manager 是 Docker 套件的後繼者;20.10.23 版需要 DSM 7.2 以上,並新增 Project 頁面對 Docker Compose 的支援。更新後需要手動解除安裝舊的 Docker 套件。

建立 Project 時,精靈會要求填寫專案名稱、路徑(專案的工作目錄)與來源,來源可以上傳 docker-compose.yml,也可以在編輯器中直接撰寫。

Project 的操作按鈕與 Compose 指令的對應如下:

Project 操作對應指令說明
Builddocker-compose up --build --no-start建置專案的映像檔
Startdocker-compose start啟動既有容器,需先 Build
Stopdocker-compose stop停止容器但不移除
Restartdocker-compose restart重新啟動所有容器
Cleandocker-compose down停止並移除容器、網路、磁碟區與映像檔

補充說明:Container Manager 的版本需求會隨更新提高,例如 24.0.2-1543 版需要 DSM 7.2.1 以上,並支援在命令列使用 docker compose;24.0.2-1706 版需要 DSM 7.4 以上。可安裝的版本與支援機型,以 Synology 的 Container Manager 套件頁(Applied Models)與發行說明為準。

2. Volume 掛載與權限對應(PUID/PGID 與 user)

容器寫入 NAS 共用資料夾時,如果容器內行程的 UID/GID 沒有該資料夾的寫入權限,就會出現 Permission Denied。

PUID 與 PGID 不是 Docker 本身的設定。LinuxServer.io 的文件說明,這組變數讓容器內部使用者對應到主機上的使用者,而且他們的映像檔都採用這個機制。其他映像檔不一定讀取這兩個變數,使用前要先看該映像檔的說明。

不支援 PUID/PGID 的映像檔,可以改用 Compose 服務的 user 屬性。Docker 官方文件說明,user 會覆寫容器行程使用的使用者,預設值則由映像檔(例如 Dockerfile 的 USER)決定。

示意圖:小型伺服器機櫃、資料夾與透明收納盒放在同一個托盤上,代表容器掛載 NAS 資料夾
圖:bind mount:共用同一份資料夾

3. 資源限制與容器日誌管理策略

Docker 官方文件說明,容器預設沒有資源限制,可以用到主機上所能提供的資源。NAS 同時執行多個容器時,建議替容器設定 CPU 與記憶體上限。

日誌也要設定輪替。Docker 的 json-file 日誌驅動程式,max-size 預設為 -1(不限制),max-file 預設為 1,而且 max-file 要搭配 max-size 才有作用。沒有設定時,容器的日誌檔不會依大小輪替。

示意圖:長紙捲進入裁切機被分成三個固定大小的紙捲,最舊的一捲被丟進回收桶,代表日誌輪替
圖:日誌輪替:限制大小並只保留固定份數

三、 常見問題與排錯(Q&A)

1. Synology 的 Docker 套件與 Container Manager 是什麼關係?

解答:Container Manager 是 Docker 套件的後繼者,需要 DSM 7.2 以上。

Synology 的發行說明記載,Container Manager 新增了 Project 頁面的 Docker Compose 支援與容器健康狀態顯示,也支援對標籤為 latest 的映像檔偵測更新。從舊版 Docker 套件升級後,需要手動解除安裝舊的 Docker 套件。

2. 用 Docker Compose 部署多容器時,如何設定 bridge 網路讓容器互相通訊?

解答:同一個 Compose 專案的服務預設就能用服務名稱互相連線;需要隔離或指定網路時,再用頂層 networks 自訂。

Docker 官方文件說明,執行 docker compose up 時,Compose 會建立名為 <專案名>_default 的網路並讓所有服務加入,服務之間可以直接用服務名稱互連。而在 Docker 的預設 bridge 網路上,容器只能用 IP 位址互相存取;使用者自訂的 bridge 網路上,容器則可以用名稱或別名互相解析。

Synology 的 Network 頁面也建議使用自訂 bridge 網路,以控管哪些容器可以互相通訊,並啟用容器名稱的自動 DNS 解析。

要明確指定網路時,在 docker-compose.yml 宣告自訂網路,並讓需要互通的服務加入:

services:
  web:
    image: nginx:latest
    networks:
      - custom-bridge
  db:
    image: postgres:15
    networks:
      - custom-bridge

networks:
  custom-bridge:
    driver: bridge

3. 容器內寫入檔案出現 Permission Denied 時,如何對應 NAS 共用資料夾權限?

解答:先查出擁有該資料夾權限的 DSM 使用者 UID/GID,再依映像檔支援的方式帶入容器。

  1. 用 SSH 登入 NAS,查詢使用者的 UID 與 GID(把 username 換成實際帳號),輸出中的 uid 與 gid 就是要對應的數值:
    id username
  2. 如果映像檔支援 PUID/PGID(例如 LinuxServer.io 的映像檔),在 environment 帶入對應數值:
    environment:
      - PUID=1026
      - PGID=100
  3. 如果映像檔不支援這兩個變數,改用 user 屬性指定 UID 與 GID:
    user: "1026:100"

補充說明:上面的 1026 與 100 只是範例數值,要改成步驟 1 查到的結果。

4. NAS 重啟後容器陷入 Crash 迴圈,如何設定 restart policy 與 healthcheck?

解答:restart 只決定容器停止後要不要重啟,要等相依服務就緒再啟動,需要搭配 healthcheck 與 depends_on。

Docker 官方文件說明,Compose 不會等容器「就緒」,只會等到它處於執行中;depends_on 設定 condition: service_healthy 後,Compose 才會等相依服務的健康檢查通過。

  1. 替被依賴的服務設定 healthcheck:
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
  2. 在依賴它的服務設定 restart 與 depends_on:
    restart: unless-stopped
    depends_on:
      api:
        condition: service_healthy

補充說明:範例中的服務名稱 api、連接埠與 /health 路徑都是假設值,要換成自己應用程式實際提供的健康檢查端點,且 test 使用的指令必須存在於該映像檔內。

5. 如何限制特定容器的 CPU 與記憶體用量?

解答:Compose 專案在 deploy.resources.limits 設定上限,用精靈建立的容器則在建立時啟用資源限制。

Docker 官方文件說明,容器預設沒有資源限制。在 docker-compose.yml 中加入:

deploy:
  resources:
    limits:
      cpus: '1.0'
      memory: 1024M

Synology 的說明指出,資源限制在建立容器時啟用後就無法停用,容器的「設定」可以編輯資源限制。

6. Container Manager 的資料持久化,bind mount 與 Docker volume 要怎麼選?

解答:資料要放在你指定的 NAS 資料夾時用 bind mount;交給 Docker 管理儲存位置時用 volume。

Docker 官方文件說明,bind mount 是把主機上的檔案或目錄掛進容器;volume 則是在 Docker 的儲存目錄內建立新目錄,由 Docker 建立並維護。

因此需要自己決定資料夾位置、方便直接檢視與編輯時,可以用 bind mount,路徑寫成絕對路徑,例如:

volumes:
  - /volume1/docker/app-data:/app/data

補充說明:Project 的 Clean 操作會移除容器、網路、磁碟區與映像檔,Delete 則會刪除專案的所有容器與資料。執行前先確認重要資料已另外備份。

7. 容器日誌佔滿硬碟空間時,如何設定 log rotation?

解答:在每個服務下設定 logging,限制單一日誌檔大小與保留份數。

Docker 官方文件說明,json-file 的 max-size 預設不限制大小。max-size 的值是正整數加單位(k、m 或 g),max-file 只有在設定 max-size 時才有作用:

logging:
  driver: "json-file"
  options:
    max-size: "20m"
    max-file: "5"

參考資料與延伸閱讀

發佈留言