<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>自宅サーバー on Off-Grid</title><link>https://offgrid.taikiito.com/tags/%E8%87%AA%E5%AE%85%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC/</link><description>Recent content in 自宅サーバー on Off-Grid</description><generator>Hugo</generator><language>ja-JP</language><lastBuildDate>Mon, 05 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://offgrid.taikiito.com/tags/%E8%87%AA%E5%AE%85%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC/index.xml" rel="self" type="application/rss+xml"/><item><title>自分の「サーバー」を持つとはどういうことか</title><link>https://offgrid.taikiito.com/guides/self-hosting-basics/</link><pubDate>Sun, 13 Sep 2026 00:00:00 +0000</pubDate><guid>https://offgrid.taikiito.com/guides/self-hosting-basics/</guid><description>他のガイドは実は『自分のサーバーが既にある』前提で書かれている。ターミナルもDockerも触ったことがない人向けに、サーバーとは何か、レンタルと自前どちらを選ぶべきか、実際に自分が何をしたかを説明する、このサイトの本当の出発点。</description><content:encoded><![CDATA[<p>正直に告白すると、<a href="/guides/google-photos-to-immich/">写真の移行</a>や<a href="/guides/google-drive-to-nextcloud/">ファイルの移行</a>など、他のガイドはすべて「ImmichやNextcloudが動くサーバーが、自分の手元に既にある」という前提で書かれている。ターミナル(文字を打ち込んで操作する黒い画面)を開いたこともない人がいきなりあの記事を読んでも、何をどこから始めればいいのか分からないはずだ。指摘を受けて、そこが一番の土台なのに書いていなかったことに気づいた。この記事は、その土台の話をする。</p>
<h2 id="そもそもサーバーとは何か">そもそも「サーバー」とは何か</h2>
<p>普段使っているパソコンやスマホは、使う時だけ電源を入れて、使い終わったら閉じたり寝かせたりする。<strong>サーバーとは、それと逆で、24時間365日ずっと電源が入っていて、インターネットの向こう側からいつでもアクセスできる状態のコンピュータ</strong>のことだ。</p>
<p>Google Photosも、Gmailも、実態は「Googleが管理する巨大なサーバー群」に自分のデータを預けて、そこに常時アクセスしている状態にすぎない。「データ主権を取り戻す」とは、この「常時アクセスできる置き場所」を、Google任せではなく自分の管理下に置き換える、ということだ。そのためには、自分の管理下にある「常時起動しているコンピュータ」、つまり自分のサーバーが要る。</p>
<h2 id="サーバーを持つ2つの道">サーバーを持つ2つの道</h2>
<p>サーバーを持つには、大きく2つの選び方がある。</p>
<p><strong>① レンタルサーバー(VPS)を借りる</strong> — 月額数百円〜数千円で、どこかのデータセンターにあるコンピュータの一部を間借りする方式。AWS Lightsail、さくらのVPS、カゴヤ CLOUD VPSなどが有名どころ。自分で機械を持たなくていい代わりに、月額費用がずっとかかり続ける。</p>
<p><strong>② 自分の手元にあるPCを使う(自宅サーバー)</strong> — 使っていない古いPCや、ゲーミングPCのような性能の高いPCを、24時間つけっぱなしにして使う方式。初期投資(電気代はかかる)以外の追加費用がかからない代わりに、電源やネット回線が落ちたらサービスも止まる、という自己責任になる。</p>
<p>自分は最初、AWS LightsailというVPSを使っていたが、途中で②の自宅サーバー(使っていたゲーミングPC)に切り替えた。理由は、写真管理ソフト(Immich)の顔認識機能がGPU(画像処理用の高性能な部品)を使うと速く動くのに、一般的なVPSにはGPUオプションが無いか、あっても高額だったため。自宅のゲーミングPCには既にGPUが載っていたので、それをそのまま活用できるほうが合理的だった。加えて、VPSの月額費用も浮いた。</p>
<p><strong>とはいえ、どちらが正解ということはない。</strong> GPUを使う予定が無く、自宅に眠っているPCも無いなら、まずは安価なVPSを1つ借りるところから始めるほうが手軽だと思う。自分の場合はたまたま条件が噛み合って②を選んだ、という話として読んでほしい。</p>
<h2 id="自分がどうやってこの作業を進めているか">自分がどうやってこの作業を進めているか</h2>
<p>このサイトのガイドは、自分がターミナルに一つ一つコマンドを手打ちして進めたわけではない。実際には<strong>Claude(AIアシスタント)に「こうしたい」と会話しながら指示を出し、実際のコマンド実行やファイル編集はClaude側にやってもらう</strong>、という進め方をしている。使っているのはMulmoClaude(自分がGitHub上で公開している、Claudeを使ったAIアシスタントの土台)というソフトで、これ自体の成り立ちは<a href="/posts/">開発日誌</a>に書いている。</p>
<p>このMulmoClaude自体も、ここまでの話と同じ「自分のサーバー」の上で動いている。<strong>最初はAWS Lightsail(レンタルサーバー)の上で動かしていたが、Immichの顔認識をGPUで速く処理したいという理由で自宅のゲーミングPC(GALLERIA)に切り替えた時、Nextcloud・VaultwardenといったほかのサービスもろともMulmoClaude自体も一緒にGALLERIA側へ引っ越した。</strong> つまり今は、この文章を書いているAI自身も含めて、全部が同じ自宅の1台のPCの上で動いている状態になっている。</p>
<p>なので、このサイトの文章の「自分がやった」は、実際には「Claudeに頼んで、Claudeが実行した」を指していることがほとんどだと理解しておいてもらえればと思う。とはいえ、何をどうするかの判断・決断は全部自分がしているので、「作業の手を動かす部分をAIに任せている」くらいの温度感で読んでほしい。</p>
<h2 id="出てくる専門用語を一通り">出てくる専門用語を一通り</h2>
<p>ここから先のガイドで繰り返し出てくる言葉を、先にまとめて説明しておく。</p>
<ul>
<li><strong>ターミナル</strong> — マウスでクリックする代わりに、文字でコマンド(命令文)を打ち込んでコンピュータを操作するための画面。最初は怖く見えるが、実態は「決まった呪文を決まった場所にコピー&amp;ペーストするだけ」の作業がほとんどで、慣れの問題が大きい。</li>
<li><strong>Docker(ドッカー)</strong> / <strong>docker-compose(ドッカーコンポーズ)</strong> — サーバー上でソフトを動かすための仕組み。1つ1つのソフトを「コンテナ」という隔離された箱に入れて動かすので、複数のソフトを同じサーバーに入れてもお互いが干渉しにくい。<code>docker-compose</code>は、その箱をいくつか組み合わせて一括で起動・停止するための設定ファイルの書き方。</li>
<li><strong>ドメイン</strong> — <code>taikiito.com</code>のような、自分のサーバーにつける覚えやすい名前。年間数百円〜数千円で自分の名義で取得できる(自分はCloudflare Registrarで取得した)。</li>
<li><strong>DNS</strong> — 「<code>taikiito.com</code>というドメインは、実際にはどのサーバーを指すか」をインターネット全体に教えるための、住所録のような仕組み。ドメインを取得したら、DNSの設定でどのサーバーに繋げるかを指定する。</li>
<li><strong>Cloudflare Tunnel(クラウドフレア・トンネル)</strong> — 自宅のサーバーを、自宅のルーターの設定(ポート開放という、外から直接アクセスできる穴を開ける作業)をいじらずに、安全にインターネットへ公開するための仕組み。自分もこれを使っていて、ルーター側の設定は一切変更していない。ポート開放は誤って設定すると自宅のネットワーク全体が外部から丸見えになるリスクがあるため、この方式のほうが安心して扱える。</li>
</ul>
<p>これらのソフト自体は、すべて無料(OSS、オープンソースソフトウェア = 誰でも無料で使える公開されたソフト)で使える。かかる費用は基本的に「サーバー代(自宅の場合は電気代のみ)」と「ドメイン代(年数百円〜)」だけだ。</p>
<h2 id="実際に手を動かす-最小構成でサーバーを1台立てる">実際に手を動かす: 最小構成でサーバーを1台立てる</h2>
<p>ここから先は、自分が最初にやった手順そのままに、VPS(レンタルサーバー)でサーバーを1台立てるところまでを書く。<strong>自宅サーバー(Windows + WSL2)は環境依存が強すぎて万人向けに書き起こせないと判断し、まずは誰でも同じように再現できるVPSの手順に絞った。</strong> 自宅サーバーへの切り替えは、この記事の後半「自宅サーバーに切り替える場合」で触れる。</p>
<h3 id="step-1-ドメインを取得する">Step 1: ドメインを取得する</h3>
<p>まず自分のサーバーの「名前」になるドメインを取得する。自分は<a href="https://www.cloudflare.com/products/registrar/">Cloudflare</a>のRegistrar(ドメイン登録サービス)を使った。理由は、相場より安い実費に近い価格で提供されていて、WHOIS(ドメイン所有者情報)を公開しないプライバシー保護もデフォルトで付いてくるため。ダッシュボードの「Register a Domain」から、空いているドメイン名を選んで購入するだけで完了する。年間数百円〜数千円ほど。</p>
<h3 id="step-2-vpsレンタルサーバーを契約する">Step 2: VPS(レンタルサーバー)を契約する</h3>
<p>自分が最初に使ったのは<strong>AWS Lightsail</strong>、リージョンはシンガポール、OSはUbuntu(Linuxの一種)、**プランは月$7(メモリ1GB・2vCPU・SSD 40GB)**を選んだ。動画生成のような重い処理をする予定がなければ、この最小プランで十分動く。契約すると、そのサーバーの持ち主だけが入れる「IPアドレス」(サーバーの住所のようなもの)が発行される。</p>
<p>VPSは他にもさくらのVPS・カゴヤ CLOUD VPS・DigitalOcean・Vultrなど選択肢は多い。自分がAWSを選んだ決め手は、シンガポール在住で近いリージョンが使えたのと、後々AWSの他サービス(バックアップ等)との連携がしやすそうだったため——ただしこの用途では正直どれを選んでも大差ない。</p>
<h3 id="step-3-ターミナルからサーバーに接続しdockerを入れる">Step 3: ターミナルからサーバーに接続し、Dockerを入れる</h3>
<p>契約すると、サーバーに接続するための「SSH鍵」(パスワードの代わりに使う、より安全な鍵ファイル)が発行される。ターミナル(黒い画面でコマンドを打ち込む操作)から、次のように接続する。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">ssh -i 発行された鍵ファイル ubuntu@サーバーのIPアドレス
</span></span></code></pre></div><p>接続できたら、Docker公式が配布しているインストールスクリプトを実行する。これ1行で、Dockerと<code>docker compose</code>がまとめて入る。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -fsSL https://get.docker.com <span class="p">|</span> sh
</span></span><span class="line"><span class="cl">sudo usermod -aG docker <span class="nv">$USER</span>
</span></span></code></pre></div><p>(2行目は、<code>sudo</code>〈管理者権限で実行〉を毎回付けなくてもDockerコマンドが使えるようにするおまじない。一度ログアウトしてから入り直すと反映される。)</p>
<h3 id="step-4-cloudflare-tunnelでサーバーを安全に公開する">Step 4: Cloudflare Tunnelでサーバーを安全に公開する</h3>
<p>サーバーは立ったが、まだ<code>taikiito.com</code>のようなドメインからはアクセスできない。ここで前述の<strong>Cloudflare Tunnel</strong>を使う。取得したドメインをCloudflareのネームサーバーに切り替えた上で(Cloudflareのダッシュボードの指示通りに進めれば数クリックで終わる)、サーバー側で次を実行する。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># cloudflaredをインストール</span>
</span></span><span class="line"><span class="cl">curl -L --output cloudflared.deb https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
</span></span><span class="line"><span class="cl">sudo dpkg -i cloudflared.deb
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Cloudflareアカウントと連携(ブラウザが開くのでログインする)</span>
</span></span><span class="line"><span class="cl">cloudflared tunnel login
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># トンネルを作成(名前は自分で決める。ここでは仮に my-server)</span>
</span></span><span class="line"><span class="cl">cloudflared tunnel create my-server
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ドメインとトンネルを紐付ける</span>
</span></span><span class="line"><span class="cl">cloudflared tunnel route dns my-server example.taikiito.com
</span></span></code></pre></div><p>最後に、どのURLへのアクセスをサーバー内のどのポートに転送するかを設定ファイル(<code>~/.cloudflared/config.yml</code>)に書く。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">tunnel</span><span class="p">:</span><span class="w"> </span><span class="l">my-server</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">credentials-file</span><span class="p">:</span><span class="w"> </span><span class="l">/home/ubuntu/.cloudflared/&lt;トンネルID&gt;.json</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="nt">ingress</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">hostname</span><span class="p">:</span><span class="w"> </span><span class="l">example.taikiito.com</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">    </span><span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">http://localhost:8080</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="nt">service</span><span class="p">:</span><span class="w"> </span><span class="l">http_status:404</span><span class="w">
</span></span></span></code></pre></div><p>再起動しても自動で動き続けるよう、サービス化しておく。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo cloudflared service install
</span></span></code></pre></div><p>ここまでできれば、あとはサーバー内の<code>localhost:8080</code>(上の設定例のポート番号)で何かソフトを動かせば、<code>https://example.taikiito.com</code>からアクセスできるようになる。ルーターのポート開放(外から直接アクセスできる穴を開ける、事故ると危険な設定)を一切いじらずに済むのがこの方式の利点。</p>
<h3 id="step-5-動作確認">Step 5: 動作確認</h3>
<p>具体的に何かソフトを動かして確認したい場合は、このサイトの次のガイド(<a href="/guides/google-photos-to-immich/">写真をGoogle PhotosからImmichに移す</a>)がそのままStep 6以降の実例になる——<code>docker-compose.yml</code>を書いてImmichを起動し、上のingress設定のポート番号をImmichのポートに合わせれば、そのまま公開まで到達できる。</p>
<h2 id="自宅サーバーに切り替える場合">自宅サーバーに切り替える場合</h2>
<p>自分は後になって、AWS Lightsail(VPS)から自宅のゲーミングPC(自宅サーバー)に切り替えた。理由は前述の通りGPU(画像処理用の高性能な部品)を使いたかったのと、月額費用を浮かせたかったため。ただしこの切り替えは、Windows PCの中でLinuxを動かす「WSL2」という仕組みや、再起動時の自動起動設定など、環境固有のハマりどころが多く、万人向けの手順としてはまだ書き起こせていない。GPUを使う予定がなければ、上記のVPS構成のままで十分運用できる。自宅サーバーへの興味がある場合は、今後別記事として書く予定。</p>
<h2 id="正直な難易度感">正直な難易度感</h2>
<p>ここまで読んで「思ったより大変そう」と感じたなら、その感覚は正しい。自分の場合も、自宅サーバーへの切り替えではWindowsとLinux(WSL2)の両方の知識が必要になったり、再起動のたびにサービスが自動で立ち上がらない不具合に何度も遭遇したりと、一筋縄ではいかない場面が何度もあった。上記のVPS手順自体はそこまで難しくないが、初めてターミナルを触る場合は1〜2時間はかかると思っておいてほしい。</p>
<p>ただし、これは「一度整えてしまえば、あとはほぼ触らなくていい」類の作業でもある。土台さえできてしまえば、その後の<a href="/guides/google-photos-to-immich/">写真の移行</a>や<a href="/guides/1password-to-vaultwarden/">パスワードの移行</a>といった個別の作業は、ここまでの土台よりずっと軽い。</p>
<h2 id="この先">この先</h2>
<p>サーバーが立ち、ドメインからアクセスできる状態まで来たら、あとは個別のサービスを動かすだけ。まずは実際に何を移したかの記録から読んでもらえればと思う。→ <a href="/guides/google-photos-to-immich/">写真をGoogle PhotosからImmichに移す</a></p>
<p><strong>更新履歴</strong> — 2026-09-13: 初版 / 同日: 「自分がどうやってこの作業を進めているか」(MulmoClaude/Claudeの利用、Lightsail→GALLERIA移設)を追記 / 同日: VPS(AWS Lightsail)でのドメイン取得〜Docker〜Cloudflare Tunnelまでの具体的手順を追記</p>
]]></content:encoded></item><item><title>自宅サーバーが5.5日止まったので海外VPSへ移った</title><link>https://offgrid.taikiito.com/guides/home-server-to-vps/</link><pubDate>Mon, 05 Oct 2026 00:00:00 +0000</pubDate><guid>https://offgrid.taikiito.com/guides/home-server-to-vps/</guid><description>自宅のWindowsノートPCが原因不明のまま5.5日間フリーズし、写真・パスワード・ファイルのサーバーが全部止まった。壊れた機械から転送するのではなく、毎晩取っていたクラウドバックアップからVPS側へ引っ張って復元する方式で、26分の停止で移行した記録。公開IPになって初めて露出した穴とその塞ぎ方も書いた。</description><content:encoded><![CDATA[<p>写真・パスワード・ファイルの置き場を全部自宅のPC1台に集めていた。そのPCが<strong>5.5日間フリーズしたまま</strong>動かなくなり、全部止まった。家を離れていた期間だったので、帰るまで何もできなかった。原因は結局特定できていない。</p>
<p>その障害の記録と、そこから海外VPS(レンタルサーバー)へ移った記録。<strong>壊れた機械からデータを転送するのではなく、毎晩取っていたクラウドバックアップからVPS側へ引っ張って復元した</strong>のが一番再利用できる部分だと思う。実際の停止時間は26分だった。そして移行後、<strong>自宅のルーターの内側にいたから気づかずに済んでいた穴</strong>が一気に表に出た。</p>
<h2 id="前提">前提</h2>
<ul>
<li>自宅のWindows機〈ノート型〉(WSL〈Windowsの中でLinuxを動かす仕組み〉上でサーバーを動かしていた)で、Immich(写真)・Nextcloud(ファイル)・Vaultwarden(パスワード)・Authentik(ログインの入口)など<strong>常時14コンテナ</strong>を動かしている状態</li>
<li>外部公開はCloudflare Tunnel(ルーターに穴を開けずにサーバーを公開する仕組み)経由で、ルーターのポート開放は一切していない</li>
<li>毎晩<code>rclone</code>(いろいろなクラウドストレージへファイルを同期するコマンド)でBackblaze B2(安価なオブジェクトストレージ)へ日次バックアップを取っている</li>
<li>構築の土台は<a href="/guides/self-hosting-basics/">自分の「サーバー」を持つとはどういうことか</a>、バックアップの設計は<a href="/guides/backup-ransomware-resistant/">バックアップを「消されても戻せる」形にする</a></li>
</ul>
<h2 id="何が死んだのか">何が死んだのか</h2>
<p>最初の症状は、自分のドメインを開くと<strong>Cloudflare Error 1033</strong>(トンネルの出口であるサーバー側にCloudflareが接続できない時のエラー)が出たこと。Cloudflareの障害情報ページには何も出ていない。別経路のリモートデスクトップで見ると「最後のオンライン 12:07」でオフライン表示。<strong>トンネルが切れたのではなく、サーバーの入っているPC自体が落ちている。</strong></p>
<p>遠隔からできることは何もなかった。SSHも入れない。Cloudflare Tunnelは「サーバーが生きていれば外から入れる」仕組みなので、サーバーが死ぬと一緒に死ぬ。</p>
<p>帰ってから見たPCの状態がこれ。<strong>電源は入っていて画面も出ているのに、マウスカーソルが一切動かない。</strong> キーボードも効かない。ブルースクリーンも出ていない。電源ボタンの長押しで強制終了して再起動したら、何事もなかったように復旧した。</p>
<p>後日イベントログを調べて停止時間が確定した。</p>
<pre tabindex="0"><code>EventLog ID 6008
&#34;The previous system shutdown at 11:11:13 AM on 9/21/2026 was unexpected.&#34;
</code></pre><p>このログが記録されたのは<strong>9/26 23:45</strong>(自分が強制再起動した時刻)。つまり<strong>9/21 11:11:13にハングして、そこから5日半固まったまま</strong>だった。</p>
<ul>
<li>9/21〜9/26の間、Systemログに<strong>イベントが1件も記録されていない</strong>。完全な空白。瞬断の繰り返しではなく、OSが本当に何も処理できない「サイレントハング」だった裏付けになる。</li>
<li><strong>ブルースクリーンのダンプファイルが無い</strong>(残っていたのは1年半前の古いものだけ)。<strong>ディスプレイドライバのクラッシュログも0件</strong>。写真の顔認識にGPU(画像処理用の高性能な部品)を使っていたのでGPUドライバのハングが一番疑わしい候補だったが、<strong>ログが書かれる前に固まった可能性もあり確定できなかった。</strong></li>
</ul>
<p><strong>根本原因は今も分かっていない。</strong> BSODもエラーログも残さず固まる種類の故障は、原因究明が原理的に難しい。</p>
<p>🔴 <strong>ここで一度、原因を誤診した。</strong> 強制再起動後に別のソフトの認証セッションが切れていたので、最初はそれが5.5日の原因だと分析した。実際は「PCが固まっていた」が唯一の原因で、セッション切れは再起動後に浮上した<strong>二次的な問題</strong>だった。<strong>復旧直後に見つかった不具合は、障害の原因ではなく結果であることがある。</strong> 時系列のログで裏を取るまで原因を名指ししない。</p>
<h2 id="なぜvpsに移ることにしたか">なぜVPSに移ることにしたか</h2>
<p>最初に考えたのは、もっと安い対策ばかりだった。ウォッチドッグタイマー(固まったら自動でリセットする機能)、GPUドライバの更新、旅行時はSSHできる端末を必ず携帯する運用ルール。</p>
<p>🔴 <strong>「スマートプラグで遠隔から電源を入れ直す」案は、そもそも使えなかった。</strong> サーバーにしていたのはノート型のWindows機で、<strong>内蔵バッテリーがあるのでコンセントを切っても電源は落ちない</strong>。ノートPCを常時稼働のサーバーに流用するのは「静かで省電力」という利点があって自分もそれで選んだのだが、<strong>固まったときに遠隔で殴る手段を一つ失う</strong>という代償がついてくる。これは置き場所を決める段階で知っておきたかった。「WindowsをやめてこのPCを素のLinux専用機にする」案も検討したが<strong>否定的</strong>な結論になった。マウスも効かないOS全体の停止なのでLinux側だけの不調ではなく、<strong>原因がGPUドライバなら素のLinuxでも再発しうるので、OS再インストール＋全サービス移行という大工事に見合う保証がない</strong>。</p>
<p>それでも移行を決めた理由は、<strong>数日後に同じサイレントフリーズが再発した</strong>こと。原因が分からない以上「次はいつ、どれだけ止まるか」が見積もれない。<strong>データセンターの機械なら、少なくとも電源とネットワークと物理的な復旧は他人の仕事になる。</strong></p>
<h2 id="vpsの比較で実際に効いた軸">VPSの比較で実際に効いた軸</h2>
<p><strong>2026年9月時点</strong>の調査値。今は変わっているはず。</p>
<table>
	<thead>
			<tr>
					<th>候補</th>
					<th>スペックと価格の感覚</th>
			</tr>
	</thead>
	<tbody>
			<tr>
					<td>Contabo</td>
					<td>6vCPU / 12GB RAM / 200GB SSD が月$9前後。容量あたりで圧倒的に安い</td>
			</tr>
			<tr>
					<td>Vultr</td>
					<td>2vCPU / 8GB で月$24〜48</td>
			</tr>
			<tr>
					<td>DigitalOcean</td>
					<td>2vCPU / 4GB で月$24</td>
			</tr>
			<tr>
					<td>Hetzner</td>
					<td>単価は安いが月間転送量の上限が低く、写真用途では超過料金のリスク</td>
			</tr>
			<tr>
					<td>Oracle Cloud Free Tier</td>
					<td>2 OCPU / 12GB ARM が無料枠</td>
			</tr>
			<tr>
					<td>国内VPS</td>
					<td>2コア / 2GB / SSD 200GB が月770円〜。ただし週1回程度の数秒〜数分の瞬断報告あり</td>
			</tr>
			<tr>
					<td>AWS Lightsail</td>
					<td>以前使っていたが、この用途では割高だったので自宅運用に移った経緯がある</td>
			</tr>
	</tbody>
