Skip to content

WordPressからMkDocsに替える

はじめに

このWebサイトは(現在は)WSL2上のNginx単体で処理が完結しているが、過去はWordPressを使用していた。

正確には、Material for MkDocsを使用して、元ネタのMarkDownファイルから静的コンテンツを生成し、それをNginxで全世界に公開している訳だが、実際にサーバーとして動いているのはNginxのみである。サーバーがNginxのみなので軽量で管理も楽だ。

ここでは、元のWordPressの構成をMkDocsに置き換えた際の苦労について、自分のためのメモとして読み物に纏めようと思う。

現行構成

更改前の構成(移行、現行構成と書く)としては以下の通りである。

現行構成のはじまり

無秩序に増改築していった現行構成の成り立ちについて書く。

growiを使い始める

確か2022年の頃だっと思う。たまたま当時の仕事でgrowiに触れていたのだが、

「growiを使えば、自宅で簡単にサーバー立てられるのでは?記述もMarkDownでできるしこりゃ楽でええわ」

と思って触り始めてみたのだと記憶している。仕事でDockerにも触れていたので、どうせだったら流行り(*1)のDockerで動かそうと考えて、最初はDocker Desktop on Windowsでgrowiを使って自宅サーバーを立てた。

元々はWizardryのプレイ日記を知り合いに見せるためにサイトを作るつもりだったので、「外部のブログサービスを使用する」という選択肢は最初から頭になかった。限られた用途に使うだけなので、アクセス数も限られているだろうし、折角だから自分であれこれ触ってみたい、という考えである。ついでにミドルウェアの設定などを自分で弄ってそれを仕事にも役立ててしまおうと、当時のおれは感心にも思った訳だ。

(*1)流行りというか、当時で既に枯れた技術であると言える。おれにとっては目新しかったというだけ。

growiからWordPressへ

さて、こうしてしばらくはgrowiに満足して記事を書いていたのだが、

「スマホからでも簡単に見られて、かつ、もっとリッチな機能が欲しい!」

みたいな雑な思い付きで、何となくWordPressを導入したように思う。取り敢えず触って動かしてみて遊ぶ、というのが、何かを始める際のおれの大体のモチベーションである。子供と一緒で長期的な視座がまるでない。

リバースプロキシにNginxを入れる

そういう流れでWordPressを入れてはみたのだが、今度はgrowiからの記事移動が面倒臭い。記事移行が終わるまでgrowiを生かしておく必要があったので、バックエンドのWordPressとgrowiにそれぞれリクエストを振り分けるリバースプロキシとして、フロントにNginxを入れた。

当時の仕事では、TomcatのリバースプロキシにApacheを使っていた筈だ。それなのになぜここでApacheではなくNginxを選んだのかは、今となっては完全に忘れてしまった。思い出せないという事は大した理由ではなかったのだろう。

現行構成の概要

現行構成についてざっくり箇条書きで書く。

DynamicDNS

前述した通り、No-IPを使ってdezikomoe.ddns.netのドメインを取った。

自身のIPアドレスの通知は、No-IPが配布しているDUCというツールを使って行うことができる。

ルーター

当時はバッファローのWXR-2533DHP2を使っていた。現在はNECのWX7800T8 PA-WX7800T8を使っている。

ルーターのポートマッピングで、ポート80(HTTP)とポート443(HTTPS)へのリクエストを、Nginxが動いている母艦PCに振り分けする。

母艦OS

当時はWindows10 Professionalだったが、途中でWindows11 Professionalに変更した。というか、おれはWindows10を使い続けたかったのに、Microsoftに強制的に変更させられた。「Windows10は最後のWindows」とは何だったのか?

どちらの場合でも、同じくWindows Defenderファイアウォールでポート80(HTTP)とポート443(HTTPS)の穴開けが必要である。

ここまで下準備をして、やっと外部からの通信がWindows上のNginxまで届くようになる。面倒だが仕方がない。この時代に自分のWindowsPCでホストしようとなどという物好きは少ないだろう。これについてはMicrosoftが正しいと思う。

Nginx

既に書いてしまったが、Nginxではポート80ポートとポート443ポートでlistenしている。

ちょっと面倒なのだが、default.confの設定で以下のようにしていた。これまたざっくり書くと、概ね以下の4パターンである。然し今になって現行構成のdefault.confを見ると、「ああ、色々苦労したんだなあ」という形跡が読み取れる。平たく言うと汚い。

パターン1:ポート80(HTTP) growiの記事へのリクエストをWordPressに飛ばす

return 301 https://$host/対応するURL;で対応するWordPressのURLに飛ばす。

# 五つの試練 旅人の財産 攻略マップ tp[0-9]+ を切り出して飛ばす
location ~* ^/user/dezikomoe/wizardry_the_five_ordeals/tp(?<tp_number>[a-z0-9]+)/?$ {
    return 301 https://$host/wp/wizfo/tp$tp_number/;
}
パターン2:ポート80(HTTP) growi固有のAPIリクエストをgrowiに流す

proxy_pass http://localhost:3000;で、バックエンドのgrowiに流す。

参考にしたqiitaの記事まで律儀にコメントに残している所が我ながら偉い。

# growiのAPIを許可
location ~* /js/|/favicon.ico|/_api/|/attachment/|/styles/|/images/|/socket.io {
    # 参考 https://qiita.com/StoneDot/items/e6c755fc3a6e94cc4d58#apache-2427
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   Host $host;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_cache_bypass $http_upgrade;
    proxy_pass         http://localhost:3000;
    access_log off;    # うざいのでログに出さない
}
パターン3:ポート80(HTTP) それ以外のリクエストをWordPressのトップに飛ばす

