稼働中のサイトを娯楽で移行する者はいない。移行が起きるのは、今のホストが突然パスポートの写真を求めてきたときであり、24時間以内の期限付きで苦情を転送してきたときであり、あるいはデータセンターが所在する国が、データを預けるにふさわしい場所には見えなくなったときだ。何がきっかけであれ、危険なのは移行そのものだ——サイトが暗転しうる唯一の瞬間であり、不用意な一歩が新しいサーバーを、捨てようとしていたはずの身元に縫い付けてしまう唯一の瞬間でもある。
この二つのリスクには同じ処方箋が効く。しかもそれはツールではない。順序だ。正しい順序で行われた移行には、サイトが到達不能になる窓は存在しない。両方のサーバーが同時に生きていて、DNSが最後に動くものだからだ。誤った順序で行われた移行は、障害と痕跡を同時に生む。以下がその順序であり、主流プロバイダー間を行き来する場合ではなく、オフショアでKYC不要のホストへ移る人向けに書いている——仕組みそのものは同じだが、その後の後始末は同じではない。
「ダウンタイムゼロ」の本当の意味
この言葉は緩く使われがちで、その緩さが人を痛い目に遭わせる。2台のマシンから同時にHTTPを配信するのは簡単だ。2台が同時に配信している間状態を一致させ続けることこそが難しい部分であり、データを失う原因になるのもそこだけだ。だから何かを計画する前に、自分が実際にどちらを運用しているのかを見極めておく必要がある。その答えが、その夜全体の形を決めるからだ。
| 移行対象 | 実際に効いてくる部分 | 取るべきプラン |
|---|---|---|
| 静的サイト、パンフレットサイト、生成された出力 | 何もない。分割すべき状態が存在しない | コピーして検証し、切り替える。文字通りダウンタイムゼロ |
| データベース付きCMS——WordPress、Ghost、フォーラムなど | コメント・ログイン・投稿が同時に2つのデータベースに書き込まれてしまうこと | 最も静かな時間帯に、数分単位の読み取り専用フリーズを |
| ストアや、注文を受け付けるあらゆるもの | スプリットブレインが起きると、支払い済みの注文が静かに失われる | 短い作業時間帯を確保する。突き合わせ作業より安上がりだ |
| cronジョブやバックグラウンドワーカーを持つあらゆるもの | 同じジョブが両方のサーバーで発火すること——メールも二重、課金も二重 | 新しい方を起動する前に、旧ホスト側のスケジュールを無効化する |
| 同じドメイン上のメール | MXレコードはAレコードとは無関係に、独自のタイマーでキャッシュから失効する | メールは別の夜に移行し、旧MXを1週間受信可能なまま残しておく |
本当に無償なのは1行目だけだと気づいてほしい。それ以外のすべてにおいて、「ダウンタイムゼロ」が意味するのは「誰もチケットを立てないほど短い書き込みフリーズ」でしかない。04:00の2分間の読み取り専用は誤差の範囲だが、2つのデータベースにまたがる2時間の分裂書き込みは、週末をまるごと使う突き合わせ作業になる。フリーズの方を選ぼう。

