メンテナンスページの回避策 - これって可能?

うん、段階的にやるのがいいよ:

  1. 多少強力なサーバーを入手する
  2. 2つのコンテナのインストールを動作させる

この時点で満足ならここで止めてもいいし、そうでなければ:

  1. 上記の@Lillyの優れたガイドを使ってメンテナンスページを実装する。:+1:

ハハ、この部分について説明する時間を取らなかったのですが、質問してくれてよかったです(説明すべきでしたよ。説明すべきことが多く、Cloudflare は複雑ですから!)

ワーカーのルートページが設定されると、フォーラム上のすべての画像の読み込みやページビューがそのワーカーを介してルーティングされます。

Cloudflare の無料 CDN プランには、ワーカーのルートに対して 1日あたり 100,000 リクエストの制限が含まれています。

したがって、比較的活発なフォーラムの場合、1日以内に無料枠の上限に達しないようにするため、常時オンにしておくのは避けたほうがよいでしょう。 これはワーカーのルートのことであって、メンテナンスページのことではありません。メンテナンスページは常時表示しておくことができます。ワーカーのルートが設定されていない限り、メンテナンスページにはアクセスされません。 これは、ステップ 2 でルートを割り当てた部分(設定と削除が簡単です)にすぎません。 Cloudflare の有料プランを使用していない限り、メンテナンス作業を行っている間のみルートを有効にしておくのがよい習慣です。

  1. ドメインの Cloudflare ワーカー ルートページに移動し、ルートの右側にあるボタンをクリックします。

  1. 編集画面の下部で、remove(削除)ボタンをクリックして、ワーカーページをルートから切り離します。

  1. 心配しないでください。 ワーカーコード自体は削除されず、ルーティングルールのみが削除されます。 次にリビルド/アップデートを実行するときは、上記のステップ 2のように再度追加すればよいです。

Cloudflare の有料プランを使用している場合は、何も心配する必要はありません。 ただし、その場合はワーカーページではなく Cloudflare のエラーページを使用できます…(Cloudflare がかなり複雑だと言いましたよね?LOL)

:warning: 以下は高度な管理者設定です

無料プランでアップデートを完全に自動化したい場合は、Cloudflare API トークンとゾーン ID、および curl コマンドを使用してワーカーの route id を取得する必要があります。 次に、ワーカーのルートを自動的にオン/オフするためのいくつかの追加の処理を /root/update-web.sh スクリプトに追記します。

#!/bin/bash
cd /var/discourse

CF_TOKEN="your_actual_token_here" #<---Cloudflare API トークン
ZONE_ID="xxxx" #<---Cloudflare プロファイルページから取得
ROUTE_ID="xxxx"
WORKER_NAME="my-site-maintenance-page"

echo "➡️ 最新の Discourse Docker スクリプトを取得中..."
git pull

echo "➡️ 背景で新しい Web コンテナをブートストラップ中..."
./launcher bootstrap web_only

