如果你遺失了(或根本沒記下)MariaDB 的 root 密碼,而你的 WordPress 網站是透過 Docker Compose 執行,其實毋須驚慌,你的資料仍然是安全的。這篇教學會一步一步帶你用「乾淨、安全」的方式重設 root 密碼,把資料庫救回來。無論你是剛架第一個部落格的新手,還是同時管理多個網站的開發者,都可以依照這個指引操作。
為甚麼會發生這種情況 😧
當你第一次啟動 Docker Compose stack 時,MariaDB 會透過 MYSQL_RANDOM_ROOT_PASSWORD=1 這個環境變數,自動產生一組隨機的 root 密碼,並只在容器日誌(logs)中輸出 一次。 如果當時沒有記下來,之後就沒辦法再找回那一組密碼。 而在資料庫已經初始化之後,就算你在 docker-compose.yaml 裡改動 MARIADB_ROOT_PASSWORD,MariaDB 亦不會再理會這個變數。
好消息是:你的 WordPress 資料庫內容完全不會因此受影響。 我們接下來要做的,只是重設 root 密碼,不會是動到你的資料。
開始之前:先確認你的 Volume 名稱
請先打開你的 docker-compose.yaml,找出 MariaDB 使用的 volume 名稱,大致會類似以下設定:
services:
mariadb:
image: mariadb:latest
volumes:
- mariadb_data:/var/lib/mysql
environment:
MYSQL_RANDOM_ROOT_PASSWORD: "1"
volumes:
mariadb_data:在這個例子中,volume 名稱是 mariadb_data。 請記下來,後面步驟會用到。
第 1 步:先把現有的 stack 停掉
首先,先把整個 stack 完全停下來,避免有任何正在進行的資料庫連線干擾操作:
docker compose down⚠️ 千萬不要使用 docker compose down -v,否則會把 volume 連同所有 WordPress 資料一併刪除。
第 2 步:啟動以「安全模式」運行的 MariaDB 容器
接著,我們建立一個臨時的 MariaDB 容器,掛載你現有的 volume,並跳過權限檢查來取得登入資訊庫:
docker run --rm --name temp-mariadb \
-v mariadb_data:/var/lib/mysql \
mariadb:latest \
--skip-grant-tables --skip-networking--rm:容器停止後會自動移除,毋須手動清理。--skip-grant-tables:暫時略過權限表,讓你可以在沒有密碼的情況下登入。--skip-networking:關閉遠端連線,只保留本機操作,較為安全。
請保留這個終端機視窗運作不要關閉,另開啟一個新的終端機視窗繼續以下步驟。
第 3 步:進入臨時容器的 Shell
在新的終端機中輸入:
docker exec -it temp-mariadb bash然後以 root 使用者登入 MariaDB(此時毋須密碼):
mariadb -u root如果你看到 MariaDB [(none)]> 這個提示符號,表示已成功登入。
第 4 步:檢查目前的 root 帳號狀態
在變更任何設定之前,先確認 root 使用者存在,以及它的認證方式:
USE mysql;
SELECT user, host, authentication_string, plugin FROM user WHERE user='root';
FLUSH PRIVILEGES;SQL你應該會看到類似以下的結果:
| user | host | authentication_string | plugin |
|---|---|---|---|
| root | localhost | *6BB4837EB7432910… | mysql_native_password |
這裡的 authentication_string 是一組經過雜湊處理的密碼,我們沒辦法從其反推出原本的明碼。不過,這是很正常的。
第 5 步:重設 root 密碼
現在,讓我們正式修改 root 使用者的設置,設定新密碼,並重新載入權限表。
ALTER USER 'root'@'localhost' IDENTIFIED BY 'YourNewStrongPassword123!';
FLUSH PRIVILEGES;SQL💡 請務必設定一組強密碼:建議混合大小寫字母、數字與符號,長度至少 16 個字元以上,畢竟這是資料庫的最高權限帳號。
如果你使用的是較舊版本的 MariaDB(10.4 之前),請改用以下指令:
UPDATE user SET authentication_string=PASSWORD('YourNewStrongPassword123!')
WHERE user='root' AND host='localhost';
FLUSH PRIVILEGES;SQL第 6 步:確認密碼已成功更新
再次查詢 user 資料表,確認雜湊值已經改變:
SELECT user, host, authentication_string, plugin FROM user WHERE user='root';SQL只要 authentication_string 與第 4 步時看到的值不同,即表示新密碼已生效。 然後輸入後輸入以下指令離開 MariaDB:
EXIT;SQL接著離開容器的 shell:
exit由於我們之前使用了 --rm,這個臨時容器也會停止並自動刪除。
第 7 步:更新 docker-compose.yaml
接下來,把 docker-compose.yaml 中的 MARIADB_ROOT_PASSWORD 更新為剛才設定的新密碼(方便未來查閱及統一設定):
environment:
MARIADB_ROOT_PASSWORD: "YourNewStrongPassword123!"儲存檔案後,重新啟動整個 stack:
docker compose up -d第 8 步:確認一切正常運作
先測試以 root 登入:
docker compose exec mariadb mariadb -u root -pYourNewStrongPassword123!然後測試 WordPress 對應的資料庫帳戶是否仍然可以正常連線(注意:WordPress 通常會有一個專用帳號,而不是使用 root):
docker compose exec mariadb mariadb -u wordpress -pwordpress_db_password wordpress最後,在瀏覽器中開啟你的 WordPress 網站,確認頁面正常載入。在整個過程中都沒有動到 WordPress 的資料庫內容,所以網站應該會像平常一樣運作。
預防再度被鎖在門外的小貼士
為了避免將來再次遇到同樣情況,可以考慮以下做法:
- 將密碼存放於
.env檔案,並在.gitignore中排除,然後在docker-compose.yaml內以環境變數方式引用,例如${MARIADB_ROOT_PASSWORD}。 - 在正式環境中,建議使用 Docker Secrets 來管理敏感資訊。
- 切勿讓 WordPress 使用 root 帳戶連線資料庫,而是建立一個權限受限的專用資料庫使用者。
- 在更動資料庫設定或結構之前,務必先備份 volume:
docker run --rm -v mariadb_data:/data -v $(pwd):/backup alpine \ tar czf /backup/mariadb_backup.tar.gz /data
