前言
你正在看的這個部落格,是我用 Docker + WordPress 自己架的。沒有用 Blogger、沒有用 Medium、沒有用任何託管服務。
為什麼要自己架?因為掌控感。身為後端工程師,我想要完全控制自己的網站——從佈景主題到資料庫,從部署流程到備份策略。而且老實說,把整套系統容器化的過程本身就很好玩。
這篇文章會完整分享本站的技術架構,包含 Docker Compose 設定、WordPress 配置、自訂主題整合,以及自動化 setup 腳本的設計。如果你也想自架部落格,這篇可以當作參考。
為什麼選擇 Docker + WordPress?
為什麼是 Docker?
- 環境一致性:不管在哪台機器上,
docker compose up就能跑起一模一樣的環境 - 乾淨隔離:WordPress、MySQL 各自在自己的容器裡,不會污染主機環境
- 版本管理:整個部署設定都在
docker-compose.yml裡,可以 git 追蹤 - 易於備份遷移:打包 volume 就能搬到另一台機器
為什麼是 WordPress?
你可能會問:後端工程師為什麼不用 Hugo、Gatsby、Hexo 這些靜態網站生成器?
原因有幾個:
- WordPress 的編輯體驗真的很好,尤其是需要上傳圖片、嵌入程式碼時
- 我想要動態功能:搜尋、分類、標籤、留言
- 自訂主題的自由度很高,而且 PHP 其實寫起來不難(對後端工程師來說)
- WordPress 有龐大的外掛生態系,需要什麼功能通常都找得到
Docker Compose 設定
本站的核心就是一個 docker-compose.yml,定義了兩個服務:
version: '3.8'
services:
db:
image: mysql:8.0
container_name: blog-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD:-rootpass123}
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: ${DB_PASSWORD:-wppass123}
volumes:
- db_data:/var/lib/mysql
networks:
- blog-network
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
interval: 10s
timeout: 5s
retries: 5
wordpress:
image: wordpress:php8.2-apache
container_name: blog-wordpress
restart: unless-stopped
depends_on:
db:
condition: service_healthy
ports:
- "8080:80"
environment:
WORDPRESS_DB_HOST: db:3306
WORDPRESS_DB_NAME: wordpress
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: ${DB_PASSWORD:-wppass123}
WORDPRESS_TABLE_PREFIX: wp_
volumes:
- wp_data:/var/www/html
- ./wp-content/themes/techblog:/var/www/html/wp-content/themes/techblog
networks:
- blog-network
volumes:
db_data:
wp_data:
networks:
blog-network:
driver: bridge
幾個設計要點
1. 健康檢查(healthcheck)
MySQL 容器啟動後需要一點時間初始化。加上 healthcheck,WordPress 容器會等到 MySQL 真正準備好才啟動,避免連線錯誤。
2. Volume 掛載策略
我用了兩種 volume:
- Named volume(
db_data,wp_data):由 Docker 管理,資料持久化 - Bind mount(
./wp-content/themes/techblog):把本機的主題目錄直接掛進容器,這樣修改主題檔案會即時反映,不需要重建容器
本機檔案系統 容器內
├── docker-compose.yml
├── setup.sh
└── wp-content/
└── themes/
└── techblog/ ←→ /var/www/html/wp-content/themes/techblog/
├── style.css
├── functions.php
├── front-page.php
└── ...
3. 環境變數
密碼用環境變數帶入,有預設值但可以覆蓋。正式環境記得用 .env 檔或 Docker secrets 來管理敏感資訊。
自動化 Setup 腳本
每次重新部署,都要手動設定 WordPress 很麻煩。所以我寫了一個 setup.sh,把整個初始化流程自動化:
#!/bin/bash
set -e
echo "=== 啟動 Docker 容器 ==="
docker compose up -d
echo "=== 等待 WordPress 準備就緒 ==="
until docker exec blog-wordpress curl -sf http://localhost > /dev/null 2>&1; do
echo " 等待中..."
sleep 3
done
echo "=== 安裝 WP-CLI ==="
docker exec blog-wordpress bash -c '
if ! command -v wp &> /dev/null; then
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
chmod +x wp-cli.phar
mv wp-cli.phar /usr/local/bin/wp
fi
'
echo "=== 安裝 WordPress ==="
docker exec blog-wordpress wp core install \
--url="https://shnovaj.com" \
--title="Tech Blog" \
--admin_user=admin \
--admin_password=admin123 \
--admin_email=admin@example.com \
--allow-root
echo "=== 啟用自訂主題 ==="
docker exec blog-wordpress wp theme activate techblog --allow-root
echo "=== 設定永久連結 ==="
docker exec blog-wordpress wp rewrite structure '/%postname%/' --allow-root
echo "=== 建立分類 ==="
CATEGORIES=("後端技術" "程式藝術" "創客" "數學" "心得分享")
for cat in "${CATEGORIES[@]}"; do
docker exec blog-wordpress wp term create category "$cat" --allow-root 2>/dev/null || true
done
echo "=== 建立範例文章 ==="
docker exec blog-wordpress wp post create \
--post_title="Hello World — 歡迎來到我的技術部落格" \
--post_content="這是第一篇文章。" \
--post_status=publish \
--post_category=1 \
--allow-root
echo "=== 設定完成!==="
echo "前台:https://shnovaj.com"
echo "後台:https://shnovaj.com/wp-admin"
echo "帳號:admin / admin123"
WP-CLI 的威力
setup.sh 的核心是 WP-CLI——WordPress 的命令列工具。有了它,所有原本需要在網頁後台操作的事情,都可以用指令完成:
# 安裝外掛
wp plugin install classic-editor --activate --allow-root
# 匯入文章
wp post create --post_title="文章標題" --post_content="$(cat article.html)" --allow-root
# 匯出資料
wp db export backup.sql --allow-root
# 更新 WordPress
wp core update --allow-root
這代表整個部落格的設定是可重現的——刪掉所有 Docker volume,重新跑 setup.sh,就能得到一模一樣的部落格。這對後端工程師來說,是不是很有安全感?
自訂主題的整合
本站使用自訂的 techblog 主題,設計理念是模仿 iquilezles.org 的暗色極簡風格。
主題的目錄結構:
techblog/
├── style.css # 主樣式表(含主題資訊)
├── functions.php # 主題功能設定
├── front-page.php # 首頁模板
├── single.php # 單篇文章模板
├── archive.php # 分類/標籤列表
├── page.php # 靜態頁面
├── search.php # 搜尋結果
├── 404.php # 404 頁面
├── header.php # 頁首
├── footer.php # 頁尾
├── sidebar.php # 側邊欄
└── screenshot.png # 主題預覽圖
因為主題目錄是用 bind mount 掛進容器的,所以我在本機用編輯器修改 PHP/CSS 檔案,瀏覽器重新整理就能看到效果,開發體驗非常順暢。
備份策略
自架部落格最怕的就是資料遺失。我的備份策略很簡單:
資料庫備份
#!/bin/bash
# backup.sh
DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR="./backups"
mkdir -p "$BACKUP_DIR"
# 匯出資料庫
docker exec blog-db mysqldump \
-u wordpress \
-pwppass123 \
wordpress > "$BACKUP_DIR/db_$DATE.sql"
# 備份上傳的媒體檔
docker cp blog-wordpress:/var/www/html/wp-content/uploads \
"$BACKUP_DIR/uploads_$DATE"
echo "備份完成:$BACKUP_DIR"
還原
# 還原資料庫
docker exec -i blog-db mysql \
-u wordpress \
-pwppass123 \
wordpress < backups/db_20260225_120000.sql
# 還原媒體檔
docker cp backups/uploads_20260225_120000/uploads \
blog-wordpress:/var/www/html/wp-content/
開發環境 vs 正式環境
目前本站是跑在本機的開發環境。如果要搬到正式環境,需要加上:
1. Nginx 反向代理 + SSL
# 正式環境增加 nginx 服務
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf
- ./certbot/conf:/etc/letsencrypt
depends_on:
- wordpress
2. Let’s Encrypt 自動續約
# 用 certbot 取得免費 SSL 憑證
docker run --rm -v ./certbot/conf:/etc/letsencrypt \
-v ./certbot/www:/var/www/certbot \
certbot/certbot certonly --webroot \
-w /var/www/certbot -d yourdomain.com
3. 資源限制
# 限制容器的記憶體和 CPU 使用
wordpress:
deploy:
resources:
limits:
memory: 512M
cpus: '1.0'
遇到的坑與解法
坑 1:檔案權限問題
WordPress 容器內的 Apache 用 www-data 用戶執行,但 bind mount 的檔案可能是你本機用戶的權限。
# 解法:調整容器內的權限
docker exec blog-wordpress chown -R www-data:www-data \
/var/www/html/wp-content/themes/techblog
坑 2:WordPress 生成錯誤的 URL
如果你的 WORDPRESS_CONFIG_EXTRA 沒設好,WordPress 可能會把 URL 寫死成 http://localhost。
environment:
WORDPRESS_CONFIG_EXTRA: |
define('WP_HOME', 'https://shnovaj.com');
define('WP_SITEURL', 'https://shnovaj.com');
坑 3:MySQL 初始化太慢
有時候 MySQL 第一次啟動要很久(特別是在 ARM Mac 上),WordPress 容器會因為連不上資料庫而失敗。這就是為什麼 healthcheck + depends_on.condition 很重要。
小結
用 Docker 自架部落格的好處是完全的掌控權和可重現的部署流程。壞處是你要自己處理所有的維運工作——備份、安全性更新、SSL、效能調校。
對後端工程師來說,這些其實都是日常工作會接觸到的東西,做起來不會太陌生。而且在自己的部落格上實踐這些技術,本身就是一種很好的學習方式。
如果你決定要自架,我的建議是:先在本機用 Docker 跑起來,等內容累積到一定程度、確認有持續寫作的動力後,再考慮搬到 VPS 上。過早租伺服器,最後可能只是多花錢養蚊子。
延伸閱讀
- Docker Compose 官方文件
- WP-CLI Handbook
- WordPress Docker 官方映像
- Let’s Encrypt 免費 SSL
- 本站原始碼 — 包含 docker-compose.yml 和自訂主題