コンテナーにJavaScriptベースの静的Webサイトを展開/ホストするための戦略


7

これは、いくつかの開発チームで時々発生しますが、「正しい」方法を理解していません。

私たちは、いくつかのhtml、js、cssファイルである静的なWebサイトに「コンパイル」する多くの反応ベースのWebアプリケーションを使用しています。

ただし、これらのアプリの「ビルド」は、機能フラグの有効化/無効化、バックエンドURLの構成など、いくつかの変数を使用します。つまり、従来の意味でバイナリを「ビルド」して、デプロイ時に設定ファイルを適用することはできません。時間-「ビルド」自体にこれらの環境固有の変数を設定する必要があるため、「ビルド」できるのはデプロイ時のみです。

とりあえず、必要な環境変数をDockerコンテナーに注入し、次の行に沿って開始コマンドを実行することでこれを解決します

npm build && nginx run

これにはいくつかの欠点があります。

  1. ビルドプロセスは、コンテナーのランタイム要件に比べて多くのCPU /メモリを消費します。つまり、ランタイム要件ではなく、ビルドプロセスのコンテナーをスケーリングする必要があります。
  2. ビルドの失敗を「追跡」するのは困難です。Kubernetesでヘルスチェックを使用できますが、ビルドに2分かかる場合でも、コンテナーのヘルスチェックエンドポイントのテストを開始してその生存を確認する前に、3分(安全のために1つ余分)待つ必要があります。
  3. デプロイには時間がかかることがあります。「シリアル」デプロイを行うようにKubernetesを構成すると、各ポッドが開始され、2〜3分の「initialDelay」期間待機してから次のポッドが開始されます。これは、デプロイが3〜4ポッドにスケーリングされている場合、10分のデプロイ時間を簡単に見ていることを意味します。

これはすべて、私にとって非常に最適ではないと感じています。コミュニティーが「ビルド時にデプロイ」という難問を最新のJavaScript Webアプリケーションで解決する方法を聞いてみたいと思います。

Kubernetesの場合、ビルドを実行し、アーティファクトを永続ストレージに配置し、起動時にアプリコンテナーを永続ストレージから単純にプルする「init-containers」を使用できることを理解していますが、これはまだ問題を「バイパス」するように感じられます根本的な問題を解決します。


申し訳ありません、わかりません。なぜnpm build、コンテナのビルド時ではなく実行時に実行するのですか?
Xiong Chiamiov 2018

@XiongChiamiovフロントエンドの構成はビルド中に行われ、再ビルドしないと変更できないと思います(最悪の場合、コンテナーの起動時に「sed」される可能性があるインクルードファイルで分離する必要があると思います)
Tensibai

丁度。npm build単なる任意のコマンドです。JSフレームワークが期待するものreact buildか、sanity buildそれとも何でもかまいません。コンテナのデプロイ時にそれを行うことを余儀なくされているのは、それがbuild目的の環境を知っているときだからです。
Trondh

回答:


5

私の立場から見ると、最善のアプローチは次のとおりです。

  1. NodeJSプロジェクトをディストリビューションにビルドし、それをDockerイメージにラップするJenkinsを使用した個別のビルドプロセス
  2. JenkinsからのDockerイメージを蓄積するDockerレジストリを起動します(このレジストリはKubernetesクラスターからアクセスできる必要があります)
  3. 環境変数をJenkinsシークレットに移動するか、別のツールを使用して外部Gitリポジトリから構成を収集および結合します(REST APIを介してSpring Cloud Configを使用して、すべての環境のすべてのアプリケーションのjson / yml定義を収集します)

Jenkinsを使用すると、一般的なパイプラインに基づいて継続的デリバリーシステムを構成できます。可能なフローは次のとおりです。

  1. 開発者はGitFlowに対応して作業を完了します(最新のプルリクエストはリリースブランチにマージされます)
  2. WebhookがJenkinsパイプラインをトリガーします。
    • ステージ1:環境定義を収集する
    • ステージ2:npmを使用してNodeJSアプリを構築する
    • ステージ3:ディストリビューションを使用してNginx Dockerイメージをビルドする
    • ステージ4:DockerイメージをDockerレジストリにプッシュする
    • ステージ5:標準定義を使用してKubernetesにサービスをデプロイ/更新する
  3. 結果に関する通知の送信

このプロセスは、Rancherを使用して視覚化できます。チャットで質問にお答えします。


それで、環境ごとに1つのイメージを持つことを提案していますか?これは、いくつかの変数のために
大量

@Tensibai urは、各環境ごとに約15MBの画像について話します。ローテーションと追加の管理人サービスがあれば、1 Gbですべてのプロジェクトを処理できます。
マクシム2018

このソリューションに基づいて、アプリの複数の「構成」をどのように作成しますか。たとえば、「ステージング」用と「製品」用の1つです。。(「BackendApi」という設定は、例えば異なり、ということがあることをふりをすることができます
Trondh

@Trondhは、Spring Cloud Configを使用すると言ったとおりです。これは、アプリケーションごとに基本構成を取得し、から追加構成を適用しますprofiles。たとえば、リクエストhttps://config/backend.ymlするapplication.ymlと、から設定を受け取り、から追加のプロパティを受け取りますbackend.yml。以下のためにhttps://config/backend-stage.ymlそれが適用されることにより、プロパティで応答しますapplication.yml< - backend.yml< - backend-stage.yml
マクシム

@Maksim 15MBを数バイトのテキストに使用するのは無駄です。ある時点で、さまざまなバージョンのさまざまな環境で数百のマイクロサービスを使用すると、元の同じ数バイトのデータのTBになります。QAとprodのイメージが2つのビルドのものと本当に同じであることを保証できないので、私があなたが提案していることを正しければ、それは私の意見では間違った道です(同じコードであっても、それらは同じidと検証は混乱になります)。しかし、多分私はそれを正しく取得し、ポッドのスピンアップ時に画像と設定が1つしかない場合は、投稿が正しく理解されなかった可能性があります。
Tensibai
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.