最近、メインサイトを humfurie.org から humfurie.com に移しました。単なる名前の変更だと思っていましたが、実際には DNS、ダイナミック DNS、Cloudflare のキャッシュ、リバースプロキシ、DNS フィルター、そしてセルフホストしているほぼすべてのサービスに影響しました。ここまで大変だとは思ってもみなかったので、何が変わったのか、何を更新する必要があったのか、同じことをする人が確認すべきことを書き残します。
何が変わったか
2つのドメインの役割が同時に入れ替わったことが、通常の移行より複雑になった理由です。
- humfurie.org は humfurie.com になりました。現在はメインサイト兼ポートフォリオです。
- humphrey.humfurie.org は humfurie.org になりました。こちらは別のウェブサイトで、Laravel を学ぶためのサイドプロジェクトとして作っている Laravel と React 12 のアプリです。
つまり humfurie.org は単に消えたのではなく、以前とはまったく別のサイトを指すようになりました。これはキャッシュなどに影響します(後述します)。
ステップ 1: DNS レコードとダイナミック DNS
最初の作業は、すべてのドメインとサブドメインを新しい DNS レコードに追加することでした。公開しているサービスにはそれぞれ専用のホスト名があるため、新しいドメインの下に1つずつレコードが必要でした。
さらに、Portainer で oznu のイメージを使ってダイナミック DNS(DDNS)を設定しました。DDNS は、自宅回線のグローバル IP アドレスが変わっても DNS レコードがその回線を指し続けるようにする仕組みです。これがないと、ISP が新しいアドレスを割り当てたときに、セルフホスト環境が気づかないうちに止まってしまうことがあります。
ステップ 2: サブドメイン上のすべてのサービスを切り替える
サブドメインで動いているものはすべて新しいドメインに移す必要がありました。思っていたより数が多かったです。
- ポートフォリオと新しい humfurie.org のサイト
- Immich
- AdGuard
- Outline
- n8n
- humfurie.org の API
- Resend のインスタンス
- Cordova のサイト
- LibreChat
- R2 のインスタンス
どのサービスも自分の設定の中でホスト名を参照しているので、DNS を変えたあとに「設定したら放置」というわけにはいきませんでした。
ステップ 3: Cloudflare のキャッシュをやり直す
切り替えのあと、ページが正しく読み込まれなくなりました。原因はキャッシュで、Cloudflare が古い環境のコンテンツや設定を保持したままでした。正常に読み込めるようにするため、キャッシュをやり直す必要がありました。
humfurie.org については、そのキャッシュ設定も別にやり直しました。そのアドレスにあったサイトとはもう別のウェブサイトなので、以前のキャッシュの挙動は意味をなさなくなったからです。ドメインを別のサイトに使い回す場合は、同じ対応が必要になると思ってください。
ステップ 4: コードと MCP 接続の更新
コード側では、ポートフォリオを humfurie.com を使うように修正しました。個人用のサービスが別のドメインで到達できるようになったので、Claude の MCP も更新しました。古い URL はもう使えなくなっていたためです。それが終わってから、すべての変更を push しました。
ステップ 5: サーバー側(これで終わりではなかった)
コードを push すれば終わりだと思っていましたが、違いました。セルフホストのサーバーにデプロイ済みのサービスにも、新しいドメインを反映する必要がありました。
- SSH でサーバーに接続し、すべてのサービスを pull しました。
- 各サービスが起動時に読み込むドメイン設定を持つ .env ファイルを更新しました。
- リバースプロキシの Traefik を更新しました。Traefik はホスト名でリクエストを振り分けるため、ドメインを変えると変更箇所も大量になります。
- DNS 機能を使っているので、AdGuard の項目も新しいドメインに合わせて更新しました。
ステップ 6: まだ説明のつかない警告(ローカル? それともグローバル?)
すべて順調だと思ったところで、新しい問題が出ました。一部のサブドメイン(n8n、outline、cordova)が安全でないと表示され、ブラウザに「接続はプライベートではありません」と出ます。これはまだ未解決で、正直なところ、自分のネットワーク内だけの問題なのか、誰にでも起きるグローバルな問題なのかもまだわかっていません。
これまでにわかったことと、なぜ辻褄が合わないのかは次のとおりです。
- Google のセーフ ブラウジングのサイトステータスでは、サイトは安全と表示されますが、それでも警告は出ます。
- SSL 証明書は問題なさそうです。Mac から n8n.humfurie.com を確認したところ、切り替えた日に発行された有効な Let's Encrypt 証明書で、ホスト名も正しいものでした。少なくともその経路では、証明書が壊れているようには見えません。
- DNS が不可解な応答を返しています。AdGuard のクエリログを見ると、返ってくるアドレスは 0.0.0.0 または 192.168.0.0 で、本来はサーバーが 192.168.1.1 で応答するはずです。私の見る限り、自分のサイトだけでなくすべてのサイトで起きているため、Google ではなく自分の DNS 設定が原因である可能性が高いと考えています。
現時点で疑っているのは AdGuard です。DNS 機能を使っていて、移行中に多くの設定を変更したからです。空のアドレスを返す DNS フィルターがあれば、ブラウザはどこにも到達できず、証明書の警告はその副作用かもしれません。ただし確認はできておらず、新しいドメインに対する実際のレピュテーションの問題が一部にある可能性も排除できません。次は、クエリログで応答の理由(ブロック、リライト、上流の応答のどれか)を確認し、AdGuard、ルーター、1.1.1.1 のようなパブリックリゾルバーの応答を比較し、同じサイトをスマートフォンのモバイル回線から開いて、問題がネットワークの外でも再現するかを確かめます。
ローカルの問題かグローバルの問題かがわかったら、このセクションを更新します。
ドメインを切り替えるときのチェックリスト
- 始める前に、旧ドメインのホスト名を使っているサービスをすべて洗い出す。
- 新しいドメインとサブドメインをすべて DNS レコードに追加し、IP が変わる場合は DDNS を設定する。
- CDN のキャッシュを消去して作り直す。特に、旧ドメインが別のサイトを指すようになる場合は必須。
- リポジトリ内のコードだけでなく、すべてのアプリ設定と .env ファイルを更新する。
- リバースプロキシのルーティングルールを更新する。
- 旧名称を参照しているローカル DNS やフィルタリングのルールを更新し、ネットワークの外のデバイスからもテストする。
- MCP 接続など、URL でサービスを呼び出す連携を更新する。
- 早い段階で Google Search Console に新しいドメインを登録しておくと、サブドメインにフラグが立ったときにセキュリティ警告を確認し、審査をリクエストできる。
最後に
ほとんどの環境は新しいドメインで動いていますが、想像よりはるかに多くの手順が必要で、ステップ 6 の警告はまだ残っています。大事な教訓は、セルフホストでは DNS、キャッシュ、ルーティングのように普段は意識しなくなった部分も含めて、すべての依存関係を自分で管理するということです。同じような移行を計画しているなら、先にチェックリストを作り、自分のネットワークの内側だけでなく外側からもテストしてください。思い出したことがあれば、この記事に追記していきます。