Select Page

Docker 學習日誌:看懂 docker build,從映像建置到容器更新

學 Docker 時,很容易先記住一串指令,等到遇上「明明 build 成功,服務卻沒有更新」,才發現還有一些觀念需要釐清。

這篇從一條常見的建置指令出發,記錄映像、標籤、建置範圍與快取的關係,再整理部署時值得注意的七件事。範例使用通用的 Python API 專案名稱,方便套用到自己的環境。

一、先看懂這條指令

假設專案根目錄叫做 my-project,在該目錄執行:

docker build -t demo-api:1 -f api/Dockerfile .
指令片段意義
docker build依照 Dockerfile 建立映像
-t demo-api:1將映像命名為 demo-api,標籤設為 1
-f api/Dockerfile指定要使用的 Dockerfile
.以目前目錄作為建置範圍,也就是 build context

docker build:依照配方製作映像

Dockerfile 描述建置步驟;image(映像)是產物;container(容器)則是由映像建立、可以啟動的執行個體。

常見指令包括:

  • FROM:選擇基礎映像,開始一個建置階段。
  • RUN:在建置過程執行命令,例如安裝套件。
  • COPY:將檔案複製到映像內。
  • CMD:設定容器啟動時預設執行的命令。

映像由多個檔案系統層組成,但不能把「每條 Dockerfile 指令」都當成「新增一層檔案」。例如 CMD、ENV 主要記錄設定;FROM 則引入基礎映像。可參考 Dockerfile 官方說明。

-t demo-api:1:給映像一個容易引用的名稱

demo-api 是映像名稱,1 是 tag(標籤)。標籤由使用者自行命名,Docker 不會因為寫了 1,就自動幫你維護版本歷史。

如果再次使用同一標籤建出不同映像,demo-api:1 會改為指向新映像。舊映像若沒有其他標籤,可能顯示為 <none>;若仍被容器引用,就不能直接當作可清除的垃圾。

已存在的容器不會因為 tag 改指向新映像,就自動換版本。

實際發布時,可以改用 demo-api:1.0.1 這類明確標籤,並約定不覆寫已發布版本,讓追蹤與回復更容易。標籤本身是可變的引用,詳見 Docker image tag。

-f api/Dockerfile:選擇配方的位置

在本文這種本機目錄建置方式中,未指定 -f 時,Docker 預設使用 context 根目錄下的 Dockerfile。

-f api/Dockerfile 表示使用子目錄內的檔案,不代表把 build context 改成 api/。

.:決定 COPY 能從哪裡拿檔案

假設專案包含以下內容:

路徑用途
api/Dockerfile建置配方
api/main.pyAPI 程式
api/requirements.txtPython 套件清單
shared/共用模組
compose.yaml服務設定
.dockerignore建置時要排除的檔案

Dockerfile 可以寫:

COPY api/main.py /app/main.py
COPY shared/ /app/shared/

這裡一般 COPY 的來源路徑,是從 build context 根目錄算起,不是從 Dockerfile 所在的目錄算起。COPY --from 則是另一種情境,可從其他階段或指定來源複製。

因此,在專案根目錄執行:

docker build -t demo-api:1 -f api/Dockerfile .

如果已經進入 api/,也可以明確把 context 指回上一層:

docker build -t demo-api:1 -f Dockerfile ..

重點是最後的路徑包含哪些檔案。詳見 Build context。

二、建置與部署時要注意的七件事

1. 控制 context 大小,避免帶入不需要的檔案

專案裡可能放著資料集、備份、套件目錄與環境設定。這些東西通常不需要拿來建置。

可以在 context 根目錄放入 .dockerignore:

