過去数年間、私は豊富なコンテンツと多数の画像を含む Discourse フォーラムを運営してきました。Maker Forums には100GB以上の画像と40万投稿以上があり、そのうち相当数が主に Google+ からインポートされ、残りはサイト上で作成されました。この投稿では、私が最終的に Maker Forums をどのように設定したか、そして後には他のいくつかの Discourse インスタンスをどのように設定したかについて説明します。これは私が始めた時に知っておきたかったことで、他の人が自分自身の Discourse インスタンスで同じような落とし穴を避けるために活用してきたものです。
より広い読者層に向けて。
警告: Linux システム管理者として作業することに慣れていない場合、このガイドはあなたには適していない可能性があります。Linux に関する知識を前提としている点について、私がすべて把握できているとは限りません。読んでいて啓発されるような感じであれば、あなたは対象読者です。読んでいて混乱する感じであれば、おそらく対象読者ではありません。これが仕事のように感じられる場合は、CDCK や @pfaffman に Discourse の運用を任せることを検討してください。彼らはプロフェッショナルです。あるいは、無料の discourse.group サイトから始めて、成長に合わせて有料プランに移行してください。
それだけではありません:私は Discourse よりも Linux の方が専門知識があります。私の意見には何の保証もありません。私のアドバイスに従って何か(あなたの Discourse フォーラム、ホストシステム、またはあなたの心)が壊れてしまった場合、両方の破片を鋭い縁付きで受け取ってください。この投稿のコンテンツに対して何らかのサポートを提供する予定はありません。
このドキュメントを、私が参加して維持している Discourse インスタンスの私のプラクティスに合わせて最新に保つ予定です(ただし、約束ではありません)。これはアドバイスとして書かれていますが、主に私自身と、私が責任を持って展開した Discourse を引き継ぐ管理者たちへのアドバイスとして意図しています。それ以外の場合は、Discourse をどのように展開するかを決定するための あなた自身の調査 の出発点として考えてください。
システム設定
CentOS 派生または Ubuntu LTS の OS を使用してください。Docker をサポートするものはおそらく動作しますが、私はこの2つを使用しています。
Docker
私は Fedora ユーザーです。Red Hat で最初の Fedora プロジェクトリードを務めており、Podman 上で Discourse を実行する方が好みです。なぜなら、そのセキュリティモデルは Docker より優れていると考えるからです。しかし、Discourse の展開は Docker のみでサポートされており、他のものを試そうとすると かなりパイオニア的な存在になります。(将来的には、docker-compose がサポートされた場合、podman-compose を使用して Podman で動作する可能性があります。)
Docker が cgroups v2 をサポートするようになったので、CentOS 派生システムに公式の Docker ビルドをインストールできます:
dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
dnf install --allowerasing docker-ce docker-ce-cli
(podman、runc、buildah との競合のために --allowerasing を含めます。これらはインストール時に削除する必要があります。)
systemctl enable --now docker
これは AlmaLinux 9 でテストしました。
セキュリティ
このセクションは Discourse 自体とは直接関係ありませんが、私の通常のセキュリティプラクティスの一部です。ネットワーク上のどのシステム(Discourse を実行している VM を含む)にもパスワードのみでのシェルアクセスを許可しないでください。 パスフレーズで暗号化された SSH キーを使用して SSH ベースのアクセスを設定し、VM 上の ssh サーバーがパスワードアクセスを許可しないように設定してください。
laptop$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/.../.ssh/id_rsa):
Enter passphrase (empty for no passphrase): SOME LONG PHRASE
Enter same passphrase again: SOME LONG PHRASE
Your identification has been saved in .ssh/id_rsa
Your public key has been saved in .ssh/id_rsa.pub
Linux ディストリビューションは通常、パスフレーズをメモリに記憶するように設定されているため、起動ごとに1回だけ入力すれば済みます。Windows はそれほど便利ではありません;同じことをするために Pageant と PuTTY を使用することを検討してください。
まず、パスワードなしで着信 SSH が機能するかを検証してください。その後に、サーバー上で /etc/ssh/sshd_config ファイルを編集し、PasswordAuthentication 行を見つけます。それを no に設定して、着信パスワードアクセスを無効にします。
PasswordAuthentication no
ファイアウォール
Discourse が公開される前でも、letsencrypt が SSL 証明書を生成および更新できるように、ポート 80 と 443 を一般的に開けておく必要があります。
firewalld を使用している場合、これらのコマンドで実現できます:
firewall-cmd --add-service http --add-service https --zone public
firewall-cmd --runtime-to-permanent
別のデバイスとファイルシステム
/var/discourse/shared を独自のファイルシステムを持つ別の デバイス にし、20GBのスペースと画像に必要な量の少なくとも2倍のスペースを確保してください;prometheus を使用する場合はさらにスペースを追加してください。デバイスが後で簡単に拡張できる場合(LVM や AWS elastic block storage のようなクラウドブロックストレージなど)、必要に応じて監視して拡張できます;そうでない場合は、初めに余裕を持たせてください。ネットワークストレージブロックデバイスを使用している場合は、パーティションテーブルを設定しないでください。パーティションテーブルなしで使用すると、拡張が容易になります;パーティションテーブルを修正する必要はありません。多くの場合、システムダウンタイムなしで拡張できます。
Maker Forums では、これは Maker Forums が実行されている VM に接続されたネットワークストレージブロックデバイスです。別の Discourse フォーラムでは、Digital Ocean Block Storage Volume です。Amazon では、AWS Elastic Block Storage です。Fedora 上の libvirt で KVM VM を実行している私のテストシステムでは、これは AlmaLinux VM に仮想ディスクとしてエクスポートされた Fedora ホスト上の LVM ボリュームです。いずれの場合も、新しい VM を作成し、重要なファイルをそこにコピーし、古い VM を停止し、/var/discourse/shared ボリュームを新しい VM に接続し、数分で復旧できました。これにより、VM 上のオペレーティングシステムのアップグレードが比較的低リスクになります。
VM のルートファイルシステムに少なくとも 25GB のスペースから始めることを確認してください;/var/discourse/shared のスペースは含みません。これはすべての docker コンテナに使用され、5GB 未満の空き容量がある場合、discourse launcher は失敗します。システム更新のためにも十分なスペースが必要です。ディスクスペースが不足している場合、これは回復が困難です。
サイト設定では、force_https を設定しますが、警告に従ってください。Discourse サイトを公開する前に、テストで設定してください。force_https でも、ポート 80 を開けておく必要があります;ポート 443 への SSL リダイレクトと letsencrypt SSL 証明書の更新のためです。(ただし、cloudflare を使用している場合は、その機能を使用してください;Discourse の force_https と互換性がないと報告されています。)
カーネル設定
Redis(Discourse が構築されている主要なコンポーネントの1つ)は オンディスク永続化を使用する際に透明巨大ページを無効にすることを強く推奨しています(Discourse はそうしています)、また、メモリオーバーコミットを許可しています。
echo 'w /sys/kernel/mm/transparent_hugepage/enabled - - - - never
w /sys/kernel/mm/transparent_hugepage/defrag - - - - never' > /etc/tmpfiles.d/thp.conf
systemd-tmpfiles --create
echo 'vm.overcommit_memory=1' > /etc/sysctl.d/90-vm_overcommit_memory.conf
sysctl --system
Discourse インストール
デフォルトのインストール は単一のコンテナですが、これにより、推奨される月次のアップグレードごとに、コマンドラインから実行する場合、通常10-15分のダウンタイムが発生します。これは、Discourse が構築されているツールの更新、セキュリティや新機能のため、または UI からのライブ更新が何らかの理由で失敗した場合に必要です。2コンテナインストールで、実際のダウンタイムを短縮できます。
2コンテナインストール
2つのコンテナで設定を開始します。
./discourse-setup --two-container --skip-rebuild
${EDITOR:-nano} containers/data.yml
./launcher rebuild data
# my preference to use app.yml but you might stick with web_only.yml, read text
mv containers/web_only.yml containers/app.yml
${EDITOR:-nano} containers/app.yml
./launcher rebuild app
これにより、数ヶ月ごとの必要なシステムダウンタイムが非常に短くなり、ほとんど気づかれません;多くのユーザーは、ダウンタイム中にクリックやスクロールを行わない限り、全く気づかないでしょう。これにより、ほとんどのセキュリティ更新を適用しやすくなります;すべてを再構築する約15分ではなく、一時的なブリップになります。次のプロセスは、ほとんどの更新で機能し、主にホストシステムの性能とインストールされているプラグインのセットに応じて、通常30-90秒のダウンタイムを提供します。
cd /var/discourse
git pull
./launcher bootstrap app
./launcher destroy app && ./launcher start app
./launcher cleanup
bootstrap と destroy/start 呼び出しの間に遅延しないでください。まれに(実際には年に1-2回)、bootstrap フェーズの最後に実行されるデータベース移行が、古いコードが更新されたデータベースにアクセスするために、アプリのユーザーに多少深刻なエラーを引き起こす可能性があります。
これは Discourse を更新する際に、データコンテナも更新する必要があるかどうかを確認する必要がある ことを意味しますが、これはまれに必要です(通常、年に1-2回を想定)。データとアプリコンテナの内容とシステムの速度に応じて、これは通常5-20分のダウンタイムをもたらします。
cd /var/discourse
git pull
./launcher stop app
./launcher rebuild data
./launcher rebuild app
データコンテナを更新するタイミングを知るための詳細については、次を参照してください:
(私の独自の展開では、web_only コンテナを app と呼ぶことを選択しました。これは、タイプしやすく、ほとんどの手順をより簡単に追跡できるためです。これは非標準ですが、使いやすさを常に高く評価しています。しかし、これは追加の作業であり、私が何が起こっているかを知っているため、私には機能します。これが悪く聞こえる場合は、マルチコンテナ展開ではデフォルトの web_only を使用してください。)
将来的に、Docker がコンテナを接続するための新しい構成への移行を強制する可能性があります:
4GB以上のメモリまたは複数の CPU を持っている場合、次のアドバイスを読んでください:
更新スケジュール
release-notes タグを監視してください(release-notes をクリックし、右上のベルをクリックします;私は「最初の投稿を監視」を使用しています)および/または https://meta.discourse.org/tag/release-notes.rss を RSS フィードに追加して、リリースがあることを知ってください。更新前にリリースノートを読んでください。データベース変更がある場合、リリースノートで言及されます。セキュリティ更新を含むリリースも強調されます。一部のバージョンへの実際の更新をスキップしても、すべてのリリースノートを読んでください;データベースを更新するリリースのリリースノートを読まない場合、読んでいないリリースノートのデータベース更新指示を見逃す可能性があります。
メール
メールは依然として人々を繋ぎ続けるための主要な方法の1つです。メールを機能させるために、送信および受信メールを設定してください。問題がある場合は、次を参照してください:
継続的に連絡を取る
Maker Forums には、長い間離れてから戻る偶発的な訪問者が見られます。デフォルトでは、Discourse は1年後にダイジェストメールの送信を停止します。偶発的な訪問者が新しい興味深いものを見たときに戻ってくるように促したい場合は、suppress_digest_email_after_days をデフォルトの365日より長い値に設定することを検討してください。Maker Forums では、偶発的な訪問者が最新情報を把握できるようにするために、これを大幅に長くしました。ダイジェストメールを読むことは、フォーラムで「 lurking(潜伏)」する有効な方法であり、誰かが貢献に興味を持つきっかけになるものがあるかどうかは分かりません。
同様に、デフォルトでは、ほとんど相互作用していない特権のないユーザー(投稿のない信頼レベル0)は、730日間ログインしない場合に最終的に削除されます。ユーザーが indefinitely(無期限に)ダイジェストメールを読んで lurking できるようにしたい場合は、「clean up inactive users after days」を 0 に設定して、ユーザーの削除を無効にします。
yearly review プラグインを追加することを検討してください。これは年に1回、2020: The Year in Review のような投稿を生成し、最終的に非アクティブなユーザーにメールで送信 します。これにより、参加を再開するよう促す可能性があります。
メール受信コンテナ
3番目のコンテナをメール受信として設定します。これにより、バウンス処理が保証され、バウンス処理が送信メールプロバイダーから独立し、メール返信のオプションが提供されます。
メール送信者を信頼するために SPF を設定していることを確認してください;少なくとも、同じ MX を介して送信および受信する場合、v=spf1 +mx -all のようなポリシーですが、より具体的であればスパム保護としてより信頼される可能性があります。DKIM も検討してください。
同じホスト名を使用してメールを受信する場合、本当にコンテナ外で SSL を終了する必要があります(「オフラインページ」の場合と同様)、certbot を実行した後、certbot 証明書をコンテナにマッピング し、コンテナを再起動する必要があります。
コンテナ外でユーザーの SSL 接続を終了する
コンテナ外で SSL を終了するための2つの選択肢があり、いずれもコンテナ内で終了するよりも大幅な利点をもたらします。discourse-setup を正常に完了し、フォーラムをブートストラップした後、そのうちの1つを設定してください。
外部 nginx
メンテナンスページをホストし、ホストが IPv6 サポートを持っている場合、IPv6 アドレスのログ記録をサポートするために、コンテナ内だけでなく、ホストシステム上で実行されている nginx を使用してください。(それ以外の場合、すべての IPv6 接続は、ローカル docker 仮想ネットワークインターフェースに関連付けられた内部 RFC1918 アドレスから来ているとしてログ記録されます。)この構成は、最終的にユーザーが見ていたページにリダイレクトされる一時的なメンテナンスページを、ほとんどのメンテナンス操作中に表示します。
このページの手順(現在)は letsencrypt というパッケージのインストールを提案していますが、現在通常は certbot と呼ばれています。このページの手順に従って --certonly を使用する場合、certbot の nginx プラグインは必要ありませんが、nginx プラグインのインストールは別のメカニズムです。CentOS 派生では:
dnf config-manager --set-enabled crb
dnf install epel-release
dnf install certbot python3-certbot-nginx
systemctl enable --now certbot-renew.timer
certbot が nginx とメール受信コンテナを再起動するように設定し、古い失効した証明書を继续使用するためにブラウザやメールがサイトへのトラフィックをブロックしないようにしてください。
# systemctl edit certbot-renew
メール受信がないシステムでは、次の2行を追加しました:
[Service]
ExecStartPost=/bin/systemctl reload nginx
システムから cert を共有する別のメール受信コンテナを使用しているシステムでは:
[Service]
ExecStartPost=/bin/systemctl reload nginx
ExecStartPost=/bin/sh -c 'cd /var/discourse && ./launcher restart mail-receiver'
SELinux を使用している場合、Ubuntu コンテナは nginx.http.sock ファイルを httpd_sys_content_t でラベル付けするように設定されていないため、外部 nginx がアクセスできません。2つの選択肢があります。
1つ目は、nginx を permissive モードで実行し、SELinux の保護を削除することです:semanage permissive -a httpd_t
しかし、これにより、おそらく最も関連性の高いサービスからの SELinux 保護が削除されます!SELinux を有効に保つには、nginx がエラーページにアクセスできるようにし、unix ドメインソケット経由のプロキシからポート(数µs遅くなりますが、ユーザーには気づかれないはずです)に切り替える必要があります。
まず、次のコマンドを実行して、nginx がエラーページにアクセスできるようにします:
semanage fcontext -a -t httpd_sys_content_t /var/www
restorecon -R -v /var/www
次に、app.yaml で - "templates/web.socketed.template.yml" をコメントアウトまたは削除し、ポート 80 をローカルマシン上の別のポートとして公開し、コンテナを再構築します。
expose:
- "8008:80" # http
ここで https を使用しないでください — 外部 nginx で SSL を終了しており、X-Forwarded-Proto ヘッダーが Discourse にリクエストが https を介して到着したことを伝えます。ポート 8008(または選択した他のポート)がファイアウォール設定によって公開されていないことを確認してください。
次に、次のコマンドを実行して、nginx がネットワーク経由でコンテナに接続できるようにします:
setsebool -P httpd_can_network_connect 1
次に、外部 nginx 構成を nginx.http.sock 経由のプロキシから http://127.0.0.1:8008(または選択したポート)に変更し、デフォルトの Connection: close ヘッダーをクリアし、外部 nginx が各リクエストに対して新しい IP 接続を確立する必要がないようにします。
...
location / {
proxy_pass http://127.0.0.1:8008;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
# Disable default "Connection: close"
proxy_set_header "Connection" "";
...
web.socketed.template.yml の削除により、real_ip 呼び出しも削除されたため、それを追加します。使用する IP アドレス範囲が意味をなすようにしてください;Docker のデフォルトは、ポリシーによりパブリックインターネットでルーティングされない 172.16* RFC1918 アドレス空間を使用することです。app.yml ファイルに次のようなものを追加し、展開に適した1つ以上の RFC1918 アドレス空間または他のものを選択します:
run:
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-recursive.conf
chmod: 644
contents: |
real_ip_recursive on;
- file:
path: /etc/nginx/conf.d/outlets/server/real-ip-header.conf
chmod: 644
contents: |
real_ip_header X-Forwarded-For;
- file:
path: /etc/nginx/conf.d/outlets/server/set-real-ip-from.conf
chmod: 644
contents: |
set_real_ip_from 192.168.0.0/16;
set_real_ip_from 172.16.0.0/12;
set_real_ip_from 10.0.0.0/8;
これは、レート制限が正しく機能し、ユーザーの登録および最終使用 IP アドレスを属性するために必要です。
詳細については:
外部サービス
私は Discourse の前に Fastly や Cloudflare を設定していませんが、他の人が設定しており、ホストシステム上で実行されている外部 nginx とは異なり、ホストシステムが完全にダウンしている間(ホストでのシステム更新中に再起動する場合など)メンテナンスページを提供できます。これがあなたにとって価値がある場合、次のように実行します:
S3 アップロードに急がないでください
セットアップ中に enable_s3_uploads を有効にするか、後で移行する前に、アップロードされた画像に S3(または同等のもの)を使用する ことを常に望んでいることを非常に確認してください。S3(s3_endpoint)とその関連 CDN(s3_cdn_url)を画像に使用すると、JavaScript もその CDN を介して提供されることに注意してください。S3 からローカルストレージへの移行はサポートされておらず、現在それを実装する具体的な計画はありません。これは、完全なバックアップと復元ですら取り消せない「一方通行のドア」です。S3 や同等のものを使用する場合、S3 の代わりに Digital Ocean Spaces を使用しないでください。meta で信頼性がないとの言及があります。
私は早期にサイトを Digital Ocean Spaces とその関連 CDN を介して画像を提供するように移動し、「一方通行のドア」が十分に理解されていないため、ローカルストレージに戻すために何百行ものカスタムコードを書く必要があり、その過程で Discourse インスタンスに軽微な損害を与えました。
詳細については:
Discourse に CDN を使用するために S3 アップロードを有効にする必要はありません。独自の画像を管理する Discourse の前に独立した CDN(例:Cloudflare、CloudFront、Fastly、GCS CDN)を使用することを検討してください。Cloudflare が推奨されないという警告は “Rocket Loader” が JavaScript を修正する ためであるという私の間接的な理解であり、現時点では、“Rocket Loader” を使用しない限り、正しく機能します。
モデレーションのための Discourse 設定
モデレーションがアクティブなサイトでは、モデレーターと管理者がトピックについてインラインで話せる enable_whispers 構成を強く検討してください。また、最近の Discourse バージョンでは、カテゴリモデレーターにより多くの機能が与えられています。異なるトピックの専門家が独自のカテゴリを持っている場合、またはサポートなどの機能的に分離されたカテゴリを持っている場合、enable_category_group_moderation を意識する価値があります。
ジオロケーションは、アカウントが正当かどうかを理解しようとする際に役立ちます。
Discourse Templates 機能はモデレーターにとって非常に役立ちます。これにより、一般的なレスポンスで協力できます。Maker Forums には数十個あります。これは、それを置き換える以前の「Canned Responses」プラグインよりも多くの機能を持っています。
User Notes 機能は、モデレーターがユーザーに関するノートを共有するのに役立ちます。これらを次のようなことに使用できます:
- 「このユーザーに注意してください、彼らは…のため悪意がある可能性があります。」
- 「この行動は疑わしいようですが、私は…によってこれが正当なユーザーであることを検証しました。」
- 「私はすでにこのユーザーと会話をして懸念に対処しており、他のモデレーターは追加する必要はありません。」
情報のアクセシビリティ
Discourse Solved プラグインは、解決された問題をマークしてサイト訪問者がそれらをより簡単に識別できるようにするだけでなく、google 検索結果を優先する可能性があります。
公開情報は非公開情報よりもアクセスしやすいです。Maker Forums では、FAQ は個人メッセージを強く抑制し、個人メッセージが真にプライベートではないことをEveryone に思い出させます。しかし、デフォルトでは、ユーザーは次のメッセージを見ることができます:
user に3回返信しました、代わりに個人メッセージを送信できることを知っていましたか?
本当にユーザーを個人メッセージに誘導したい場合は、Admin → Customize → Text に移動し、get_a_room テンプレートを修正してカンマスピスを修正することをお勧めします。
Maker Forums のように、会話を公開に保ち、Everyone に利益をもたらしたい場合は、Admin → Settings → Other → get_a_room_threshold を 1000000 のように高く設定できます。
同様に、ヘルプを提供するフォーラムを持っている場合、max_replies_in_first_day デフォルト 10 は、ヘルプを求める会話で新しいユーザーが返信の予算を使い果たしたときに個人メッセージに誘導する可能性があります。会話を個人メッセージに誘導しないように、この設定を増やすことを検討してください。
ユーザーを繋ぎ、コミュニティを構築する
いくつかのプラグインがユーザーを互いに繋ぐのに役立ちます。
フォーラムに同時ユーザーが多すぎない場合、Who’s Online プラグインを検討して、人々により接続感を与えてください。ログインユーザー、少なくとも信頼レベル1に達したユーザーのみに表示を制限したいかもしれません。whose_online_minimum_display を非常に高く設定し、whos_online_hide_below_minimum_display を true に設定して、アバターに存在フラール(whos_online_avatar_indicator)を追加するだけで使用できます。これは、ユーザーが問題を解決するのに役立つ質問と回答を迅速にサポートし、奨励するためにサポートフォーラムで有用です。
しかし、存在感は両刃の剣です。大多数のフォーラムユーザーとは異なる時間にオンラインのユーザーは孤独を感じるかもしれません、またはフォーラムは「ゴーストタウン」のように感じられるかもしれません。
多くの国のユーザーがいて、互いがより利用可能な時期についてのヒントを得たい場合は、National Flags プラグインを検討し、ユーザーがプロフィールに国旗を設定することを奨励してください。
翻訳は難しいです。同じ言語を話さない人々がコミュニケーションするのを助けるのは便利ですが、現在(この執筆時点)では、無料のサービスティアを持つ翻訳サービスはありません。翻訳サービスに支払うことを選択した場合、Discourse Translator プラグインで翻訳を有効にできます。
バックアップ
システムファイルについては、少なくとも次のものをバックアップすることを検討してください:
/var/discourse/containers(discourse 設定の詳細のため)/var/www(エラーページのため)/etc/ssl(letsencrypt 設定のため、バックアップを復元する一部として certbot をブートストラップする必要を避けるため;それ以外の場合、ブートストラップ中に nginx 設定の SSL 部分をコメントアウトする必要があります;これは証明書が短い有効性を持っているため、バックアップを最新に保つ場合にのみ機能します)/etc/systemd/system/backup-uploads.service(S3 への画像バックアップのため)/usr/local/bin/mc(minio-client を画像バックアップツールとして使用する場合)/root/.mc(minio-client による画像バックアップの設定)/root/.ssh(着信 SSH セッション認証のため)
これらのファイルの一部は、Git にチェックインしてオフサイトのある場所にプッシュしてバックアップできます。Git にチェックインするファイルに秘密(データベースパスワードなど)が含まれている場合、絶対に公開リポジトリにプッシュしないでください。代替として、それらをシステムからコピーして、あなたが制御する監視システム上の Git にチェックインするスクリプトを作成できます。/etc/ssl のバックアップを最新に保つために、これを十分に頻繁にスクリプト化してください。
目標は、災害の場合のバックアップと、ミスの場合の変更の記録を持つことです。
これらのファイルのほとんどにとって、より良い代替は、正規のコピーを他の場所に保ち、Ansible のようなツールを使用してシステム上の構成を維持することです。これにより、バックアップ後の更新が同等に容易になります。しかし、それを行う予定であれば、私が言う前に理解しているでしょう!
バックアップのための Discourse 設定
-
include_thumbnails_in_backupsでサムネイルをバックアップしてください。サムネイルなしの復元は、それらを再生成するのに時間がかかります。サイトにグラフィックスが少なければ、サムネイルは insignifiant なスペースを取ります。サイトにグラフィックスが多い場合、サムネイルの再生成には数日かかる可能性があります。サムネイルが再生成されている間、メール通知は無効になります。いずれにせよ、バックアップからサムネイルを省略する意味はありません。 -
多くの画像がある場合、バックアップに画像を含めないでください。これにより、バックアップが遅く、扱いにくくなります。それらを別々にバックアップしてください。データベースバックアップの後に画像をバックアップする場合、バックアップは一貫性があります。
-
バックアップが何らかの方法でオフサイトに行くように手配してください。
このページは、S3 または S3 のようなものへのデータベースバックアップを設定する方法を示しています:
restic でバックアップ
discourse をファイルシステムにバックアップするように設定し、次に restic を使用してファイルシステムからリモートバックアップターゲットにバックアップします。これはサンプルレシピです。
# dnf install restic
# mkdir /var/restic
# mkdir /opt/backup
# cd /opt/backup
# cat > backup <<EOF
#!/usr/bin/bash
set -e
. /opt/backup/backup-config
restic --cache-dir=/var/restic \
backup \
/etc \
/root \
/var/discourse \
/opt/backup \
--exclude /var/discourse/shared/data/postgres_data
restic --cache-dir=/var/restic forget \
--prune --keep-hourly 24 --keep-daily 7 --keep-monthly 3
EOF
# chmod +x backup
これらの詳細は、使用する restic ターゲットによって異なります。すべてが AWS の環境変数を使用するわけではないため、restic のドキュメントをお読みください。
# cat > backup-config <<EOF
### これらの詳細は設定する restic ターゲットに依存するため、変更してください
export AWS_ACCESS_KEY_ID=yours-here
export AWS_SECRET_ACCESS_KEY=same
export RESTIC_PASSWORD_FILE=/root/restic-password
export RESTIC_REPOSITORY=see-the-restic-documentation
EOF
# {$EDITOR:-nano} /root/restic-password
/root/restic-password に設定した内容のコピーを保管しておく必要があります。保管しないと、バックアップの復元ができなくなります!パスワード保管ツール(パスワードボルト)を使用してください。
最後に、いくつかのサービスを作成し、restic リポジトリを初期化して、バックアップが開始されるようにタイマーを設定します。
# cat > /etc/systemd/system/backup.service <<EOF
[Unit]
Description=Back up to remote target
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
StandardOutput=file:/var/log/backup.out
StandardError=file:/var/log/backup.err
WorkingDirectory=/var/discourse
ExecStart=/opt/backup/backup
[Install]
WantedBy=multi-user.target
EOF
# cat > /etc/systemd/system/backup.timer <<EOF
[Unit]
Description=Regular system backups
[Timer]
Persistent=true
OnCalendar=00/4:30:00
Unit=backup.service
[Install]
WantedBy=timers.target
EOF
# systemctl daemon-reload
# . /opt/backup/backup-config
# restic init
# /opt/backup/backup
# systemctl enable backup.timer
このプロセスの後、初期バックアップが作成されたことを確認できるはずです。
# restic snapshots
この方法で作成された restic バックアップを使用して、restic restore コマンドで Discourse サーバーを別のシステムに移行することに成功しました。
minio による画像のストリーミングバックアップ
Restic の代替案として、データベースのバックアップは S3 に保存できますが、S3 から画像を提供することとは別に、S3 用の画像バックアップ機能はありません。代替案として、minio-client を使用して、画像を任意の S3 互換ストレージにコピーします。これには S3 や minio など多くの S3 互換ターゲットが含まれますが、Ceph ファイルシステムの上に構築されており、S3 とは異なる方法で ListObjectsV2 API を実装しているため、DigitalOcean Spaces は対象外です。
S3 で、パブリックアクセスをブロックするバケットを作成します(AWS でこれを正しく設定する簡単な方法は、Permissions → Block public access です)。
minio-client (mc) を何らかの方法でインストールします。以下はその一例です。
curl https://dl.min.io/client/mc/release/linux-amd64/mc > /usr/local/bin/mc && chmod +x /usr/local/bin/mc
以下のようなコマンドを使用して、backup というエイリアスで minio-client を設定します。
# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4
# mc mirror /var/discourse/shared/standalone/uploads backup/UPLOADS-BACKUP-BUCKET
次に、以下のように /etc/systemd/system/backup-uploads.service サービスを作成します。
[Unit]
Description=Neartime remote backup sync of discourse uploads
After=network.target
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=600
User=root
ExecStart=/usr/local/bin/mc mirror --overwrite -a --watch /var/discourse/shared/app/uploads backup/UPLOADS-BACKUP-BUCKET
[Install]
WantedBy=multi-user.target
ここで、UPLOADS-BACKUP-BUCKET は、Discourse がデータベースバックアップをアップロードするように設定する s3_backup_bucket とは異なるバケットである必要があります。また、標準のマルチコンテナデプロイメントを使用している場合、パスは /var/discourse/shared/web_only/uploads になる点に注意してください。
# systemctl enable backup-uploads
# systemctl start backup-uploads
# journalctl -fu backup-uploads
テスト用の画像をアップロードし、元の画像と最適化された画像のバックアップが成功したことを示す行が表示されることを確認します。Control-C で journalctl の追従モードを終了できます。
復旧
執筆時点では、このプランを実際にテストしたことはありません。この概要では何か見落としている可能性があります。
- 一般的に、バックアップされたすべてのファイルを復元します
- nginx を起動します(これでメンテナンスページが表示されます)
/var/discourse/containersにある復元されたファイルを使用して、Discourse の通常デプロイを実行します- バックアップから復元していない場合は、
/usr/local/bin/mcに minio-client をインストールします /root/mcのバックアップを行わなかった場合は、バックアップエイリアスを設定します# mc alias set backup https://s3.amazonaws.com ACCESSKEY SECRETKEY --api S3v4# mc cp backup/UPLOADS-BACKUP-BUCKET /var/discourse/shared/app/uploads- 最新のデータベースバックアップを復元します。Restore a backup from the command line を推奨します
- サイトが正常に動作することを確認した 後 だけで、上記のドキュメントに従って S3 へのアップロードバックアップを再設定します。
PostgreSQL のストリーミングバックアップ
将来、PostgreSQL の continuous WAL archiving を使用して、postgresql の archive-command で minio-client を使用し、アップロードバックアップのストリーミングと同様に、ほぼリアルタイムの Postgres バックアップをストリーミングする設定を作成、テスト、提供する可能性があります。
パフォーマンスモニタリング
パフォーマンスモニタリングには、少なくとも2つのアプローチがあります。
Prometheus コンテナ
Prometheus を設定し、同じシステムで実行している場合は、Prometheus のログを /var/discourse/shared/prometheus に配置します。Prometheus のファイルは大きくなる可能性があり、ルートファイルシステムが埋め尽くされるのを防ぎたいです。また、新しいホストシステム(より大きな VM へのアップグレードや、新しいオペレーティングシステムのインストールされた VM)に移行する際に、これらのファイルを移行したい場合もあるでしょう。
Prometheus を Discourse システム(またはパブリックインターネット上の他の場所)にデプロイする場合は、その前にセキュリティを設定してください。このようにインストールした場合、以下のような nginx 設定が一つの選択肢となります。
location /prometheus/ {
auth_basic "Prometheus";
auth_basic_user_file /etc/nginx/prometheus-htpasswd;
proxy_pass http://localhost:9090/;
}
Sysstat
Prometheus が複雑すぎる場合は、代わりに sysstat を検討してください。
dnf install sysstat(Debian およびその派生システムではapt install sysstat)systemctl enable --now sysstatsystemctl enable --now sysstat-collect.timersystemctl enable --now sysstat-summary.timersystemctl edit sysstat-collect.timerを実行し、OnCalendar=*:00/10をOnCalendar=*:00/2に変更します/etc/default/sysstatが存在する場合は、falseをtrueに変更します
これ以降、sar コマンドを使用して、時々リソースが不足していないか確認できます。
その他のリソース
以下は、Discourse を社内コミュニケーションの主要な手段として内部的に使用することに関する補足的(かつよりコンパクトな)議論です。