DNSのTTLは、移行予定日の数日前に下げておく
リードタイムが必要な唯一のステップがこれであり、だからこそ最初に行うべきであり、だからこそ誰もが省略しがちなステップでもある。TTL——time to live、つまりレコードの生存時間——は、インターネット上のすべてのリゾルバに対して、次に問い合わせるまでどれだけの時間キャッシュしてよいかを伝える値だ。AレコードのTTLが86400なら、1時間前に問い合わせ済みのリゾルバは、レジストラ側で何を変更しようと、その後23時間は古いIPアドレスを配り続ける。
重要なのは、TTLを下げるという操作自体が、古いTTLの支配を受けるという点だ。リゾルバが新しい短い値を知るのは、キャッシュ済みの古いコピーが失効したときだけだ。だからTTLは300秒まで、切り替えの少なくとも1回分の旧TTL期間前には下げておく——1日単位のTTLなら、24〜48時間前ということになる。そうすれば、変更から5分以内に世界中がその新しいレコードに収束し、切り替えはもはやハラハラする出来事ではなくなる。
移行から数日後には、TTLを妥当な値に戻しておく。300秒のTTLは道具としては優秀だが、恒常設定としては質が悪い。問い合わせ量が跳ね上がり、DNSプロバイダーが単一障害点としての鋭さを一気に増してしまう。
覚えているものではなく、実際に移行するものを洗い出す
失敗した移行の事後検証は、いつも同じ結論に行き着く。誰もリストに書かなかった何かが、コピーされていなかったのだ。Webルートとデータベースは誰もが覚えている二つだが、以下のリストはそれ以外のすべてであり、記憶に頼らず文字通り一つずつ確認していく価値がある。
- スケジュール実行。全ユーザー分の
crontab -lと、systemdタイマー。更新フックや夜間ジョブはここに隠れている。 - サービス定義。独自のsystemdユニット、Webサーバーのvhost、PHP-FPMのプール、supervisor系の設定。
- シークレットと環境変数。
.envファイル、APIキー、データベースのパスワード、アプリケーションのソルト——これらは単にコピーするのではなく、ローテーションすべきものだと心に留めておく。 - TLS関連。証明書、そしてそれ以上に重要な、ACMEアカウントと更新設定。
- メールの身元情報。DKIM秘密鍵、SPFレコードとDMARCレコード。ここが食い違っても派手には壊れない——ただ静かにメールを迷惑メールへ送り込むだけだ。
- アップロード済みメディア。Webルートの外に置かれていることが多く、しばしば所有物の中で最も容量が大きい。
- あなたのIPアドレスを信頼している外部のすべて。決済ゲートウェイの許可リスト、Webhookの送信先、データベースのファイアウォール、IP制限付きのサードパーティAPI。03:00に「サイトは動くのに決済だけ壊れている」が起きる原因の第一位だ。
- パッケージ一覧。
dpkg --get-selectionsあるいはそれに相当するもの。新しいマシンに、ほぼ同じではなく、まったく同じ拡張機能とライブラリを揃えるために。
コピーを始める前に、このリストを書き出しておこう。この洗い出しリストは後にそのままテスト計画にもなる——1行1行が、DNSがまだその存在を知らないうちに新しいサーバー上で確認すべき項目になる。
まず新しいサーバーを構築し、何かを載せる前に堅牢化する
移行先は早めに注文し、1〜2日は空のまま動かしておく。重複稼働にコストはほぼない——小さなオフショアVPSなら月に数ドルだ——一方で、フリーズさせたデータベースを待たせたまま時間に追われて構築するのを避けられる価値は大きい。
旧環境には意図的に合わせる。同じディストリビューションと同じメジャーバージョン、同じPHPかNodeかPythonのメジャーバージョン、同じデータベースのメジャーバージョンだ。ついでに近代化したくなる誘惑は強烈だが、完全に我慢すべきだ。切り替え後にサイトが壊れたなら、変化した変数はちょうど1つであってほしい。スタックのアップグレードは2週間ほど後、なんでもない午後に、ロールバックできる状態で行えばいい。
空のうちに堅牢化しておく。鍵認証のみのSSH、デフォルト拒否のファイアウォール、自動セキュリティアップデート——最初の1時間の堅牢化チェックリストはまさにこのリストであり、何も載っていないマシンに適用するほうがはるかに簡単だ。法域を移すほど機微なデータを扱っているなら、保存データの暗号化を決めるのにもちょうどよいタイミングだ。後から組み込むとなると、また別の移行が発生してしまう。
データは2回コピーする、遅い一回と速い一回
メンテナンス時間中にすべてをコピーしたくなるのが人情だが、やるべきはその逆だ。旧サイトが何事もなくトラフィックを捌いている数日前に完全コピーを1回走らせ、切り替え時には変更分だけを移す2回目のパスを走らせる。1回目は6時間かかっても誰も気づかない。2回目は90秒で終わり、それがダウンタイム予算の全てになる。
ファイルにはrsync -aHAX --numeric-idsを使う。パーミッション、所有者、ハードリンク、拡張属性を保持できる。--numeric-idsフラグが重要なのは、新しく構築した2台のマシンの間ではUIDが一致することはまれだからだ。まず早い段階で1回実行し、切り替え直前に同じ引数でもう一度実行する——2回目は差分だけを転送する。
データベースにも同じ二段階の扱いが必要だが、道具は違う。mysqldump --single-transactionやpg_dumpを使えば、構築とテストの土台になる一貫性のある早期スナップショットが得られる。切り替え時には、短い書き込みフリーズの間に2回目のダンプを取るか——短いフリーズさえ痛手になるほど大きなデータベースなら——数日前から新しいサーバーを旧サーバーのレプリカとして立ち上げて追いつかせておき、それを昇格させる。レプリケーションを使えばフリーズは数秒で済む。だが2時間の移行を2日がかりのプロジェクトに変えてしまうので、規模が本当にそれを必要とするときだけ使うべきだ。
プッシュではなくプルで行い、自宅の回線は絶対に経由しない。コピーは新しいサーバー側から開始し、転送がホスト間でデータセンター速度のまま完結するようにする。自宅回線経由で数ギガバイトを流すのは遅いうえ、両方のマシンのアクセスログに自宅のIPアドレスを刻んでしまう——プライバシー目的の移行が何より避けたいはずの結びつきだ。旧ホストに新しいIPアドレスを知られること自体が許容できないなら、直接コピーは一切行わない。代わりに、自前のオフサイト暗号化バックアップから新しいサーバーを復元すれば、2台のマシンは一度も通信しない。
DNSがまだ知らないうちに、新しいサーバーをテストする
公開レコードを一切変更しないまま、新しいIPアドレスから本物のホスト名を配信することができるし、実際そうすべきだ——これこそが切り替えを平穏なものにする。ローカルの/etc/hostsにドメインを新しいIPアドレスへ向ける行を追加してもいいし、それを省いてcurlに1リクエストぶんだけ肩代わりさせてもいい。
curl -I --resolve example.com:443:203.0.113.10 https://example.com/
ここで洗い出しリストを一通りたどってみる。トップページと、奥にある3ページを読み込む。ログインする。フォームを送信する。ファイルをアップロードする。データベース接続が新しいローカルのものになっていて、インターネット越しに旧ホストを指したままになっていないかを確認する——これは旧サーバーを解約するまでは完璧に動いてしまうタイプのミスだ。cronジョブを手動で実行し、その出力を読む。リダイレクトを検証し、存在しないURLが200ではなくきちんと404を返すことも確かめる。
TLS証明書は、切り替えの後ではなく今、事前に発行しておく。DNS-01チャレンジを使えば、TXTレコードを通じてドメインの制御を証明できるので、Aレコードがまだ旧サーバーを指したままでも通用する。DNS変更後のHTTP-01検証を待ってしまうと、その間に訪れた初期の訪問者は全員証明書の警告を目にすることになる——守ろうとしていたはずのその窓の中で、自ら招いた障害だ。
切り替えの手順
ここまで来れば、新しいサーバーは構築済み、堅牢化済み、データも投入済みで、本物のホスト名でテストも済ませ、有効な証明書も保持している。切り替えそのものは、もはや短くて退屈なリストにすぎない——それこそが目指すべき状態だ。
- サイトに依存する人が他にいるなら作業時間帯を告知し、旧サイトを読み取り専用またはメンテナンスモードにする。
- 旧ホスト側のcronとバックグラウンドワーカーを無効化する。これは新しい方で起動する前に行う。後からでは絶対にいけない。
- 最後の
rsync差分パスと、最後のデータベースダンプを実行し、それをインポートする。 - 新しいサーバーでアプリケーションを起動し、最終データに対して
--resolve経由のスモークテストをもう一度実行する。 - AレコードとAAAAレコードを新しいIPアドレスに変更する。TTLが300秒なら、5分以内に世界中が追随する。
- 新しいホスト側でcronとワーカーを有効化する。
- 両方のアクセスログを並べて監視する。トラフィックは旧サーバーから流れ出し、新サーバー側に現れる。旧サーバーが静かになったら、切り替えは完了だ。
- 旧サーバーは1週間、稼働させたまま、配信させたまま、手を触れずに残しておく。それがロールバック手段になる。
8番目のステップは省略されがちだが、このリストの中で最も安い保険でもある。わずか数ドルの対価で、確信が持てるまでの間ずっと、DNSを元に戻す能力——5分で復旧できる能力——を保持できる。
移行が消せずに残すもの
ここからが、一般的な移行ガイドが省略する部分であり、価格ではなくプライバシーのために移行したのであれば最も重要な部分でもある。サイトを移行しても、その履歴は消えない。旧環境に関する公開または半公開のいくつもの記録が、移行後も永久に残り続ける。そのどれが残るのかを知っていることこそが、本当の決別と、決別したつもりでいるだけの状態との違いになる。
| 何が移行を記録するか | 誰が読めるか | 実際にできること |
|---|---|---|
| パッシブDNS——過去のAレコード | 商用の履歴サービスを通じて誰でも | 何もできない。旧IPアドレスはそのドメイン名と恒久的に結びついている。公開情報だと思って計画しよう。実際そうなのだから |
| Certificate Transparencyのログ | 誰でも、永久に、ドメインで検索可能 | これまで発行されたすべての証明書が一覧化される——存在を忘れていた内部向けっぽいサブドメインも含めて。説明的な名前よりワイルドカードを選んでおく |
| 旧ホストのアカウント記録 | 旧ホスト自身、そして彼らに開示を強制できる者 | カード情報、登録メールアドレス、ログイン時のIPアドレス。KYC不要の移行先が守るのは未来であって過去ではない |
| WHOIS履歴 | 商用のWHOIS履歴アーカイブ | ドメインが一度でも実名情報で登録されていれば、そのスナップショットは残る。後からプライバシー保護を適用しても撤回はできない |
| アナリティクスや広告の識別子 | 提供元、そしてページのソースを読む誰でも | 同じトラッキングIDを引き継ぐと、2つのサイトが決定的に結びついてしまう。新しいIDを発行するか、そもそも使わない |
| 旧ディスクに残されたダンプやバックアップ | 次にそのストレージを割り当てられる者 | 解約前に削除し、上書きしておく。共有ストレージでは、削除は保証ではなくヒントに過ぎないと考える |
送信済みメールのReceived:ヘッダー | すべての受信者に、永久に | 遡っての対処はできない。新しい経路が記録されるのは、移行後に送るメールだけだ |
| コピー作業中の自分自身の接続 | 自分のISP、そして両ホストのアクセスログ | これだけは完全に自分でコントロールできる。自分だと特定できるIPアドレスからは、どちらのマシンにも決して触れないこと |
正直に要約すれば、移行は過去を書き換えることはできず、できるのはこれ以上積み増さないようにすることだけだ。それでも十分に価値はあるが、この事実が判断を左右する。もし脅威モデルとして、新サイトと旧サイトを誰にも結びつけられないことが必須条件なら、同じドメインを新しいホストへ移すだけではそれは達成できない。切り替え中にどれだけ注意を払っても、それは変わらない。その場合に必要なのは新しい名前とクリーンな出発であり、これは次の節で扱う。逆に、今日以降は身元を特定できる記録を新たに生まないようにし、法的な重心を自分で選んだ法域へ移すことが目的なら、この移行はまさにそれを果たしてくれる。その後の清潔さを保つ習慣については、当社のサーバーOpSecガイドで扱っている。
ドメインの問題、そのまま使うか、それとも一新するか
サイトとドメインは本来別々の判断であるにもかかわらず、両者を混同するのはよくあることだ。ホスティングは今日移行し、レジストラには一切触れないままにしておくこともできる。サーバー側の変更が、ドメインに手を付けることを要求する理由は何もない。そうすべきかどうかは、そのドメインがあなたについてすでに何を知っているかに完全に左右される。
- ドメインは維持し、レジストラだけ変更する。被リンク、検索順位、人が実際に入力してくれる名前など、ドメインに価値がある場合に理にかなう。WHOISレコードの未来は正せても過去は正せないが、順位シグナルはすべてそのまま保たれる。ほとんどの商用サイトにとって正解はこれだ。
- ドメインは維持し、ホスト以外は何も変えない。匿名性ではなく法域、稼働率、DMCA対応方針を理由に移行したのであれば、まったく合理的な選択だ。あり得る中で最もシンプルな移行で、SEOリスクはゼロ。
- 新しいドメインにして、旧ドメインからリダイレクトする。検索順位は維持できるが、2つの名前を公開かつ恒久的に結びつけてしまう。継続性のために選ぶものであって、プライバシーのために選んではいけない——リダイレクトそのものが結びつきになる。
- 新しいドメインで、完全に決別する。結びつきを本当の意味で断ち切れる唯一の選択肢だが、それまでの検索順位も被リンクもすべて失う。ドメインの匿名性は最初の登録の時点までしか遡れないので、最初から匿名で登録すること。正しく行う方法は暗号資産による匿名ドメイン登録ガイドで扱っている。
意図的に選び、しかも切り替えの最中ではなく、その前に選んでおく。DNSを移した後でドメインについて気が変わると、デリケートな作業を2回行う羽目になる。
旧ホストを正しくデコミッションする
切り替えから1〜2週間が経ち、新サーバーのログが退屈なものになり、旧サーバーのログが空になったら、旧アカウントを閉じるタイミングだ。この順序で行うこと。魅力的に見える近道——いきなり解約ボタンを押すこと——こそが、自分のデータを他人のディスクに残してしまう原因だからだ。
- 旧IPアドレスを指すものが何も残っていないか確認する。サードパーティのWebhook、許可リスト、監視ツールにハードコードされたアドレス、そして
mailやcpanelのような書き忘れたDNSレコードがないかをチェックする。 - そのマシン上に存在したことのあるシークレットをすべてローテーションする——データベースのパスワード、APIキー、アプリケーションのソルト、DKIM鍵、SSH鍵。これらを新環境へそのまま引き継いではいけない。
- 旧サーバーからSSH公開鍵と、サポート用のアクセス権をすべて取り除く。
- アプリケーション、ダンプ、バックアップを削除し、空き領域を上書きする。再利用されたボリュームを軽く読み取っても何も出てこないようにするためだ。
- そこまで終えてはじめてサービスを解約し、旧アカウントに保存された支払い方法も削除する。
もう自分の管理下にないハードウェアに存在していたものは、定義上すべて漏洩済みと考える。旧ホストが悪意を持っているからではなく、そのディスクはやがてプールに戻され、消去処理の後に何が生き残ったのかを知る術は二度とないからだ。データベースのパスワードをローテーションするのは2分の作業だ。デコミッション済みのサーバー由来の鍵が何かを今も開けると数か月後に気づくのは、それよりずっと長い時間がかかる。
この手順をまとめて1ページに
理由づけを取り除いてしまえば、ホスト移行は9つのステップになり、そのうち緊急性があるのはたった2つだけだ。
- 2日前:DNSのTTLを300秒まで下げる。
- 2日前:移行先サーバーを注文し、旧スタックとバージョンを揃えて堅牢化する。
- 数日前:洗い出しリストを書く——cron、シークレット、TLS、メール関連の鍵、メディア、IP許可リスト、パッケージ。
- 数日前:ホスト間で1回目の完全データコピーを実行する。
- 作業時間帯の前:DNS-01で証明書を発行し、
--resolve経由ですべてをテストする。 - 作業時間帯(数分):書き込みをフリーズし、旧cronを無効化し、差分コピーと最終ダンプを実行し、新しいアプリを起動する。
- 作業時間帯(数秒):Aレコードを変更し、新ホスト側でcronを有効化する。
- 翌週:旧サーバーはロールバック用に生かしたまま両方のログファイルを監視し、その後TTLを再び上げる。
- その後:シークレットをローテーションし、データを消去し、解約する——そして、この移行が消せなかったものを忘れないこと。
このリストの中に、難しいものは一つもない。痛手になるステップは、例外なく順序を間違えたステップだ——当日の夜に下げたTTL、DNS変更の後に発行した証明書、もう権威を持たなくなったマシン上に有効なまま残されたcronジョブ。順序さえ正しければ、移行の中で面白いのは移行作業そのものではなく、サーバーをどこに置くかを選ぶことになる。まだそこを決めていないなら、法域選びのガイドから始めるといい。