XServerのWordPressブログをCloudflare Pagesに移行した話
長年XServerでWordPressブログを運営していました(と言っても記事の投稿はすっかり止まってましたが…汗)が、思い切ってHugo+Cloudflare Pagesに移行しました。 表示速度の向上、ランニングコストゼロ、Markdownでの執筆環境など、メリットが多く大満足です。
この記事では、実際に移行した手順とハマったポイントをまとめます。
なぜ移行したのか
- コスト削減:XServerのサーバー代(月額1,000円程度)をなくしたかった
- 高速化:静的サイトはサーバーレンダリングがないため表示が速い
- 管理の簡素化:WordPressのプラグイン更新・セキュリティ対応が面倒だった
- Markdown執筆環境:もともとMarkdownやGitを日常的に使っており、相性が良い
移行の全体像
WordPress(XServer)
↓ エクスポート(XMLファイル)
↓ wordpress-export-to-markdown で変換
Hugo(ローカル)
↓ GitHub にプッシュ
Cloudflare Pages(自動ビルド&デプロイ)
↓ カスタムドメイン設定
jiru-labo.com で公開
Step 1:Hugoのインストール
macOSの場合はHomebrewで一発です。
brew install hugo
hugo version
インストール後、ブログ用のプロジェクトを作成します。
hugo new site Blog
cd Blog
Step 2:テーマの設定
今回は Mainroad テーマを使いました。シンプルで日本語ブログに向いています。
git init
git submodule add https://github.com/vimux/mainroad.git themes/mainroad
hugo.toml を編集してテーマを設定します。
baseURL = "https://jiru-labo.com/"
locale = "ja"
title = "じるラボ"
theme = "mainroad"
summaryLength = 70
[pagination]
pagerSize = 10
[taxonomies]
category = "categories"
tag = "tags"
[params]
description = "〜50代から目指せ!Webアプリケーションエンジニアへの道〜"
authorbox = true
pager = true
post_meta = ["date", "categories"]
mainSections = ["posts"]
[params.author]
name = "じる"
[params.sidebar]
home = "right"
list = "right"
single = "right"
widgets = ["search", "recent", "categories", "taglist"]
[params.thumbnail]
visibility = ["list", "post"]
[markup]
[markup.goldmark]
[markup.goldmark.renderer]
unsafe = true
注意:
paginateは旧設定名で、Hugo v0.128以降は[pagination] pagerSizeを使います。Cloudflare PagesのHugoバージョンによってはエラーになるので注意。
Step 3:WordPressの記事をエクスポート
- WordPressの管理画面 → ツール → エクスポート
- 「すべてのコンテンツ」を選択してXMLファイルをダウンロード
Step 4:XMLをMarkdownに変換
wordpress-export-to-markdown を使います。
npx wordpress-export-to-markdown
対話形式でいくつか質問されます。
Path to WordPress export file: export.xml
Output folder: output
Create year folders: No
Create month folders: No
Create a folder for each post: Yes ← ページバンドル形式にする
Save images: Yes
変換後、output/ フォルダ内に各記事がフォルダ単位で生成されます。
これを content/posts/ にコピーします。
cp -r output/* content/posts/
Step 5:フロントマターの修正
WordPressからの変換では、アイキャッチ画像が coverImage: というキーで出力されます。
Mainroadテーマは thumbnail: を使うので一括置換します。
find content/posts -name "index.md" -exec sed -i '' 's/^coverImage:/thumbnail:/' {} \;
また、画像はページバンドルの images/ フォルダに入っているので、パスを合わせます。
find content/posts -name "index.md" -exec sed -i '' \
's|thumbnail: "\(.*\)"|thumbnail: "images/\1"|' {} \;
各記事に <!--more--> タグを追加すると、トップページで記事の冒頭だけ表示されます。
Step 6:テーマのサムネイル表示をカスタマイズ
Mainroadテーマはサブモジュールのため、テーマファイルを直接編集しても Cloudflare Pagesのビルドには反映されません。
代わりに、プロジェクトルートの layouts/ フォルダに同名ファイルを置くことで
テーマをオーバーライドできます(Hugoの標準機能)。
mkdir -p layouts/partials
layouts/partials/post_thumbnail.html を作成し、
ページバンドル内の画像を Resources.GetMatch で取得するように修正します。
{{- if $thumbnail := .page.Params.thumbnail }} {{- $class := .class }} {{-
$visibility := .page.Site.Params.thumbnail.visibility | default (slice "list"
"post") }} {{- if in $visibility $class }} {{- $resource :=
.page.Resources.GetMatch $thumbnail }} {{- $imgURL := cond (ne $resource nil)
$resource.RelPermalink ($thumbnail | relURL) }}
<figure class="{{ with $class }}{{ . }}__thumbnail {{ end }}thumbnail">
{{ if eq $class "list" }}<a
class="thumbnail__link"
href="{{ .page.RelPermalink }}"
>{{ end }}
<img class="thumbnail__image" src="{{ $imgURL }}" alt="{{ .page.Title }}" />
{{ if eq $class "list" }}</a
>{{ end }}
</figure>
{{- end }} {{- end }}
Step 7:GitHubにプッシュ
GitHubでリポジトリを作成し、プッシュします。
git add .
git commit -m "initial commit"
git remote add origin git@github.com:ユーザー名/Blog.git
git push -u origin main
Step 8:Cloudflare Pagesにデプロイ
- Cloudflare Dashboard にログイン
- Workers & Pages → 作成 → Pages → Gitに接続
- GitHubリポジトリを選択
- ビルド設定を入力:
| 項目 | 値 |
|---|---|
| フレームワークプリセット | Hugo |
| ビルドコマンド | hugo --minify |
| ビルド出力ディレクトリ | public |
環境変数 HUGO_VERSION |
0.147.0 |
ポイント:
HUGO_VERSIONを指定しないと古いバージョンが使われてビルドエラーになることがあります。
Step 9:カスタムドメインの設定
ネームサーバーをCloudflareに変更
Cloudflareにドメインを追加し、XServerのネームサーバーをCloudflareのものに変更します。
XServer側:
- アカウントパネル → ドメイン → ネームサーバー設定変更
- Cloudflareから指定されたネームサーバーを入力(例:
joan.ns.cloudflare.com)
反映には最大48時間かかります。
Cloudflare PagesにカスタムドメインをひもづけEL
- Workers & Pages → 対象プロジェクト → カスタムドメイン
- カスタムドメインを設定 →
jiru-labo.comを入力 - 同様に
www.jiru-labo.comも追加
しばらく待つと「アクティブ」「SSL有効」になります。
ハマったポイントまとめ
① paginate が非推奨エラー
Cloudflare PagesのHugoでは paginate = 10 が使えません。
# NG(旧)
paginate = 10
# OK(新)
[pagination]
pagerSize = 10
② サムネイルが表示されない
テーマはgitサブモジュールのため、ローカルで編集してもCloudflareには反映されません。
layouts/partials/ にオーバーライドファイルを置くのが正解です。
③ GitHubへのpushがSSHエラー
リモートURLがHTTPSになっていてエラーになる場合はSSHに切り替えます。
git remote set-url origin git@github.com:ユーザー名/Blog.git
SSHキーがGitHubに登録されていない場合は ~/.ssh/id_ed25519.pub の内容を
GitHubのSettings → SSH keysに追加してください。
④ 画像パスの問題
WordPressエクスポートで生成される画像パスはフラットなファイル名ですが、
ページバンドル形式では images/ サブフォルダに入ります。
フロントマターの thumbnail: パスを images/ファイル名 に修正が必要です。
まとめ
| 項目 | 移行前 | 移行後 |
|---|---|---|
| サーバー | XServer(有料) | Cloudflare Pages(無料) |
| CMS | WordPress | Hugo(静的サイト) |
| 執筆形式 | ビジュアルエディタ | Markdown |
| デプロイ | FTP/プラグイン | git push で自動 |
| 表示速度 | 普通 | 高速 |
移行作業は半日〜1日程度かかりましたが、完了後は管理が格段に楽になりました。 Markdownで記事を書いてgit pushするだけで公開できるのは、エンジニアには特に快適です。
WordPressからの脱出を考えている方の参考になれば幸いです。