それ以外のリクエストは、https://dezikomoe.ddns.net/ permanent;で飛ばす。

# rewriteしてWordPressへ飛ばす
location = / {
    rewrite ^(.*)$ https://dezikomoe.ddns.net/ permanent;
}

自分で書いた設定だが以下が気になったので、ここで懺悔する。

  • リダイレクトの際にreturn 301rewrite https://dezikomoe.ddns.net/ permanentが混在しているのは何故だろう?揃えよう。
  • http://dezikomoe.ddns.net/パスへのリクエストをhttps://dezikomoe.ddns.net/パスに流す定義がないな。我ながらアホか。
パターン4:ポート443(HTTPS)でのアクセスをWordPressに流す

ポート443(HTTPS)は、http://localhost:4430;でバックエンドのWordPressに流す。

# 正規のアクセス WordPressへ流す
location / {
    proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header   Host $host;
    proxy_set_header   X-Forwarded-Proto https;
    proxy_http_version 1.1;
    proxy_set_header   Upgrade $http_upgrade;
    proxy_set_header   Connection "upgrade";
    proxy_cache_bypass $http_upgrade;
    proxy_pass         http://localhost:4430;
}

WordPress

バックエンドのメイン。Docker Desktop on Windowsにて、ポート4430で動かす。

growi

バックエンドの残骸。Docker Desktop on Windowsにて、ポート3000で動かす。

なぜWindowsでNginxか

自宅サーバーの醍醐味は何かと言えば、それはアクセスログ解析であろう。暗い醍醐味だがこれが楽しいので仕方がない。

当初はNginx自体もDocker Desktop on Windowsで動かしていたのだが、リクエスト元のIPアドレス(*2)がどうしてもログに出力されず、Stack OverFlowを散々漁っても「このような事象が起きていますが解決できません」的なやりとりしか発見できなかったので、遂に諦めてWindows上でNginxを動かしたのである。今なら解決できそうな気もするが、当時は途中で気持ちが折れた。

(*2)当たり前だがX-Forwarded-Forには正しく渡したつもり。

次期構成

拡張に拡張を重ねた継ぎ接ぎの現行構成対して、次期構成は以下のように非常にシンプルだ。

  • フロントWebサーバー:Nginx(on WSL2)
  • DynamicDNS:MyDNS

サイト更改に合わせてドメインを取り直したかったので、AIに候補を聞いた上で、日本語が使えて老舗のMyDNSを選んだ。

後述するが、MyDNSへのIPアドレス通知はcurlを投げるだけで済むので楽だ。今は何でもAIが教えてくれる。

MkDocs

2026-06-14の日記に書いたが、MarkDownからの静的サイト生成にはMkDocsを使用している。

  1. VS CodeでMarkDownを編集する
    MarkDownのエディタは色々試したが、最終的にはVS Codeに落ち着いた。
    MarkTextは少しファイルが大きくなると洒落にならんレベルで重かった。論外だと思ったので付記しておく。

  2. mkdocsで静的サイトを生成する
    ターミナルでmkdocs buildのコマンドを叩けば、後はmkdocsが静的サイトを生成してくれる。
    静的サイトの生成先には、WSL2から見える場所に指定すればOK。

これだけで良い。楽だ。二度とWordPressの管理画面を使わずに済む。

自動化設定

ログを見る際に手動でコマンドを叩いていたので、落ち着いてきた辺りで色々自動化しよう。

MyDNSへのIPアドレス通知

DynamicDNSサービスとして使用しているMyDNSは、一定期間の間にcurlを使って自身のグローバルIPアドレスを通知する必要がある。

ISPから付与されているIPアドレスも不定期で変わるため、一定間隔での自動通知は必須と言える。今まで試験運用だったのでサボっていた。

シェルスクリプトを作る

まず、ホームディレクトリにでも以下のシェスクリプトを置く。

#!/bin/bash
curl -u ユーザID:パスワード https://ipv4.mydns.jp/login.html

実行権限を付与する

シェスクリプトにはchmodで実行権限を付けるのを忘れずに。

$ chmod +x mydns_update.sh
$ ll mydns_update.sh
-rwxr-xr-x 1 dezikomoe dezikomoe 77 Jul  8 17:47 mydns_update.sh*

crontabを登録する

crontabを登録する。

$ sudo crontab -e

10分ごとに実行するよう、以下の行を追加する。ログ出力先には動作確認用に適当に同じ場所を指定した。更新が10分だと短すぎるだろうか?と思い、MyDNSのサイトを見てみたが、適切なタイミングは見つけられなかった。

なお、今回、生まれて初めてnanoを使ったのだけれど、普段はLinux環境ではvimを使っているので、どうも使いにくかった……。

*/10 * * * * /home/dezikomoe/dezikomoe_sh/mydns_update.sh >> /home/dezikomoe/dezikomoe_sh/mydns.log 2>&1

crontabを確認する

crontab -lで、設定した内容を確認する。先程の内容が表示されればOK。

$ sudo crontab -l
(中略)
*/10 * * * * /home/dezikomoe/dezikomoe_sh/mydns_update.sh >> /home/dezikomoe/dezikomoe_sh/mydns.log 2>&1

Nginxの自動起動

Windowsの再起動時に備えて、WSLを起動すればNginxが自動起動するようにしておく。

サービスの自動起動を登録する

systemctlでサービスの自動起動を登録しておく。

$ sudo systemctl enable nginx
Synchronizing state of nginx.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable nginx

自動起動を確認する

動作確認をする。コマンドの実行結果がenabledになっていればOK。

$ sudo systemctl is-enabled nginx
enabled