if [ $? -eq 0 ]; then
    echo "✅ ブートストラップ成功!"
    
    # Cloudflare メンテナンスワーカーを有効化
    echo "🚧 メンテナンスページを有効化中..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":"'$WORKER_NAME'"}' > /dev/null

    # コンテナを切り替える(30秒のダウンタイムウィンドウ)
    echo "🔄 コンテナを切り替え中..."
    ./launcher destroy web_only && ./launcher start web_only
    
    # Cloudflare メンテナンスワーカーを無効化
    echo "🌍 メンテナンスページを無効化中..."
    curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/workers/routes/$ROUTE_ID" \
         -H "Authorization: Bearer $CF_TOKEN" \
         -H "Content-Type: application/json" \
         --data '{"pattern":"*your-site.com/*","script":null}' > /dev/null

    echo "🚀 完了! ダウンタイムなしでサイトが更新されました。"
else
    echo "❌ ブートストラップ失敗! 現在のサイトをオンライン状態に保つため、切り替えを中止します。"
fi 

私はすべての自動化には興味がなく、アップデート/リビルド時に立ち会いたいので、以前のスクリプトバージョンを使用しています。 アップデートを実行する直前にワーカーのルートを追加し、その後削除するだけです。 これには数秒しかかかりません。

私の一般的な手順は以下の通りです:

  1. Cloudflare でワーカーのルートを追加
  2. Hetzner に SSH 接続
  3. システムのアップデートを実行(例:sudo apt update && sudo apt upgrade -y、必要に応じてサーバーを再起動)
  4. 再起動が必要だった場合は再度 SSH 接続
  5. ./update-web.sh を実行
  6. Cloudflare でワーカーのルートを削除

Visual Basicで昔々「Hello World」を1回やったことがある程度で、コーディングや開発の世界についてはほとんど何も知りません。でも、WordPressやMastodon/Pixelfedサーバー、そして何となくDiscourseの管理はそれなりにできるんです。それに、AIというものが存在します(ただし、宣伝されているほど初心者に優しいわけではありません)。

Dockerを使っているDiscourseでは、これが現実的に可能かどうかはわかりませんが、通常のNginx-Varnish-WordPress環境では、Pleskサーバーが50xエラーを検知してエラーページを表示するシステムを構築したことがあります。実際には3つの構成があり、Varnishがダウンした場合はフロントエンドのNginxが生成したスナップショットコンテンツを表示し、WordPress関連のバックエンドがダウンした場合はVarnishがキャッシュされていないコンテンツにスナップショットを使用し、3つ目はフロントエンドのNginxが応答しない場合のエラーページです。

Varnishの仕組みはDiscourseでは使えませんが、Dockerの世界でも50xエラーが発生した際にエラーページを表示するような複雑なシステム(スパイダーウェブのようなもの)を構築できない理由は見当たりません。

ただし、そのようなシステムは非常にエラーを引き起こしやすいものになるでしょう。そして、ユーザーが数十人を超えた場合に何が起こるのか、私には全く見当もつきません。

もちろん、最も明らかな解決策もあります:Discourseの前にNginxを配置するということです。2コンテナ構成に移行する以前、私はその方法を使っていました。

ついに時間をかけてDiscourseを再インストールしました。現在の状況を評価し、2つのコンテナの運用にどれほどのメンテナンスが必要かを考慮した結果、当面は1つのコンテナで運用を続けることにしました。将来的に2つのコンテナが必要になった場合は、ここで述べた内容を見直すつもりです。プラグインのインストールは、コンポーネントの管理ほど頻繁に行う必要がないようです。また、オンラインユーザーが少ない時間帯にコミュニティが20分間ダウンすることと、コミュニティが特定の日に一時停止されることをユーザーに知らせるバナーを表示することなら、現時点ではかなり合理的だと考えています。

どうなるか見ていきましょう。

単一のコンテナとほぼ同じくらい必要です :flushed_face:

そして、心痛も少し減るでしょう :slight_smile:

どのように進めるのか、もう少し詳しく教えていただけますか?

私への返信だったのか、@Jagsterさんへのものだったのか、少しわかりません。どういう意味ですか?

サイトがオンラインのままで新しいコンテナをブートストラップするプロセスは、はるかにストレスが少なく、ビルドが壊れてもパニックになる必要がなく、オフラインにならずに修正に必要な時間をすべて確保できるためです。

つまり、両方を持つことを推奨しているのですね。だから「心の痛みが少ない」ということなのですね。
この分野に不慣れな私としては、2つのコンテナがあるからといって、Discourseのインスタンスが2つあるわけではないと思っていますが、合っていますか?

というトピックを読んで、これにどれくらいの作業量や注意が必要なのかを理解しようとしています。そうすることで、私が管理できない状況に陥って、単一のコンテナで起こりうる他の問題よりも、プロセス全体をより問題のあるものにしないようにしたいのです。

2つのコンテナ構成について共有してくださったことに感謝を伝えたいです。私は1つのコンテナを使用しており、通常3〜5分かかります(64GB RAM搭載の専用サーバーの場合)。

デュアルインストール環境では、両方のコンテナを更新すべきタイミングを、明確でシンプルな例を交えて教えていただけますか?つまり、どのDiscourseのアップグレードで両方のコンテナを再起動し、新しく作成されたweb_containerのみを再起動すればよいかを知りたいのです。

まず、2コンテナ構成での起動方法について、非常にシンプルな手順に従います。その後、主に必要なのは以下です。

./launcher bootstrap web_only && ./launcher destroy web_only && ./launcher start web_only ) 2>&1 | tee ~/$(date +%Y-%m-%d_%H-%M-%S)-upgrade.log'

tee 部分はログ出力のためのもので、私が使用している tmux のフィードを見るよりも(私にとっては)ブラウザで確認する方が簡単だからです。

基本的には app.yml を使用して再構築するのと全く同じですが、ユーザーへの影響ははるかに少なくなります。もちろん data-container も存在しますが、メンテナンスが必要になることは非常に稀です。もしコンテナでより高度な操作を行うのであれば、コンテナの扱い方とタイミングもご存知のことでしょう。

2コンテナ構成でアップグレードが失敗した場合でも、フォーラムは起動したままですが、単一コンテナ構成ではクラッシュしてしまいます。

つまり、起動だけが少し手間がかかりますが、手順は非常に明確です。Amazon SES を使用する場合、mail-reveiver の設定の方がより難しい作業だと思います。

例えば、これは私が単純に無視できない種類のコメントです。アップデートやアップグレードが、単にボタンをクリックするだけというほど簡単ではなく、より多くの注意と集中を必要とするもののように見えるからです。経験豊富な人にとっては簡単で自明なことに見えるかもしれませんが、そうでない人にとってはそうではないかもしれません:

このトピックの指示は、2015年のものですが、2026年でもまだ正確ですか?

今日ちょうどDiscourseを再インストールしたばかりなので、試してみても構いません。もし何か問題が起きても、1つのコンテナに戻すだけで済みます。ただ、作業の途中で、2026年にもう適用できないことをやってしまわないか、確認したかっただけです…

私にとっての「数分」の節約は、20分以上のものです。月1回のアップグレードなら月1回という点は正しいですが、私は少なくとも週2回アップグレードを行っています。また、あるプラグインが失敗して何回も試行錯誤しなければならない場合(もちろんライブインスタンスで作業しているため :wink:)は、その長いダウンタイムはただの苦痛です。

新しいリリースごとに追うべき「アナウンスの詳細」など存在しません。mcdanlj さんにはそれが当てはまるかもしれませんが、彼は普通のシステム管理者ではなく、はるかに高いレベルで仕事をしているのです。

ちょっと混乱しています…

あなたはこう言っています:

しかし、その上にあるあなたの返信を読むと、こう言っているため、さらに多くの作業が必要になるように聞こえます:

このことだけで、2つのコンテナは確かに1つよりもメンテナンスが複雑で、同じではないように聞こえますよね。ダウンタイムなどのことは理解していますが、コンテナ自体のメンテナンスは、単一のコンテナでのシンプルなアップグレードよりも複雑で、エラーが発生しやすそうに見えます。何か見落としている点でもう?

その通りです:

コンテナ1 = ウェブサイトとnginx
コンテナ2 = データベースとredis

(おそらくこれが正しいはずです)

コンテナ1の内容は_かなり頻繁に_変更されます。

コンテナ2の内容は非常に稀に変更されます。

そして、コンテナ2を更新せずにコンテナ1だけを更新できます。

さらに素晴らしいことに、コンテナ1の代替品を準備してから、数秒で切り替えることができます(この準備作業は「ブートストラップ」と呼ばれます)

単一コンテナ構成の場合、./launcher rebuild app を実行すると、Web とデータの両方が停止され、両方がアップグレードされます。ただし、データ側のアップグレードは非常に稀にしか必要ありません。また、ジョブが完了した後、問題がなければすべてが再起動されます。

2コンテナ構成では、“web” コンテナのみを再構築し、データコンテナには手を加えません。すべてが正常に完了すれば、古いコンテナを削除して新しいコンテナを起動します。もし何か問題が発生しても、以前から機能していた “web” コンテナが引き続き使用され続けるため、影響を受けません。

つまり、実際の違いは、ソフトウェアとデータベースのその他のいくつかの項目をどう扱うかという点に限られます。

もちろん、1コンテナ構成も選択肢の一つです。ただし、本質的なポイントは、2コンテナ構成を作成した場合、難易度の名前に関する唯一の実際の違いは、アップグレード時に使用されるコマンドであり、そのためには alias が使えます :wink:

これは、データベースの更新時期が来たと何かを述べる手書きの告知があった時代の話です。新しい自動化されたサイトは派手ですが、かつてのように、実際に最も重要なことについての人間の注記はありません。

今では、データベースが更新されるという投稿に気づく必要があるのでしょうか? 私は数ヶ月間それらを逃していたようです。

しかし、これは数年に一度しか起こらず、DB を明示的に再構築する際に再構築され、CDCK はしばらくの間、古いバージョンの pgsql との互換性を保っているようです。そのため、実際には私に影響を及ぼしたことはありません。少なくとも今のところ。

自分自身のために 2コンテナ(またはそれ以上!)のセットアップはとても気に入っていますが、それが誰でも最も簡単ではないため、まだ注意を促しています。2コンテナのデプロイが「もちろん、それは簡単だ」と感じる人が誰で、「うーん、ただボタンを押したいだけだ」と感じる人が誰なのかを判断するのは私にとって難しいことです。