.git/
.env
.env.*
!.env.example
.venv/
node_modules/
**/__pycache__/
**/*.pyc
data/
backups/
*.tar
*.tar.gz

請依專案調整:如果建置真的需要 data/ 中的檔案,就不能整個排除。

現代 Docker 常使用 BuildKit,能跳過未使用的檔案,並減少重複傳輸。因此,「整個目錄一定會先全部打包送出」並不是通用的描述。但明確排除無關檔案,仍能減少負擔,也避免 COPY . . 把環境設定或備份帶進映像。參考 BuildKit 與 .dockerignore 說明。

2. 安裝套件可能需要網路,離線部署要事先準備

以下建置步驟通常需要連到套件來源:

RUN apt-get update \
    && apt-get install -y --no-install-recommends curl \
    && rm -rf /var/lib/apt/lists/*

RUN pip install --no-cache-dir -r requirements.txt

基礎映像若尚未存在,也可能需要下載。使用內部套件庫或已備妥的離線套件時,做法則會不同。

若部署環境無法上網,一種常見方式是在可上網、且目標平台相容的準備機建好映像,再匯出:

docker image save -o demo-api_1.tar demo-api:1

把檔案搬到目標主機後載入:

docker image load -i demo-api_1.tar

save 和 load 處理的是映像;Compose 設定、環境變數、掛載檔案與資料庫資料,需要另外準備。若有多個服務,也要備齊各服務使用的映像。參考 docker image save 與 docker image load。

此外,同一份 Dockerfile 在不同日期重新建置,不一定得到完全相同的套件。需要可重現的版本時,應管理套件鎖定檔、基礎映像 digest 與建置來源。參考 Docker 建置最佳實務。

3. Cache 能加速建置,但不會主動檢查套件是否更新

Docker 會依指令、前面的建置狀態與相關輸入,判斷是否能重用快取。

以常見的單階段 Dockerfile 為例,調整順序可以減少重做的工作:

WORKDIR /app

COPY api/requirements.txt ./requirements.txt
RUN pip install --no-cache-dir -r requirements.txt

COPY api/main.py ./main.py
COPY shared/ ./shared/

這樣只修改程式碼時,前面的套件安裝步驟通常仍能使用快取;修改套件清單時,才需要重新安裝。參考 快取最佳化。

但 RUN apt-get update ... 或 RUN pip install ... 若命中快取,就不會實際執行,也不會上網確認是否有新版。一般 COPY 的內容或相關檔案中繼資料改變,則可能讓快取失效;只改檔案修改時間並不足以觸發。參考 快取失效規則。

需要停用建置快取時:

docker build --no-cache -t demo-api:1 -f api/Dockerfile .

如果也要嘗試更新基礎映像,可加上 --pull:

docker build --pull --no-cache -t demo-api:1 -f api/Dockerfile .

--no-cache 與 --pull 用途不同。另外,Dockerfile 裡的 pip --no-cache-dir 只控制 pip 的下載快取,不會關閉 Docker 的建置快取。Docker 旗標可參考 Buildx build 說明。

4. 定期看磁碟使用量,再決定清理範圍

多次建置後,可能累積舊映像與 build cache。因為映像之間可以共享層,磁碟占用不一定是每建一次就增加一份完整映像大小。

先查看:

docker system df
docker image ls

若要清除未被容器引用的 dangling 映像,可以執行:

docker image prune

這個命令會先要求確認;加上 -f 才會省略確認。-a 會把清理範圍擴大到所有未被容器引用的映像,包含有標籤、可能留作回復用途的版本。

映像清理也不等於清空 build cache,不必把兩者混為一談。參考 docker image prune 與 Build cache 管理。

5. Build 成功後,還要讓服務使用新映像

假設 compose.yaml 中有以下服務:

services:
  api:
    image: demo-api:1
    ports:
      - "127.0.0.1:8000:8000"

此設定假設應用程式在容器內監聽 0.0.0.0:8000,並將主機端連線限制在本機。api 是 Compose 服務名稱,demo-api:1 是映像名稱,兩者用途不同。

建置完成後,在 Compose 檔案所在目錄執行:

docker compose up -d api

Compose 偵測到映像或設定變更時,通常會重建容器。如果希望明確要求重建,即使沒有偵測到變更,也可以用:

docker compose up -d --force-recreate api

所以,--force-recreate 是強制重建的選項,不是更新映像唯一的方法。參考 docker compose up。

docker compose restart api 則是重新啟動既有容器,不能用來切換到剛建好的映像。參考 docker compose restart。

重建之前,也要知道資料放在哪裡:

資料位置重建容器時要注意的事
容器可寫層刪除舊容器時,裡面的資料會一併失去
具名 volume重新掛載相同 volume 可沿用資料;刪除 volume 另當別論
主機 bind mount資料保留在主機路徑,需確保仍掛載相同位置
外部資料庫或儲存服務需確認連線設定及新版程式的資料相容性

沒有掛載 volume,不代表重建一定安全。 上傳檔案、SQLite 或日誌若只存在容器內,就可能遺失。參考 Docker 儲存說明。

更新後可查看:

docker compose ps
docker compose logs --tail=100 api

接著實際呼叫 API 或檢查健康狀態。容器正在執行,與應用程式已正常提供服務,是兩件需要分別確認的事。

6. 搬映像之前,確認 CPU 架構

常見平台包括 linux/amd64(一般 x86-64 主機)與 linux/arm64(ARM64 主機)。

未特別指定時,建置平台通常跟隨 builder 的預設平台。不同架構的單一平台映像,不能假設能在另一台主機原生執行。

可以先檢查映像:

docker image inspect demo-api:1 --format '{{.Os}}/{{.Architecture}}'

若 builder 已具備跨平台建置能力,可明確指定目標:

docker buildx build --platform linux/amd64 --load -t demo-api:1 -f api/Dockerfile .

這裡 --load 會將單一平台建置結果載入本機映像儲存區。跨平台的 RUN 步驟可能需要模擬器、原生節點或其他支援,基礎映像與套件也必須支援目標平台。

遇到 exec format error 時,架構不符是排查方向之一,也要檢查執行檔與腳本格式。跨平台原理與前提可參考 Multi-platform builds。

7. 建置時做基本自檢,讓問題早點出現

假設程式需要 requests 套件與 curl 指令,可以在安裝完成後加入:

RUN python -c "import requests" && command -v curl

這種自檢可以提早發現套件漏裝或命令不存在。命令回傳非零狀態時,該次建置會失敗。

但自檢只能涵蓋實際檢查的項目,不能保證部署環境中的資料庫、網路、權限或完整功能都正常。建置時也應避免匯入會立刻連線正式服務的模組。

還有一個容易忽略的地方:這次 build 失敗,之前的同名映像可能仍然存在。 不要只看 docker image ls 有沒有該 tag,就認為這次建置成功。

三、把日常更新整理成固定步驟

以下假設位於專案根目錄,使用前面的 Compose 設定,而且既有容器也是由同一個 Compose 專案建立。

先建置:

docker build -t demo-api:1 -f api/Dockerfile .

確認成功後,再更新服務:

docker compose up -d api

查看狀態與日誌,再驗證實際功能:

docker compose ps
docker compose logs --tail=100 api

如果使用 Bash 自動串接建置與更新,可以使用 &&,確保前一步成功才繼續:

docker build -t demo-api:1 -f api/Dockerfile . && docker compose up -d api

若原本使用 docker compose -p demo ... 指定專案名稱,後續操作也要維持相同的 -p demo,避免操作到另一組服務。

這次學習後,我會在每次更新時依序確認:建置用了哪些檔案、產出了哪個映像、服務是否已使用新映像,以及資料是否放在能持續保存的位置。把這幾件事分開檢查,就比較容易找出更新流程卡在哪一步。

LibreChat 是什麼?Docker 安裝、多模型整合與 Ollama 串接教學

LibreChat 是什麼?Docker 安裝、多模型整合與 Ollama 串接教學

LibreChat 是把 OpenAI、Anthropic、Google、OpenAI 相容端點與本地模型,整理成一個可以自己部署、自己管理的 AI 工作台。早期把它叫做「套殼」還勉強能描述外觀,但到了現在,這個說法已經低估了它的定位。

它比較像模型與工具之間的控制層。使用者面對同一個聊天介面,管理者則能在後面決定模型來源、權限、Agents、MCP、搜尋、文件檢索與資料保存方式。對想把雲端 API 和內網 Ollama 放在一起的人,LibreChat 是很實用的開源入口。

LibreChat 是什麼

LibreChat 是可自行部署的開源 AI 平台,原始碼放在 LibreChat GitHub。它不包含自己的大型語言模型,而是把不同模型供應商、本地推理服務與工具能力接到同一個操作介面。

  • 在同一段對話裡切換不同模型
  • 保存 Prompt、Presets、對話分支與搜尋紀錄
  • 上傳文件並使用 RAG、OCR 與檔案檢索
  • 建立 Agents,串接 MCP、Skills、工具與子代理
  • 使用 Code Interpreter、Artifacts、圖片生成與網頁搜尋
  • 提供多使用者登入、角色、群組與存取控制

目前官方文件以 v0.8.x 為主,GitHub README 也會展示較新的候選版本功能。正式環境不要只看介面截圖判斷版本,部署前應先確認自己使用的映像標籤與官方升級說明。

它不是免費的 ChatGPT Plus 集合包

這是最容易誤會的地方。LibreChat 本身免費開源,不代表接進去的模型都免費

ChatGPT Plus、Claude Pro 與 Gemini 的消費者訂閱,通常也不能直接當成 API 額度使用。要呼叫官方模型,仍需準備對應的 API Key,費用由各供應商另外計算。

如果不想累積雲端 API 費用,可以改接 Ollama、llama.cpp、LM Studio、vLLM 或其他 OpenAI 相容服務,不同推理後端怎麼選,可以先看 本地大模型推理框架比較。LibreChat 負責操作與編排,模型成本、速度和能力仍由後端決定。

用 Docker 安裝 LibreChat

官方目前仍把 Docker Compose 列為最直接的本機安裝方式。先確認電腦已安裝 Git 與 Docker Desktop,再執行以下命令。

git clone https://github.com/danny-avila/LibreChat.git
cd LibreChat
cp .env.example .env
docker compose up -d

Windows PowerShell 或命令提示字元可把複製指令改成下面這一行。檔名之間要保留空格,不能把整段黏在一起。

copy .env.example .env

啟動完成後打開 http://localhost:3080。第一個完成註冊的帳號會成為管理員,系統沒有預設帳號與密碼,確認管理員可登入後,公開服務建議把 ALLOW_REGISTRATION 設為 false,避免陌生人自行註冊。

三層設定檔不要混在一起

檔案用途適合放什麼
.env密鑰與伺服器開關API Key、登入、註冊與服務環境變數
librechat.yamlLibreChat 功能設定自訂端點、模型清單、Agents、MCP 與介面選項
docker-compose.override.yml容器覆寫掛載設定檔、改連接埠、替換映像與新增服務
docker-compose.yml官方基礎配置原則上維持原樣,方便後續更新

API Key 建議放在 .env,再由 librechat.yaml 使用環境變數引用。不要把真正的 Key 直接寫進 YAML,也不要提交到 GitHub。修改設定後需要重新啟動容器才會生效。

個人環境可以由伺服器統一提供 Key。多人共用時,也可以在自訂端點把 apiKey 設為 user_provided,讓每位使用者在介面輸入自己的憑證,避免所有請求都共用同一把組織 Key。選哪一種方式,取決於費用要集中管理,還是由使用者各自負責。

docker compose down
docker compose up -d

串接內網 Ollama

LibreChat 可以把 Ollama 當成 OpenAI 相容端點。以下範例直接使用內網位置 192.168.0.240:11434。先在專案根目錄建立 librechat.yaml。

version: 1.3.13
cache: true
endpoints:
  custom:
    - name: Ollama
      apiKey: ollama
      baseURL: http://192.168.0.240:11434/v1/
      models:
        default:
          - qwen3:32b
        fetch: true
      titleConvo: true
      titleModel: current_model

接著在 docker-compose.override.yml 把 YAML 掛進 API 容器。

services:
  api:
    volumes:
      - type: bind
        source: ./librechat.yaml
        target: /app/librechat.yaml

如果 Ollama 和 LibreChat 在同一台電腦,Docker Desktop 環境可以依官方範例改用 http://host.docker.internal:11434/v1/。如果 Ollama 在另一台 AI Server,就使用可從 LibreChat 主機連到的區網 IP。遠端服務的監聽、防火牆與測試方式,可接著參考 Ollama 遠端連線教學。

不要直接把 11434 對整個網際網路開放。比較穩妥的做法是限制在內網、VPN 或反向代理後方,再用防火牆控制來源。

從聊天介面升級成 Agent 工作台

LibreChat 現在的價值,已經不只在多模型切換。Agents 可以組合系統指令、模型、工具、MCP、Skills、文件與子代理,並在需要時加入人工確認。這讓同一套介面能分別建立研究助理、文件問答、程式開發、客服與內部知識助手。

若主要需求是跨文件研究與來源整理,Open Notebook 私有 AI 研究工作流會更專門。若重點是跨模型聊天、工具與 Agent 的統一入口,LibreChat 的範圍更廣。兩者也不衝突,前者可以負責知識工作流,後者負責日常模型與代理入口。

常見安裝問題

出現 librechat.yaml 錯誤

先檢查縮排與 YAML 語法,再確認 override 已把檔案掛到 /app/librechat.yaml。容器內讀不到檔案時,主機上有 YAML 也不會生效。

3080 連接埠被占用

可在 override 把外部連接埠改成 3081:3080,之後用 http://localhost:3081 開啟。

Apple Silicon 啟動 MongoDB 失敗

官方文件指出部分 M1 到 M4 環境會遇到 MongoDB 映像的 AVX 相容問題,可在 override 將 MongoDB 映像指定為 mongo:4.4.18。這是相容性處理,不代表所有 Apple Silicon 都一定會遇到。

不知道錯在哪裡

docker compose logs api

先看 API 容器最後一段紀錄,通常會直接指出缺少的環境變數、無效 YAML、資料庫連線或供應商 API 問題。

公開部署前的安全清單

  • 第一個管理員建立後關閉公開註冊
  • 使用 HTTPS 與可信任的反向代理
  • 不要把 API Key 寫進公開 YAML 或 Git 儲存庫
  • 限制 Ollama、MongoDB 與 Redis 的網路來源
  • 定期備份資料庫與上傳檔案
  • 依團隊角色設定 Agents、MCP、檔案與對話權限
  • 升級前先查看 v0.8.x 的相容與遷移說明

LibreChat 現在已有預覽中的 Admin Panel,可管理使用者、群組、角色、系統授權與部分設定覆寫。不過預覽功能仍可能調整,正式環境不能只依賴介面上的開關,網路隔離、密鑰管理與備份仍要在基礎設施層處理。

LibreChat 適合誰

如果你只固定使用一個雲端聊天服務,官方介面通常最省事。當你開始同時使用多家模型、需要本地 Ollama、想建立不同 Agents,或要替團隊管理共用入口,LibreChat 的價值才會真正出現。

我的判斷是,LibreChat 已經從「像 ChatGPT 的開源介面」走到「自架 AI 控制台」。它不會替你省掉所有模型費用,也不會自動解決權限和維運問題,但它讓模型、工具、文件與代理不必被綁死在單一供應商。這對想建立私有 AI 工作環境的人,比單純模仿介面重要得多。

FAQ

LibreChat 可以免費使用 GPT 嗎

LibreChat 免費開源,但 GPT API 仍由 OpenAI 計費。ChatGPT Plus 訂閱通常不能直接抵用 API。想避免 API 成本,可以接本地 Ollama 或其他自架模型。

LibreChat 可以接 Ollama 嗎

可以。透過 librechat.yaml 建立 OpenAI 相容自訂端點,並把設定檔掛進容器即可。本機 Docker 可使用 host.docker.internal,內網 AI Server 則使用可連線的區網 IP。

LibreChat 適合公開給團隊使用嗎

可以,但需要 HTTPS、註冊控制、角色權限、密鑰管理、資料備份與內部服務隔離。第一個註冊帳號會成為管理員,建立後應立即檢查公開註冊設定。

Windows 跑 AI Agent 為什麼要用 WSL?完整環境整理

Windows 跑 AI Agent 為什麼要用 WSL?完整環境整理

Windows 跑 AI Agent,真正的關鍵不是把所有工具硬裝進 PowerShell,而是把 Windows 當成桌面和硬體入口,把 Linux 工具鏈交給 WSL 2,這樣做的好處很直接:Python、Node、Docker、Git、CUDA、各種開源 Agent 工具,都會更接近它們原本被設計和測試的環境。

我的判斷是,如果你在 Windows 上做 Codex、Claude Code、Cursor、OpenCode、本地模型或自動化 Agent,WSL 2 幾乎是標準底座,不是因為 Windows 不行,而是 AI Agent 這一波工具鏈大多先從 Linux 生態長出來。

先講結論

  • Windows 11 或新版 Windows 10 可以用 `wsl –install` 安裝 WSL,預設會走 WSL 2。
  • AI Agent 專案建議放在 WSL 的 `/home` 目錄,不要長期放在 `/mnt/c`。
  • VS Code 建議用 Remote WSL,讓編輯器在 Windows,工具鏈在 Linux。
  • Docker Desktop 可以啟用 WSL 2 backend,適合需要容器化 Agent 服務的人。
  • NVIDIA GPU 可以在 WSL 2 裡用 CUDA,但重點是安裝 Windows 端驅動,不要在 WSL 裡裝 Linux 顯示驅動。

為什麼 Windows 跑 AI Agent 需要 WSL

Microsoft 對 WSL 的定位很清楚:讓開發者可以在 Windows 上直接使用 Linux distribution、Linux 應用、工具和 Bash 命令列,而且不需要傳統虛擬機或雙系統。對 AI Agent 來說,這剛好補上 Windows 和開源工具鏈之間的落差。

很多 Agent 專案會同時碰到 Python、Node、Playwright、ffmpeg、SQLite、Docker、Git hooks、shell scripts。這些東西在 Linux 裡比較自然,在 Windows 原生環境則容易遇到路徑、權限、編碼、套件編譯和命令差異。

如果你正在使用 Codex 與 ChatGPT Work,或想把 OpenWork 和 OpenCode 桌面工作台 跑穩,WSL 可以讓 Windows 變成比較舒服的 Agent 開發機,而不是一直在修環境。

第一步:安裝與確認 WSL 2

Microsoft 官方文件建議,在符合版本的 Windows 上,可以用系統管理員 PowerShell 執行:

wsl --install

安裝後可以用下面指令查看 distribution 和 WSL 版本:

wsl.exe --list --verbose

如果你有多個 Linux distribution,可以用 `wsl.exe –set-default` 設定預設環境。對大多數 AI Agent 使用者,我會建議先用 Ubuntu,原因不是它最酷,而是教學、套件、問題排查和相容性資料最多。

第二步:專案不要放在 /mnt/c

這是最常見的坑。Microsoft 文件明確建議,如果你主要在 Linux 命令列裡工作,專案檔案應該放在 WSL 檔案系統內,例如 `/home/你的帳號/projects`。不要把主要專案放在 `/mnt/c/Users/…` 下面長期開發。

原因是跨 Windows 和 Linux 檔案系統會影響效能,也可能讓檔案權限、大小寫、watcher、node_modules、Python venv 出現奇怪問題。AI Agent 工作流常常有大量小檔案、快取、套件安裝和檔案監看,這種差異會被放大。

簡單說:Linux 工具鏈處理的專案,就放 Linux 檔案系統,需要從 Windows 檔案總管打開時,可以在 WSL 目錄下執行:

explorer.exe .

第三步:VS Code 用 Remote WSL

不要把 VS Code 直接開在 Windows 路徑裡,再讓終端機切來切去。比較乾淨的方式是安裝 VS Code 的 WSL 支援,從 WSL 裡開專案:

code .

這樣 UI 還是在 Windows,但 extension host、terminal、語言服務和套件環境會跑在 WSL。對 Python、Node、Rust、Go、Docker compose、Playwright 這類 Agent 常用工具,這種模式會少很多不必要的摩擦。

第四步:Docker 交給 WSL 2 backend

很多 AI Agent 工具會需要資料庫、瀏覽器服務、向量資料庫、Redis、sandbox 或 API mock。這時候 Docker 是很自然的選擇。Docker Desktop 支援 WSL 2 backend,可以讓 Windows 上的容器工作流更接近 Linux。

我會把它看成「可複製環境」的保險。今天你在 Windows WSL 跑得起來,明天移到 Linux server 或雲端 VM,踩坑會少很多。這和我之前整理 Docker 跟 command line 一樣使用 的方向一致,容器不是炫技,而是讓環境可重現。

第五步:GPU 和 CUDA 要小心裝

如果你要跑本地模型、推理框架或 CUDA 工具,WSL 2 可以吃到 NVIDIA GPU,NVIDIA 官方文件的關鍵提醒是:安裝 Windows 端 NVIDIA 驅動後,CUDA 驅動會映射進 WSL,不要在 WSL 裡安裝 Linux 顯示驅動。

這點很重要。很多人一進 Ubuntu 就照 Linux 教學裝完整 NVIDIA driver,反而把環境弄壞,WSL 裡需要的是相容的 CUDA toolkit 和使用者空間工具,不是另一套 Linux 顯示驅動。

如果你在 Windows 上遠端連自己的 AI server,可以參考我之前寫的 Windows PowerShell 連接 Ollama AI Server。如果是要本機推理,則更需要把 WSL、GPU driver、CUDA 和模型框架的版本關係先整理好。

Windows 跑 AI Agent 的 WSL 檢查表

階段建議做法原因
安裝使用 wsl –install 並確認 WSL 2取得 Linux 工具鏈與較完整相容性
檔案專案放在 /home 內避免 /mnt/c 跨檔案系統拖慢 I/O
開發VS Code Remote WSL讓編輯器在 Windows,工具鏈在 Linux
容器Docker Desktop WSL 2 backend讓 Agent 工作流更容易複製
GPUWindows 驅動 + WSL CUDA避免在 WSL 內安裝 Linux 顯示驅動
Windows 跑 AI Agent 的 WSL 檢查表
WSL 跑 AI Agent 的重點不是只把 Ubuntu 裝起來,而是把檔案、編輯器、容器和 GPU 全部放在正確位置。

我會怎麼配置一台 Windows AI Agent 機

如果是我自己整理一台 Windows AI Agent 工作機,我會照這個順序來:

  • Windows Terminal 裝好,PowerShell 和 Ubuntu 分開使用。
  • WSL 2 裝 Ubuntu,專案目錄固定放在 `/home`。
  • VS Code 用 Remote WSL 開專案。
  • Python 用 uv 或 venv 管,Node 用 nvm 或 corepack 管。
  • 需要服務就用 Docker compose,不把資料庫亂裝在 Windows 裡。
  • 需要本地模型時,先確認 NVIDIA Windows driver、WSL kernel、CUDA toolkit 和推理框架版本。

如果你的目標是 本地大模型推理框架,WSL 可以讓 vLLM、SGLang、llama.cpp、Ollama 周邊工具更接近 Linux 使用方式。如果你的目標是 Agent 開發,WSL 則可以讓 shell、瀏覽器自動化、檔案操作和套件安裝更穩。

我的判斷

Windows 不需要變成 Mac,也不需要硬裝成 Linux。最好的方式是讓 Windows 做它擅長的事:桌面、驅動、硬體管理、遊戲和日常軟體。讓 WSL 做它擅長的事:Linux 工具鏈、開源套件、容器、AI Agent 環境。

真正穩的 Windows AI Agent 工作流,不是把所有東西混在同一個地方,而是把邊界分清楚。Windows 管外層,WSL 管開發環境,Docker 管可重現服務,GPU driver 留在 Windows,專案檔案留在 Linux 檔案系統。這樣才比較不會每次換工具就重修一次環境。

延伸資源

FAQ

Windows 跑 AI Agent 一定要用 WSL 嗎?

不一定,但如果工具鏈偏 Linux、需要 Python、Node、Docker、CUDA 或多個開源套件,WSL 2 通常比純 Windows 環境穩定。

WSL 專案檔案應該放哪裡?

如果主要在 Linux 命令列工作,專案最好放在 WSL 的 `/home` 目錄,不要放在 `/mnt/c`,這樣 I/O 效能和權限行為通常比較穩。

VS Code 可以直接編輯 WSL 專案嗎?

可以。建議使用 VS Code Remote WSL,讓編輯器留在 Windows,語言工具鏈、終端機和套件環境跑在 WSL 裡。

WSL 可以用 NVIDIA GPU 嗎?

可以,但要用支援 WSL 的 Windows NVIDIA 驅動。重點是不要在 WSL 裡安裝 Linux 顯示驅動,CUDA 驅動會從 Windows 端映射進 WSL。

Docker Desktop 和 WSL 2 有什麼關係?

Docker Desktop 可以使用 WSL 2 backend,讓 Windows 上的容器工作流更接近 Linux 開發環境,適合需要複製 AI Agent 服務環境的人。

Open Notebook 是什麼?自架版 NotebookLM 工具解析

Open Notebook 是什麼?自架版 NotebookLM 工具解析

如果你常把 PDF、論文、產業報告或內部文件丟進 AI 工具整理,Google NotebookLM 確實很方便;但只要資料牽涉商業機密、未公開研究、客戶內容或公司內部知識庫,雲端上傳與模型選擇限制就會變成真正的門檻,Open Notebook 的定位,正是把 NotebookLM 類型的文件理解、問答、摘要與 Podcast 生成,搬到更可控、更可自訂的開源工作流裡。

Open Notebook 私有 AI 研究工作流示意封面圖
圖:Open Notebook 私有 AI 研究工作流示意

Open Notebook 解決的是什麼問題?

傳統文件型 AI 助手最容易卡在兩件事:資料放在哪裡,以及模型能不能換。對個人研究來說,把公開文章交給雲端 AI 問答通常沒什麼壓力;但對企業團隊、顧問、研究員或寫作者來說,資料可能包含未公開策略、訪談紀錄、合約、財務數據或客戶文件。這時候,能否自架、能否控制資料歸屬、能否選用自己的模型,就不只是偏好,而是能不能導入的前提。

Open Notebook 的優勢在於,它不是只做一個聊天視窗,而是把「文件匯入、知識庫整理、跨文件問答、來源引用、Podcast 生成、模型配置」串成一套私有 AI 研究工作流。官方 GitHub 專案 lfnovo/open-notebook 目前採 MIT 授權,官方說明也把它定位為一個 privacy-focused alternative to Google NotebookLM,截至 2026-07-07,GitHub API 顯示約 35K stars,最新 release 為 v1.10.0。

核心亮點一:資料主權回到自己手上

Open Notebook 最吸引人的地方,是它把資料控制權從平台端拉回使用者端。你可以把文件、音訊、多媒體檔案、網頁等素材放進自己掌控的環境,再用 AI 做摘要、檢索與問答。對需要處理敏感研究、公司內部文件或客戶資料的人來說,這比「功能多一點」更重要。

這也讓 Open Notebook 很適合搭配文件前處理工具。例如需要先把 PDF、Word、PPT 轉成 AI 更容易讀的文字格式時,可以參考我之前寫過的 MarkItDown 教學,先把原始文件整理成更乾淨的資料,再交給知識庫系統分析。

核心亮點二:模型不再被單一供應商綁住

NotebookLM 的好處是省事,但限制也很明顯:使用者基本上跟著 Google 的模型與產品設計走。Open Notebook 則主打 18+ AI provider,官方 README 提到支援 OpenAI、Anthropic、Ollama、LM Studio 等供應商。這代表同一套知識庫可以依任務切換模型:便宜模型做初步整理,強模型做深入推理,本地模型處理敏感資料。

如果你的工作流已經開始用 Ollama 或本地模型,Open Notebook 的價值會更明顯。它可以成為文件層的操作介面,而模型層則交給你自己的 AI server,想走本地端路線的人,也可以延伸看 GraphRAG 使用本地端的 Ollama 或 Ollama 遠端連線教學,把模型部署與文件分析分開思考。

核心亮點三:Podcast 生成更像內容製作工具

Podcast 生成是 NotebookLM 很受歡迎的功能,但固定雙人對談也限制了內容形式。Open Notebook 的方向更偏向內容製作工具:可以做 1 到 4 位 speaker,並調整角色設定與對話形式。這讓它不只適合做「兩人解說」,也能做單人旁白、三人圓桌、多人辯論或不同角色的知識導覽。

對自媒體、研究型內容創作者或企業內訓來說,這點很實用。你可以先把一批文件整理成知識庫,再把其中的核心結論轉成 Podcast 腳本,甚至為不同聽眾設計不同敘事角色。它不是單純把文字念出來,而是把文件理解、腳本結構與音訊內容生產接在一起。

核心亮點四:Ask 模式更適合跨文件研究

Open Notebook 的 Ask 模式適合處理「不是問單一文件,而是要整合一批資料」的任務。例如你有 20 份產業報告,真正想問的不是某一頁寫了什麼,而是不同報告之間是否有共同趨勢、矛盾、缺口與可引用依據。這時候,單純的檢索式問答會不夠,需要能跨文件整理、比對與引用來源的研究流程。

這也是 RAG 類工具接下來會越來越重要的原因:文件不是只被「搜尋」,而是要被組織成可以反覆推理的知識庫。Open Notebook 提供的是比較完整的操作層;而像 GraphRAG、向量資料庫、本地模型與文件轉換工具,則是可以接在底下的技術層。把這些組起來,才會形成真正可重複的 AI 工作流。

Open Notebook 和 NotebookLM 怎麼選?

比較面向Open NotebookNotebookLM
資料控制可自架,資料在自己掌控的環境以 Google 雲端服務為主
模型選擇可接多家 provider,也可接 Ollama / LM Studio主要使用 Google 模型
Podcast 形式可做 1-4 位 speaker 與自訂角色以固定形式為主
部署方式Docker、雲端或本地部署直接使用雲端產品
適合對象重視隱私、模型自由、工作流整合的人重視上手速度、不想部署的人

簡單說,如果你要的是「馬上可以用」,NotebookLM 仍然很省事;如果你要的是「資料可控、模型可換、流程可自訂」,Open Notebook 會更有想像空間。它不是每個人都需要的工具,但對研究、顧問、內容團隊與企業知識庫來說,很值得放進評估清單。

導入前要先確認的限制

Open Notebook 的自由度比較高,但也代表它不是完全零門檻。最基本的前提是你要能接受 Docker 或自架環境;如果公司電腦不能裝 Docker,或 IT 政策不允許本機服務,導入就會比較麻煩

Docker 新手可以先看 如何使用 Docker 跟用 command line 一樣,先把容器概念補起來。

算力也要看你的模型選擇。如果只是用雲端 provider,主要成本會落在 API;如果想完全本地跑模型,就要準備足夠的 GPU、記憶體與模型部署能力。換句話說,Open Notebook 降低的是資料與模型綁定,不是把所有基礎設施成本變成零。

誰最適合用 Open Notebook?

  • 研究員:需要整理大量論文、報告、訪談與來源引用。
  • 內容創作者:需要把資料轉成腳本、長文、Podcast 或系列內容。
  • 學生與知識工作者:需要把課堂筆記、PDF、網頁資料統一管理。
  • 企業團隊:需要建立內部知識庫,又不希望敏感文件全部交給外部雲端。

Open Notebook 適合把 AI 研究流程變成私有工作台

Open Notebook 的價值,不只是「開源版 NotebookLM」這麼簡單。它真正有意思的地方,是把資料主權、模型自由、Podcast 生成、跨文件研究與自架部署放在同一個工作台裡。對只想偶爾整理公開資料的人來說,它可能稍微重了一點;但對需要長期累積知識庫、處理敏感文件、或把 AI 研究流程變成團隊基礎設施的人來說,它是一個值得測試的選項。

Open Notebook Github

FAQ

Open Notebook 是 NotebookLM 的替代品嗎?

它可以被視為 NotebookLM 的開源替代方案,但重點不只是功能相似,而是提供自架、模型選擇、資料控制與更多自訂能力。

Open Notebook 一定要很強的電腦才能用嗎?

不一定。如果使用雲端模型,主要需要 Docker 與 API 設定;如果要完全本地跑大型模型,才需要更強的 GPU、記憶體與部署能力。

Open Notebook 適合企業內部知識庫嗎?

適合放進評估清單,尤其是重視資料控制、模型彈性與自架部署的團隊。不過正式導入前,仍要評估權限管理、備份、資安政策與維運成本。

雲端現代化:如何將 WordPress 部署至 Cloud Run、Cloud SQL 與 Cloud Storage

在管理多個 WordPress 專案時,傳統 VM 加架構往往面臨擴展性與維護成本的挑戰。透過 Google Cloud Run (Serverless)、Cloud SQL (代管資料庫) 與 Cloud Storage (雲端儲存) 的組合,我們可以建立一個自動縮放、安全且高效率的網站環境。

一、 架構預覽

  • 計算節點:Google Cloud Run (Docker 容器化運行)。
  • 資料庫:Google Cloud SQL (MySQL 8.0)。
  • 靜態檔案:Google Cloud Storage (GCS)。
  • 流量分配:Google Cloud Load Balancing (HTTPS 負載平衡器)。

二、 準備 Docker 鏡像與環境排除

在打包之前,請務必設定 .dockerignore 以優化鏡像體積並保護敏感資訊 。

my-wp-site/
├── Dockerfile           # 自動化打包腳本
├── wp-config.php        # 修改為讀取環境變數的版本
├── .dockerignore        # 排除不需要打包的檔案 (如 .git, local backups)
└── wp-content/
    ├── plugins/         # 放置您自定義的外掛
    └── themes/          # 放置您自定義的主題

建立 標準化 Dockerfile 範本

# 使用官方 PHP-Apache 映像檔,穩定且相容性高
FROM wordpress:php8.2-apache

# 1. 設定環境變數 (Cloud Run 預設監聽 8080,但官方 WP 鏡像預設是 80)
# 這裡我們讓 Apache 監聽 Cloud Run 指定的 PORT
RUN sed -i 's/Listen 80/Listen ${PORT}/g' /etc/apache2/ports.conf
RUN sed -i 's/:80/:${PORT}/g' /etc/apache2/sites-available/000-default.conf

# 2. 安裝必要的系統套件 (如有需要自訂 PHP 擴展可在這加)
RUN apt-get update && apt-get install -y \
    libpng-dev \
    libjpeg-dev \
    && docker-php-ext-configure gd --with-jpeg \
    && docker-php-ext-install gd

# 3. 複製現有的自定義檔案進入容器
# 建議只複製 plugins 和 themes,核心檔案由官方鏡像提供
COPY ./wp-content/plugins/ /var/www/html/wp-content/plugins/
COPY ./wp-content/themes/ /var/www/html/wp-content/themes/
COPY ./wp-config.php /var/www/html/wp-config.php

# 4. 設定正確的檔案權限 (對 WordPress 運行至關重要)
RUN chown -R www-data:www-data /var/www/html

# 5. 設定預設環境變數 (可在部署時被 gcloud 指令覆蓋)
ENV PORT=8080
ENV DB_HOST=127.0.0.1
ENV DB_USER=root
ENV DB_PASSWORD=password

# 暴露埠號
EXPOSE 8080

1. 建立 .dockerignore

Plaintext

.git
.gitignore
.dockerignore
Dockerfile
*.sql
*.zip
.vscode/
wp-config-sample.php

2. 打包與推送鏡像

PowerShell

# 編譯鏡像
docker build -t asia-east1-docker.pkg.dev/[PROJECT_ID]/wp-repo/[docker_name]:latest .

# 推送到 Artifact Registry
docker push asia-east1-docker.pkg.dev/[PROJECT_ID]/wp-repo/[docker_name]:latest

三、 資料庫遷移與設定

1. 匯入 SQL 腳本

將 .sql 檔案上傳至 Google Cloud Storage (GCS) 後執行匯入 。

注意:請確保 SQL 檔案中不含 CREATE DATABASE 或 USE 語句,以免匯入失敗或指向錯誤的資料庫。

PowerShell

gcloud sql import sql [INSTANCE_NAME] gs://[BUCKET_NAME]/[docker_name].sql --database=[docker_name]_db

2. 設定 wp-config.php 智慧判斷

為了同時支援本地開發與雲端環境,建議在 wp-config.php 加入連線判斷邏輯 :

PHP

// 偵測是否在 Cloud Run 環境 (透過 Unix Socket 連線)
if (getenv('INSTANCE_CONNECTION_NAME')) {
    define( 'DB_HOST', ':/cloudsql/' . getenv('INSTANCE_CONNECTION_NAME') );
} else {
    define( 'DB_HOST', getenv('DB_HOST') ?: '127.0.0.1' );
}

// 負載平衡器 HTTPS 辨識
if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') {
    $_SERVER['HTTPS'] = 'on';
}

四、 部署至 Cloud Run

部署時需指定 Cloud SQL 連線名稱,這會自動建立加密隧道 。

PowerShell

gcloud run deploy [docker_name] `
  --image asia-east1-docker.pkg.dev/[PROJECT_ID]/wp-repo/[docker_name]:latest `
  --region asia-east1 `
  --allow-unauthenticated `
  --add-cloudsql-instances [PROJECT_ID]:asia-east1:[INSTANCE_NAME] `
  --set-env-vars="INSTANCE_CONNECTION_NAME=[PROJECT_ID]:asia-east1:[INSTANCE_NAME],DB_NAME=[docker_name]_db,DB_USER=root,DB_PASSWORD=[PASSWORD]"

五、 設定負載平衡器 (GCLB) 與自訂網域

為了使用自有的網域(如 blog.rain.tips),建議使用 HTTPS 負載平衡器 。

  1. 建立 Serverless NEG:讓負載平衡器找到 Cloud Run 。
  2. 設定前端 IP:保留一個靜態全域 IP。
  3. Google 管理憑證:在前端設定中新增網域,Google 會自動處理 SSL 簽發與續期 。
  4. DNS 設定:將您的網域 A 紀錄 指向負載平衡器的靜態 IP 。

六、 故障排除 (Troubleshooting)

  • Error establishing a database connection:
    • 檢查 Cloud Run 服務帳戶是否擁有 「Cloud SQL Client」 角色 。
    • 確認 DB_HOST 在雲端環境是否正確指向 :/cloudsql/... 。
  • 503 Service Unavailable:
    • 確認 Cloud Run 服務已設定為 「允許未經驗證的叫用」 。
    • 檢查負載平衡器的憑證是否已變為綠色的 Active 狀態 。
  • IPv6 連線問題:
    • 若使用 Nginx 反向代理遇到 Network is unreachable,請強制 Nginx 優先使用 IPv4 或修改系統 /etc/hosts 。

參考資料