</table>
<p>効いた軸は4つ。</p>
<p><strong>① ディスク容量が最優先。</strong> 写真のライブラリが実測115GB、ファイル同期が16.6GB。OS・Docker・データベースを含めて170〜180GBと見積もり、200GBのプランにした。「写真が増えるたびに月額が雪だるま式に増えるのが嫌だ」という条件があったので、<strong>同じ値段でどれだけディスクが付いてくるか</strong>が一番差の出る軸になった。</p>
<p><strong>② メモリは写真の量ではなくコンテナの数で決まる。</strong> ここは一度自分で間違えかけた。「古い写真をクラウドへ逃がすならメモリも小さくていいのでは」と考えたが違う。常時14コンテナが動いていて、以前メモリ不足で全サービスが繰り返し落ちた実績がある。しかも<strong>VPSにはGPUが無いので、顔認識や画像検索の処理をCPUとメモリでやることになり、必要メモリはむしろ増える</strong>。8GBではなく12GBから始め、安定を確認してから下のプランへ落とす順序にした。</p>
<p><strong>③ リージョン(どの国のデータセンターか)は在庫で決まった。</strong> 第一候補にしていたリージョンは<strong>月+$4.90の追加料金</strong>がつく上に、申し込み画面で<strong>在庫切れ</strong>だった。追加料金ゼロで常に在庫があるリージョンに変えたら、結果として<strong>バックアップ先のB2との経路が短くなり、復元も移行後の日次バックアップも速くなる</strong>という副産物があった。「近いほうが良いに決まっている」と思い込んでいた軸が、実際には料金・在庫・バックアップ先との距離で裏返った。</p>
<p><strong>④ 遅延は実測すると論点が変わる。</strong> 申し込み画面の「近いリージョン4ms、遠いリージョン158ms」は<strong>生のネットワーク遅延で、Cloudflare Tunnel経由の実構成には当てはまらない</strong>。自宅のPCで動かしていた時点ですでに写真サーバーの初期応答は73〜87msだった。DNSがCloudflareを指しているので、自宅のWiFiからでも一度エッジへ出て戻る経路になり、「目の前にあるから速い」状態には元々なっていなかった。移行後は<strong>0.55〜0.7秒</strong>(自宅PC時代は0.3秒前後)。比較のためにGoogle Photosのアプリ画面を測ると248〜255msで、<strong>「すでに受け入れている遅さ」と同程度</strong>だと分かったので許容できる論点に落ちた。</p>
<ul>
<li>🔴 サムネイルをCloudflare側にキャッシュさせれば速くなるが、<strong>それは自分の写真をCloudflareに置かせることになるのでやらない</strong>。速度のために主権を手放すなら移行の意味がない。</li>
</ul>
<p>契約は6vCPU / 12GB RAM / 200GB SSD / 転送量無制限、Ubuntu 24.04、<strong>1ヶ月契約で月$9.00、初期費用ゼロ</strong>。年契約の割引は見送った。原因不明の障害から逃げるための移行で、移行先が気に入らなかった時にすぐ降りられないのは本末転倒だから。</p>
<h2 id="移行方式-壊れた機械から運ぶのをやめる">移行方式: 壊れた機械から運ぶのをやめる</h2>
<p>ここが今回の中心。</p>
<p>普通に考えると、移行とは<strong>旧サーバー → 新サーバー</strong>へデータを直接転送することだ。ランブックの最初の案もそうなっていた。150GBを<code>rsync</code>(差分だけコピーするコマンド)で送る、数時間〜半日かかる、という計画。</p>
<p>これを見て思ったのが、**「毎晩クラウドにバックアップを取っているのだから、新サーバーがそこからダウンロードすればいいのでは?」**だった。採用した。</p>
<pre tabindex="0"><code>これまでの案:  自宅PC ──(細い家庭回線)──&gt; 新VPS
採用した案:    自宅PC ──&gt; B2(クラウド) ──(データセンター間)──&gt; 新VPS
</code></pre><ol>
<li><strong>自宅の細い上り回線に依存しない</strong>。VPS↔B2はデータセンター間なので桁違いに速く、実測で約30MB/sだった。</li>
<li><strong>旧サーバーが移行作業中ずっと安定している必要がない</strong>。これが決定的だった。5.5日固まる機械を、半日の転送が終わるまで無事でいてくれと祈りながら使うのは設計として間違っている。</li>
<li><strong>既にそこにあるので準備作業がゼロ</strong>。写真の本体もデータベースのダンプ(中身を1つのファイルに書き出したもの)も毎晩同期済み。</li>
<li><strong>ついでに災害復旧の予行演習になる</strong>。「クラウドのコピーしか残っていない状態から戻せるか」を本番で一度やることになるので、バックアップが本当に使えるのかが確定する。</li>
</ol>
<h3 id="鶏と卵の問題は先に解いてあった">鶏と卵の問題は先に解いてあった</h3>
<p>前提がある。<strong>B2から引っ張るにはB2へのアクセス鍵が必要</strong>で、その鍵が旧サーバーの中にしか無ければ、サーバーを失った時点で何も取り出せない。</p>
<p>ここは1ヶ月前に手を打ってあった。<strong>B2アクセス用の<code>rclone</code>設定、Cloudflare Tunnelの設定、<code>docker-compose.yml</code>一式、環境変数ファイルの内容を、Vaultwarden(自分のパスワード管理サーバー)にSecure Note 4件として複製保存していた。</strong> Vaultwardenのモバイルアプリはオフラインキャッシュを持つので、サーバーに一切アクセスできなくてもスマートフォンから取り出せる。後日<strong>このメモに書かれた値だけで</strong>B2上の全データが見えることを実測で確認した。🔴 <strong>この検証は鍵を入れ替えるたびに毎回やる。</strong> 「保存したつもり」で中身が古い、という事故が一番ありそうな場所だから。</p>
<h2 id="ランブックの形">ランブックの形</h2>
<p>手順はPhase A〜Hに分けて1つの文書にした。<strong>実行中にその場で考える余地を削るのが目的</strong>で、特にDNSの切り替えは後戻りの判断が数秒で要る。</p>
<pre tabindex="0"><code>Phase A  旧サーバーを止めて最終バックアップ
Phase B  Vaultwardenから鍵4件を取り出す
Phase C  新VPSの初期設定(ユーザー・SSH鍵・Docker)
Phase D  B2から rclone copy でデータを引っ張る
Phase E  データベースのダンプをリストア
Phase F  docker-compose を復元してコンテナ起動
Phase G  新しいトンネルを作ってDNSを1本ずつ切替
Phase H  移行後(バックアップの再構築・監視・検証)
</code></pre><p>書き上げた最初の版には穴が4つあり、実行前のレビューで直した。</p>
<ul>
<li><strong>稼働中のままコピーしたパスワードデータは壊れている可能性がある。</strong> Vaultwardenのデータベースファイルは書き込み中にコピーすると不整合になりうる。当日は<strong>コンテナを止めてから</strong>バックアップを手動実行する手順に変えた。これで「日次バックアップから最大24時間分が欠ける」問題も同時に消える。</li>
<li>🔴 <strong>イメージのバージョンを固定せずに復元すると壊れる。</strong> データベースのダンプは、取得した時点のソフトのバージョンの構造に紐づいている。<code>docker compose pull</code>で最新版を取ると構造が合わなくなる。</li>
<li><strong>環境変数ファイルの復元元を間違って書いていた。</strong> 以前使っていたパスワード管理サービスは解約済みで、正しくはVaultwardenだった。<strong>手順書は、書いた時点では正しくても構成変更で腐る。</strong></li>
<li>🔴 <strong>同じトンネルを2台のホストで同時に動かしてはいけない。</strong> リクエストが2台にランダムに振り分けられて、「たまに繋がらない」という一番デバッグしづらい障害になる。<strong>新しいトンネルを別に作って、DNSを1本ずつ向け替える</strong>形にした。</li>
</ul>
<p>他に決めておいたこと。</p>
<ul>
<li><strong><code>rclone copy</code>を使い、<code>sync</code>は使わない</strong>。<code>sync</code>は転送元に無いファイルを転送先から消す。過去にこれで必要なディレクトリを消して障害にした実績がある。</li>
<li><strong>切替順序</strong>: 一番軽いパスワードサーバー → <strong>ログインの入口(最重要。落ちると他のサービスにログインできなくなる)</strong> → ファイル → 写真 → 残り。<strong>旧サーバーへのSSH経路は一番最後。</strong> 先に向け替えると旧サーバーに入れなくなって確認作業ができない。</li>
<li><strong>DNSのTTL(切替が反映されるまでの待ち時間)を事前に短くする手順は不要だった。</strong> 対象レコードは全部Cloudflareのプロキシを通る設定で、外に返るアドレスは切替前後で変わらない。振り分けはCloudflare内部で起きるので<strong>書き換えの数秒後に反映され、戻すのも数秒</strong>。TTLを下げる必要があるのは、プロキシを通さずサーバーのアドレスを直接返している場合だけ。</li>
</ul>
<h2 id="実際の停止時間は26分">実際の停止時間は26分</h2>
<p><strong>15:19にサービスを止めて、15:45に全部復帰した。</strong> 写真150GBを運ぶ移行としては想定よりはるかに短い。クラウド経由にしたことで、一番重い写真の転送が「停止中にやる作業」から外れたのが効いている。</p>
<p>復元後の検証値は、写真<strong>59,104ファイル</strong>(<code>rclone check</code>でB2との差分ゼロ)、写真サーバーの登録件数<strong>29,720件</strong>、ファイル同期サーバー144テーブル・<strong>16.6GB</strong>、ログイン入口のユーザー3件。</p>
<h3 id="ランブックに書いていなかった落とし穴">ランブックに書いていなかった落とし穴</h3>
<ul>
<li>🔴 <strong>浮動タグが他にもあった。</strong> バージョン固定は写真サーバーだけ警告していたが、ファイル同期・データベース・パスワード管理も<code>:latest</code>(常に最新を取るタグ)のままだった。<strong>旧サーバーで実際に動いているイメージのダイジェスト(内容に対する一意の識別子)を全部調べて固定した</strong>。<code>docker inspect</code>の<code>.Image</code>はそのマシンの中だけのIDでダウンロードには使えないので<code>RepoDigests</code>を使う。</li>
<li>🔴 <strong>写真サーバーが起動ループした。</strong> <code>Failed to read /data/encoded-video/.immich</code>。サムネイルと変換済み動画のフォルダをバックアップ対象から外していたため、<strong>そのフォルダにある整合性チェック用の目印ファイルまで一緒に欠けていた</strong>。空のフォルダではなく「目印だけがある」状態が必要だった。</li>
<li><strong>ファイル同期サーバーが<code>Cannot write into &quot;config&quot; directory!</code>で503。</strong> <code>rclone</code>はファイルの所有者情報を保持しないので、復元したファイルが全部自分のユーザーの所有になっていた。<strong>クラウド経由の復元では所有者が落ちることを前提に、復元後のチェック項目に入れておく。</strong></li>
<li>🔴 <strong>ユーザーのIDが揃っていなかった。</strong> 新VPSに旧サーバーと<strong>同じ名前</strong>のユーザーを作ってパスを揃えたので、設定ファイルを無改造で使い回せた。これは正解だった。ただし名前は同じでも<strong>内部の数値のID</strong>が1つずれていて、一部のコンテナ内で<code>No user exists for uid 1001</code>で落ちた。<strong>名前だけでなく数値IDまで揃える必要がある。</strong></li>
<li><strong>「Dockerのデータとワークスペースを移せば終わり」ではなかった。</strong> 動画変換用のコマンドや日本語フォントといった<strong>ホスト側のOSパッケージ</strong>が新VPSに無く、移行の夜に機能が動かないことで発覚した。さらに<code>cron</code>(定時実行の仕組み)自体が未インストールで、登録コマンドが<strong>黙って失敗</strong>していた。バックアップの自動実行が最初から動いていないところだった。</li>
<li>🔴 <strong>写真46件が旧サーバーにしか存在しなかった。</strong> 復元結果をファイル単位で突き合わせて翌日見つけた。<strong>データベースには46件の記録があるのに、写真の実体がVPSにもB2にも無い</strong>。原因は、移行当日の最終バックアップで<strong>データベースのダンプは成功し、写真の同期ステップが完走しないまま終わっていた</strong>こと。しかも旧スクリプトはステップごとの成否をログに出していなかったので<strong>無言で失敗した</strong>。旧サーバーがまだ生きていたので手元から押し出して復旧できたが、運が良かっただけ。
<ul>
<li><strong>教訓1: 復元の検証を「ファイル数の一致」でやってはいけない。</strong> 60,525件と60,619件で0.15%差。見逃す水準だった。<strong>データベースに記録されているパスが1件ずつ実在するか</strong>を全件突き合わせる必要がある。</li>
<li><strong>教訓2: バックアップスクリプトはステップごとにOK/FAILをログへ出す。</strong> まさにこの欠陥を直すつもりだった移行当日に、その欠陥に刺された。</li>
</ul>
</li>
</ul>
<h2 id="公開ipになって初めて出た問題">公開IPになって初めて出た問題</h2>
<p>ここが<strong>一番多くの人が外すところ</strong>だと思う。移行そのものより危ない。</p>
<p><strong>自宅のPCはルーターの内側にいた。</strong> だから、どのサービスが「外から直接届く形」で動いていようが、外からは届かなかった。Cloudflare Tunnelという1本の出口だけが外部との接点だった。<strong>VPSは公開IPを持っている。</strong> 全部のポート(通信の入口の番号)が、世界中から直接叩ける状態で始まる。ランブックにこの観点は1行も無かった。</p>
<h3 id="-中身が剥き出しで公開されていた">① 中身が剥き出しで公開されていた</h3>
<p><strong>写真サーバーのログイン画面が生で公開</strong>されていた。Cloudflare側のログイン要求を通らない素の入口。<strong>ログイン入口サーバーのHTTPSポートも公開</strong>で、本来Cloudflare側の防御を通ってから届くはずのものが迂回できる状態。小さな静的サイトのポートも開いていた。</p>
<p>原因は<code>docker-compose.yml</code>の<code>ports:</code>の書き方。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-yaml" data-lang="yaml"><span class="line"><span class="cl"><span class="nt">ports</span><span class="p">:</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s1">&#39;2283:2283&#39;</span><span class="w">            </span><span class="c"># 🔴 これは全てのネットワークに向けて開く</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">  </span>- <span class="s1">&#39;127.0.0.1:2283:2283&#39;</span><span class="w">  </span><span class="c"># ✅ 自分自身からしか届かない</span><span class="w">
</span></span></span></code></pre></div><p><strong>自宅では両方とも同じ結果になる</strong>ので、違いに気づく機会がなかった。トンネル経由で公開する構成なら、外に向けて開く必要は最初から無い。</p>
<p>応急処置としてファイアウォールで遮断し、<strong>後日、設定ファイル側を<code>127.0.0.1</code>に直して「ファイアウォールで塞いでいる」状態をやめた</strong>。この順序は意図的で、ファイアウォールなら数秒で塞げるがコンテナの作り直しは止まる時間が出るから。ただし<strong>応急処置で終わらせない</strong>。ファイアウォールは1行消えれば無防備に戻るが、そもそも誰も外向きに待ち受けていなければ消しようがない。</p>
<h3 id="-sshのパスワードログインが無効にしたのに有効だった">② SSHのパスワードログインが「無効にしたのに有効」だった</h3>
<pre tabindex="0"><code>/etc/ssh/sshd_config.d/50-cloud-init.conf   ← PasswordAuthentication yes
/etc/ssh/sshd_config.d/99-hardening.conf    ← PasswordAuthentication no(自分が書いた)
</code></pre><p><strong>SSHのサーバーは「最初に見つけた値」を採用する。</strong> 番号が小さいファイルが先に読まれるので、99番に書いた自分の設定は永遠に負ける。VPSの初期設定が置いていった50番のファイルを無効化して解決した。🔴 <strong>設定を書いたら、書いたことを確認するのではなく、効いているかを確認する。</strong> 鍵でログインできることと、パスワードが本当に拒否されることの両方を実測する。</p>
<h3 id="-ipv6が完全に丸腰だった">③ IPv6が完全に丸腰だった</h3>
<p>ここが一番ひやりとした。遮断はしたが、<strong>IPv4のファイアウォールだけ</strong>だった。</p>
<p>VPSにはIPv6のアドレスも付いている。確認すると、<strong>IPv6側のファイアウォールのルールは空、ポリシーは全通過</strong>。コンテナはIPv4とIPv6の両方で待ち受けていたので、<strong>塞いだつもりの写真サーバーのログイン画面は、IPv6経由では公開されたまま</strong>だった。🔴 <strong>IPv4を塞いだら必ずIPv6も確認する。</strong> 設定は完全に別物で、片方だけやっても「塞いだ」とは言えない。</p>
<h3 id="-認証なしのポート19本が素通しだった">④ 認証なしのポート19本が素通しだった</h3>
<p>自分のアシスタントが外部サービスと喋るための中継プロセスが、<strong>ポート19本で認証なしで待ち受けていた</strong>。ファイアウォールのルールも無かった。<strong>この中の1本は自分のメールの受信箱に繋がっていた。</strong> 写真のログイン画面(少なくともパスワードは要求する)より危険度は上だった。</p>
<p>思い込みが穴を作った。<strong>「外に出ているポートは<code>docker-compose</code>の<code>ports:</code>に書いてあるものだけ」<strong>と思っていた。これらはコンテナではなく</strong>ホスト上で直接動いているプロセス</strong>なので、Docker向けのファイアウォール設定では止まらない。棚卸しの書き方にも罠がある。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 🔴 これでは漏れる</span>
</span></span><span class="line"><span class="cl">ss -tlnp <span class="p">|</span> grep 0.0.0.0
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># ✅ 「自分自身以外」を除外方式で全部出す</span>
</span></span><span class="line"><span class="cl">ss -tlnp <span class="p">|</span> grep -vE <span class="s2">&#34;127\.0\.0\.|\[::1\]&#34;</span>
</span></span></code></pre></div><p>待ち受けアドレスの表記は<code>0.0.0.0:PORT</code>だけではない。<strong><code>*:PORT</code>という表記(IPv4とIPv6の両方で待ち受け)もあり、<code>0.0.0.0</code>では引っかからない。</strong> 19本はこの形で見落とされていた。**「危ないものを探す」のではなく「安全なものを除外して残り全部を見る」**書き方にしないと漏れる。</p>
<p>後日これも応急処置をやめて根本を直した。使っていた中継ソフトには<strong>待ち受けアドレスを指定するオプションが存在しなかった</strong>ので、ソフト側のコードを1行書き換える形になった。直した後の確認が気持ちよかった。<strong>公開IPへは「接続拒否」が返る</strong> — ファイアウォールで弾いているのではなく、そもそも誰も待ち受けていない状態になった。これが一番強い証明。</p>
<h3 id="-ファイアウォールの確認はそのサーバー自身からでは絶対にできない">⑤ ファイアウォールの確認は、そのサーバー自身からでは絶対にできない</h3>
<p>遮断ルールには「外部から来た通信に対して」という条件が付く。<strong>VPSの中から自分の公開アドレスに繋ごうとすると内部の経路を通るので、必ず「繋がる」と出る。</strong> 塞がっているのに塞がっていないように見える。</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># 別のパソコンから実行する(VPS内からでは意味がない)</span>
</span></span><span class="line"><span class="cl">nc -vz &lt;サーバーのアドレス&gt; <span class="m">2283</span>   <span class="c1"># → Operation timed out  が正しい</span>
</span></span><span class="line"><span class="cl">nc -vz &lt;サーバーのアドレス&gt; <span class="m">22</span>     <span class="c1"># → succeeded!            が正しい</span>
</span></span><span class="line"><span class="cl">nc -vz -6 &lt;IPv6アドレス&gt; <span class="m">2283</span>      <span class="c1"># IPv6も必ず測る</span>
</span></span></code></pre></div><p>この外部からの実測を、<strong>VPSを再起動した後・ファイアウォールを触った後・<code>docker-compose</code>を触った後に回す定型チェック</strong>として手順書に書き出した。</p>
<h3 id="-監視が自分の死を通報できない">⑥ 監視が自分の死を通報できない</h3>
<p>死活監視にUptime Kumaを使っているが、<strong>それが監視対象と同じVPSの上で動いている</strong>。VPSごと落ちたら監視も一緒に落ちて通知が飛ばない。<strong>一番知りたい障害だけ通報されない。</strong> <a href="/guides/backup-ransomware-resistant/">バックアップの記事</a>で書いたデッドマンスイッチ(生存信号が途絶えたら警報を出す仕掛け)と同じ構造なので、B2の複製先を見張らせていたGitHub Actions(GitHubが決めた時刻にスクリプトを自動実行する仕組み)に死活監視を1本足して解決した。<strong>サーバーの外で動くので、サーバーが丸ごと死んでも黙らない。</strong></p>
<h2 id="再起動して自分で戻ってくるかを確かめる">再起動して自分で戻ってくるかを確かめる</h2>
<p><strong>移行が完了した状態は、一度も再起動していない状態</strong>でもある。「今動いている」と「電源が落ちても自分で戻ってくる」は別の話で、自宅サーバー時代は再起動のたびに何かが立ち上がらない問題に何度も遭遇していた。</p>
<p>事前に、systemdのユニット7件がすべて<code>enabled</code>(起動時に自動で立ち上がる設定)か、コンテナ14個の再起動ポリシーが<code>unless-stopped</code>か<code>always</code>かを確認した。<strong>ファイアウォールのルールを永続化する仕組みも必ず含める</strong> — ここが抜けると再起動で遮断ルールが消え、さっき塞いだ穴が全部開く。厄介な事情が1つあって、<strong>自分のアシスタント自身がこのVPSの上で動いているので、再起動すると自分との会話も切れる</strong>。1分の猶予を置いて再起動し、<strong>復旧手順をチャットの外に控えておく</strong>段取りにした。自分を再起動する作業は、自分以外の場所に手順を置いてから実行する。</p>
<p>結果は成功。<strong>22秒で起動</strong>し、systemd 7件・コンテナ14個すべて稼働、全9サービスがHTTP 200/302、データも再起動前と完全一致。そして<strong>外部のパソコンからの<code>nc</code>実測で、遮断したポートは<code>Operation timed out</code>、SSHは<code>succeeded!</code></strong> — 永続化が再起動をまたいで効いていることを外部視点で立証できた。</p>
<p>後日ディスクを増設した時に<strong>こちらの意図しない強制リセットが起きた</strong>(公式ヘルプには「再起動不要」と書かれていたが実態は違った)。その時も全部がデータ欠損ゼロで自動復帰したので、この検証が本物だったことは意図せず二重に確認できた。<strong>増設系の作業は、公式が無停止と書いていてもダウンタイムを見込む。</strong></p>
<h2 id="結果">結果</h2>
<ul>
<li>原因不明の5.5日間停止から、<strong>26分の停止で海外VPSへ移行</strong>した。月額は$9.00から始まり、後にディスク増設で$12.60</li>
<li>応答は0.3秒前後から0.55〜0.7秒に落ちた。<strong>遅くなったのは事実</strong>で、これは引き受けた</li>
<li>公開IPになって初めて出た露出を6種類見つけて塞いだ。<strong>うち2種類(IPv6と、認証なしの19本)は最初の対処では見落としていた</strong></li>
</ul>
<p><strong>旧サーバーはすぐ捨てずに2週間温存した</strong>。これは正解で、移行翌日に「写真46件が旧サーバーにしか無い」と判明した時に助かった。復元の検証が全部終わるまでは、古い機械を消してはいけない。</p>
<p>そして<strong>ハングの原因は今も分かっていない</strong>。分からないまま、分からないものに依存する構成をやめた、というのが今回やったことの全部だ。</p>
<p><strong>更新履歴</strong> — 2026-10-05: 初版</p>
]]></content:encoded></item></channel></rss>