從 VVV 遷移到 Docker:使用 Traefik 遷移兩個 WordPress 網站(實戰紀錄)

我使用 Vagrant 進行本地網站開發已多年,原本並無意轉向 Docker 平台;但隨著 AI 技術的興起,我決定​​嘗試一下。以下是我的一份實戰紀錄:將 loyalent.wordpress.test 與 staging-blocksy.woodwood.test 從 Vagrant(VVV)遷移到 Docker Desktop,使用 Cursor 遷移兩個 WordPress 網站, 以及一路上除錯的完整過程。

目標

起點是熟悉的本地 WordPress 環境:VVV(Varying Vagrant Vagrants) 在 Windows 上運行兩個客戶網站:

  • loyalent.wordpress.test — Polylang、qTranslate 遷移歷史、Blocksy 子主題
  • staging-blocksy.woodwood.test — Blocksy 測試站,附完整外掛套件

目標是在 G:\vvv\project-local 建立現代化架構:

project-local/
  traefik/compose.yml          # 共用反向代理
  loyalent/
    app/public_html/           # WordPress 程式碼
    db/                        # MariaDB 持久化資料
    nginx/                     # 各站點專屬 Web 伺服器設定
    compose.yml
  staging-blocksy.woodwood.test/
    ...相同結構...Code language: PHP (php)

設計原則:

  • 每個網站一個 Compose 檔案
  • 共用外部網路(traefik_shared)供 Traefik 路由
  • 維持 app/db/nginx/ 分離
  • 保留 VVV 自動 bootstrap 行為(外掛、主題、自訂初始化腳本)

第一階段:規劃(第一天)

檢視 Vagrant 設定

在撰寫任何 YAML 之前,先讀取兩個 VVV 網站目錄與 config.yml,了解必須保留的內容:

網站網域特殊行為
loyalentloyalent.wordpress.testPolylang site
staging-blocksystaging-blocksy.woodwood.test

架構決策:是否保留 Nginx?

早期就遇到一個關鍵問題:在 Traefik 後方,各站點的 Nginx 還有必要嗎?

答案:有必要,至少對這次遷移而言。

VVV 使用 Nginx 處理 WordPress 重寫規則、靜態資源快取,以及轉發到 PHP-FPM。搭配 wordpress:php8.2-fpm 時,仍需要某個元件終止 HTTP 並代理到 9000 埠。Traefik 負責主機路由;Nginx 負責 WordPress 語意。

另一種做法——wordpress:apache,由 Traefik 直接路由到 WordPress——較簡單,但會偏離 VVV 的模型。

計畫內容

共定義六項待辦:

  1. 各站點資料夾結構
  2. Compose 檔案(dbwordpressnginx、Traefik 標籤)
  3. 從 vvv-init.sh 移植的 bootstrap 腳本
  4. 從 VVV 範本轉換的 Nginx 設定
  5. Dev Container 設定
  6. 啟動驗證

第二階段:實作(第二天上午)

建置內容

共用 Traefik 堆疊(traefik:v3.3):

  • 80 埠供 HTTP 路由
  • 8080 埠供儀表板
  • Docker provider,exposedbydefault=false

各站點堆疊包含:

  • mariadb:10.11 + 健康檢查
  • wordpress:php8.2-fpm
  • nginx:alpine 搭配 Traefik 標籤
  • bootstrap 服務(profile tools)供 WP-CLI 初始化
  • dev 服務供 Dev Containers 使用

Bootstrap 腳本將 VVV 佈建流程轉為 Docker:

  • 等待資料庫 → 下載 WordPress → wp-config → 安裝或還原 SQL
  • 依 .env 安裝外掛/主題
  • 站點專屬 hooks(loyalent 的 Polylang 遷移)

WordPress 檔案以 robocopy 從 VVV 複製(loyalent 約 12 MB,staging 更大)。


第三階段:除錯馬拉松(第二天下午)

我嘗試在“詢問模式”(ask mode)下使用 Agent,並進行手動除錯。結果,「簡單遷移」在這裡變成數小時的除錯。

錯誤 1:Docker 守護程序未執行

failed to connect to the docker API at npipe:////./pipe/dockerDesktopLinuxEngine

