matpen
(Matt)
1
rake assets:precompile タスクにはデータベース接続が必要であることに気づきました。つまり、このタスクは「ビルド時」(コンテナイメージの構築中)ではなく、「実行時」(デプロイ後)にのみ実行可能です。このタスクは実行時間が非常に長くかかるため、不便です。
私は Ruby/Rails 開発者ではないため、調査を行ったところ、この動作は Rails 4 まで 無効化可能 であり、それ以降は開発者たちがいくつかのハック(null データベース接続など)に頼っていることがわかりました。後者の場合、何らかの障害を起こさないようにするため、アプリケーションの内部構造についての深い知識が必要です。
より良い解決策を探している最中に、このコミット を発見しました。これは精神面で類似しているようです。そこで以下の質問があります:
- すでに開発者がこの問題に取り組んでいるのでしょうか、それとも技術的な理由で実施不可能なのでしょうか?
- タスクの一部が実際にデータベース接続を必要とする場合、タスクを 2 つ(またはそれ以上)に分割して、ロケールのコンパイルや JS/CSS の最小化などの作業をビルド時に行うことは可能でしょうか?
- 現時点で既知の回避策(上記の「null データベース」など)は存在しますか?
Falco
(Falco)
2
テーマはデータベースに保存されます(管理UIで編集されます)。そのため、CSSはPostgreSQL内に格納されており、それらをプリコンパイルするにはビルド時にデータベース接続が必要です。
matpen
(Matt)
3
情報ありがとうございます!
ロケールのビルドを別々に実装し、ビルド時に実行することは可能でしょうか?
また、いくつかの環境(少なくとも私の環境ではそうなのですが)ではテーマの変更を許可したくない場合もあるかもしれません。その場合、CSS の代替ストレージを提供することは可能でしょうか?
Falco
(Falco)
4
カスタマイズ UI 全体を無効化するスイッチを導入するアイデアについては、すでに議論しました。これにより、CSS ファイルをビルド時にコンパイルし、ビルド中にオブジェクトストレージへアップロードすることが可能になります(JS コアやプラグインと同様の仕組みです)。
しかし、これは非常にニッチなケースであり、エンタープライズ向けデプロイメントのみに関心がある一方で、ウェブ上のコミュニティの 99% には何の価値ももたらしません。そのため、この機能はロードマップに含まれておらず、新機能の開発やパフォーマンス改善にリソースを割くことと比較すると、実現へのハードルは非常に高いです。
貴社の環境やユースケースについて、もう少し詳しく教えていただけますか?
matpen
(Matt)
6
すでにそのアイデアが議論されていたと知り、安心しました。変更に伴う作業量が大きすぎて、正当化できないことも理解しています。
私の場合、Discourse は既存の Web サイトと連携するため、Web サイトのデザインに合わせた固定のカスタムテーマを使用します。そのため、動的に変更することは意味がありません。
Falco
(Falco)
7
ああ、ビルド時にデータベースに接続できないというユースケースのことでした。
matpen
(Matt)
8
ええと、イメージをビルドするときは開発用のノートパソコンで作業しています。その後、そのイメージをリポジトリにプッシュし、最終的なシステム(DigitalOcean の VPS)がそこからプルします。
データベースは VPS 上のボリュームに存在するため、私のノートパソコンで更新することはできません。そのためには、Discourse を停止し、データベースをノートパソコンに rsync で転送し、イメージをビルドしてプッシュし、最後に Discourse を再起動する必要があります…
Falco
(Falco)
9
つまり、データベースとアプリケーションを同じ Droplet 内で実行しているのですね?
その場合、公式インストールガイドに従って、アプリケーションとデータベースが同じ Droplet 内に配置される構成にすれば、完全に機能するサイトが構築できます。このサイトは、Web インターフェースから、あるいは必要に応じてコマンドラインからフルイメージの再構築を行って更新することができます。
matpen
(Matt)
10
「ホスト上に直接」という意味であれば、いいえです。これらはコンテナ、具体的には podman コンテナ内で実行されています。理想的には、コンテナを複数のものに分けたいと考えています(Discourse用、Postgres用、Redis用など)。しかし、これは現在議論している問題と関連しており、適切な対応策についてまだ確信が持てていません。
私には危険に思えます。私は通常、本番環境にデプロイする前に開発環境でコンテナをテストします。さらに、理想的にはコンテナは読み取り専用であるべきです。
Falco
(Falco)
11
それらのコンテナを分割し、別の短期間のドロレットでイメージのブートストラップ処理を実行することができます。ドロレットは時間課金なので、コストは安く済みます。さらに、データベースコンテナホストと「ビルド」コンテナホストの間で、ドロレットのプライベートネットワークを活用することも可能です。
matpen
(Matt)
12
へへ、アイデアをありがとうございます。ただ、それは次第に複雑になってきます。さらに、ディスコースを停止してブートストラップ処理を待つ必要があるため、問題の解決にはなりません。そうしないと、データが不整合になる可能性があります。
アップグレード時には長いダウンタイム(マイグレーションとプリコンパイルで 5〜6 分)を覚悟する必要がありそうです。それでも、もし可能であれば、このトピックへのリンクを付けて、トラッカーに低優先度のissueとして登録していただけると幸いです。
ありがとうございます。これからも素晴らしい仕事を続けてください!
いいえ、そうではありません。
5〜6 分に対して「数秒」であるべきですが、専用のデータコンテナと Web コンテナが必要です。何を優先するかによります。
また、ベンチマークによると、高速なサーバー での再構築は約 3 分です。
matpen
(Matt)
14
なるほど、ありがとうございます。この場合、コンテナを分割します。そもそも、こちらの方がアーキテクチャとして優れています。
ただし、なぜこれで違いが出るのかがよくわかりません。私の認識が間違っていなければ、すべてのコンテナはすべてのホスト CPU を共有します(設定で変更しない限り)。そのため、どちらの場合でもプロセスは並列に実行されるはずです。何か見落としているのでしょうか?
michaeld
(Michael - Communiteq)
15
新しいコンテナの起動中に、古いコンテナは稼働したままになります。その後、古いコンテナを素早く停止して新しいコンテナを開始できるため、ダウンタイムを短く抑えることができます。