解法: 啟動 Docker Desktop、啟用 WSL 2,等待鯨魚圖示穩定。

錯誤 2:Vagrant 無法啟動 — 8080 埠衝突

Traefik 儀表板與 VVV 都要使用 8080。

解法: 在 vagrant up 前於 Traefik 執行 docker compose down

錯誤 3:Vagrant SSH 卡住

VM 在跑,但 2222 埠的 SSH 一直無法完成。

替代方案: 從 VirtualBox 主控台直接匯出資料庫,或使用磁碟上既有的 SQL 備份。

從 VVV 遷移到 Docker:使用 Traefik 遷移兩個 WordPress 網站(實戰紀錄)
從VirtualBox 主控台直接匯出資料庫
從 VVV 遷移到 Docker:使用 Traefik 遷移兩個 WordPress 網站(實戰紀錄)

從VirtualBox 主控台直接匯出資料庫 (Windows Explorer)

錯誤 4:過期的 Docker 網路

從 VVV 遷移到 Docker:使用 Traefik 遷移兩個 WordPress 網站(實戰紀錄)
network not found

network cc562749a6e0… not found

解法: 關閉所有堆疊、docker network prune、重建 traefik_shared,再以 --force-recreate 啟動。

錯誤 5:120 秒後資料庫仍未就緒

Bootstrap 等待 MariaDB 逾時——但 MariaDB 其實是健康的。

根本原因: wp db check 會對既有資料表執行 mysqlcheck。在空資料庫上永遠失敗。

解法: 將健康檢查改為:

wp db query “SELECT 1″ –path=”$WP_PATH”

錯誤 6:DB_HOST 仍是 localhost

遷移後的 wp-config.php 指向 localhost;在容器內這代表容器本身,而非 db 服務。

解法: wp config set DB_HOST db:3306

錯誤 7:Blocksy Companion 安裝衝突

Destination folder already exists: blocksy-companion-pro/

解法: 偵測已遷移的進階版外掛目錄並啟用,而非重新安裝;設定 WP_CLI_CACHE_DIR=/tmp/wp-cli-cache

錯誤 8:Traefik 404/網站無法連線

多個問題疊加:

  1. loyalent 堆疊沒有 nginx 容器(只有 wordpress + db)
  2. traefik_shared 網路標籤不一致(external: true 與 compose 建立衝突)
  3. Windows 上 Traefik v3.3 Docker provider 探索問題

解法:

  • 確保每個站點堆疊都有 nginx
  • 一致地將網路標為 external: true
  • 將 Traefik 升級至 v3.6.2
  • 加上明確的 router → service 標籤

錯誤 9:loyalent 壞掉,staging 正常

根本原因: 資料庫中作用中主題為 twentytwentyfive,但複製後主題目錄不完整。

解法: 啟用 blocksy-child,將 WPCACHEHOME 從 /srv/www/loyalent/... 改為 /usr/local/lsws/wordpress/...

錯誤 10:登入帳密錯誤

Bootstrap 建立了新的 admin/password。VVV 的真實使用者從未匯入。

解法: 從 G:\vvv\vvv-local\database\sql\backups\ 匯入 loyalent.sql(約 12 MB),並執行 HTTPS → HTTP 的 search-replace。


第四階段:與正式環境一致(第三天)

更新外掛時出現 FTP 提示

更新 Yoast SEO 時 WordPress 要求 FTP 帳密。

原因: Windows 綁定掛載的檔案 + 未定義 FS_METHOD

解法(兩站):

define(‘FS_METHOD’, ‘direct’);

define(‘FS_CHMOD_DIR’, 0775);

define(‘FS_CHMOD_FILE’, 0664);

維護模式卡住

Briefly unavailable for scheduled maintenance.

原因: 瀏覽器更新失敗後殘留的 .maintenance 檔案。

解法: 刪除 .maintenance,改以 WP-CLI 更新。

staging 頁尾文字錯誤

環境頁尾
VVVCopyright © 2026 – by Lim
DockerCopyright © 2026 – WordPress Theme by CreativeThemes

原因: Bootstrap 啟用了父主題 blocksy,覆蓋了存放自訂器設定的 blocksy-child

解法: 啟用 blocksy-child、從 .env 清除 INSTALL_THEMES=blocksy,並在安裝主題之後執行 site hooks。

與正式站(woodwood.xyz)的頁首/CSS 不一致

比對 Docker staging 與正式站後發現:

  1. 約 1,100 筆過期 URL — 資料庫中的 woodwood.xyzhttps:///srv/www/... 路徑
  2. LiteSpeed Cache — CDN 指向無法連線的 cdn.woodwood.xyz;JS/CSS 延遲載入破壞首屏
  3. 缺少 Blocksy 動態 CSS — 快取清除後未重新產生 global.css(約 22 KB)

已套用修正:

  • 對所有舊 URL 執行 search-replace
  • 在本地 Docker 停用 LiteSpeed Cache
  • 重新產生 wp-content/uploads/blocksy/css/global.css
  • 設定 WP_DEBUG_DISPLAY false 以隱藏 PHP 8.2 棄用通知

結果: 頁首雙色漸層(#DFE9F3 → 白)、膠囊形主按鈕、卡片版面與正式站一致。

最終架構

從 VVV 遷移到 Docker:使用 Traefik 遷移兩個 WordPress 網站(實戰紀錄)

啟動順序:

# 1. hosts 檔案(一次性)

echo "127.0.0.1 loyalent.wordpress.test" >> /c/Windows/System32/drivers/etc/hosts

echo "127.0.0.1 staging-blocksy.woodwood.test" >> /c/Windows/System32/drivers/etc/hosts

# 2. Traefik

cd /g/vvv/project-local/traefik && docker compose up -d

# 3. 各站點

cd /g/vvv/project-local/loyalent

docker compose up -d

docker compose --profile tools run --rm bootstrapCode language: PHP (php)

經驗教訓

1. 遷移的核心是資料庫,檔案相對簡單

複製 public_html 很直接。沒有 VVV 的 MariaDB 匯出檔,就會得到全新 WordPress:錯誤使用者、空的自訂器設定、缺少內容。在拆除 Vagrant 前務必匯出資料庫。

2. wp db check 不是連線測試

在空資料庫上會永遠失敗。請用 wp db query "SELECT 1" 檢查就緒狀態。

3. 主題自訂器設定在子主題裡

會強制安裝父主題的 bootstrap 腳本會默默抹掉你的設計。Site hooks 必須在安裝主題之後執行,並明確啟用 blocksy-child

4. 快取外掛在本地行為不同

CDN URL 指向正式環境的 LiteSpeed Cache 會在 Docker 上弄壞 CSS/JS。本地開發請停用或重新設定。

5. Blocksy 動態 CSS 是檔案,不只是 transient

雙色頁首來自 wp-content/uploads/blocksy/css/global.css。只清 transient 而不重新產生此檔案,頁首會變成純白。

6. Windows 綁定掛載需要 FS_METHOD=direct

否則 wp-admin 更新外掛會退回不存在的 FTP 提示。

7. Vagrant 與 Docker 的埠衝突很實在

8080(Traefik 儀表板)、80(HTTP)、2222(Vagrant SSH)——事先規劃哪個堆疊佔用哪些埠。


交付成果

產物用途
traefik/compose.yml共用反向代理
*/compose.yml各站 WordPress 堆疊
*/nginx/default.confWordPress Nginx 規則
*/app/scripts/bootstrap.sh等同 VVV 的佈建流程
*/app/scripts/site-hooks.sh站點專屬修正(DB 匯入、主題、CSS)
*/.devcontainer/devcontainer.jsonVS Code Dev Containers
README.md安裝與操作手冊

兩個網站最終在 Docker 上運行,由 Traefik 路由,VVV 資料已還原,視覺上與正式環境一致——經過約兩天的規劃、實作與系統性除錯。


本文整理了我將開發環境由 VVV 遷移至 Docker 平台的過程與探索,點擊此處可查看其他相關分享成果。

woodwood
woodwood

木木,2017 年起寫網誌。喜歡旅行、新科技和小玩意,把見聞與筆記留在這裡——給未來的自己,也給路過的你。