ベースイメージ#
ベースイメージとは何ですか?#
ベースイメージは、Lagoon上でデプロイされたプロジェクトが使用できる、または使用しているDockerイメージです。ベースイメージは、監査されていないものが上流からコードベース/プロジェクトに持ち込まれないようにする方法を提供します。また、低レベルのライブラリからアプリケーションレベルのテーマとモジュールまで、デプロイされた環境上で必要となる可能性のあるものがすべて利用可能であることを保証します。
ベースイメージは、どのシステムがデプロイされているかがわかっている場合、時間とリソースの節約に役立ちます。つまり、共有パッケージがベースイメージに含まれている場合、それらを個々の数百のサイトにデプロイする必要はありません。
派生イメージ#
派生イメージとは、ベースイメージを拡張するイメージのことを指します。例えば、いくつかのブログサイトを作る必要があるかもしれません。私たちのDrupalイメージを取得し、ブログサイトに必要なモジュールとテーマすべてを含めてカスタマイズし、そのブログイメージですべてをデプロイします。テンプレートはベースイメージから派生します。
すべての派生イメージは、composer.json
ファイル(Packagist、Satis、またはGitHubなどのリポジトリ経由で)を取り込む必要があります。これにより、基本パッケージの最新バージョンを使用するようになります。
さらに、派生イメージには、/build/pre_composer
スクリプトへの呼び出しが含まれています。これは、ベースイメージが派生イメージでスクリプト、アップデートなどを実行するために使用できます。例えば、派生イメージでパッケージが更新またはインストールされると、デフォルトで実行され、pre_composer
スクリプトはその後、ベースイメージパッケージを更新します。
べースイメージの構造#
情報
このドキュメントでは、DrupalやLaravelのベースイメージを例に取り上げます。これは、元々Lagoonプロジェクトでこれらのテクノロジーを使用しているクライアント向けに書かれたものです。他のベースイメージの内容もカバーするように拡張されますが、ベースイメージの内容に関係なく、プロセスは変わりません。
ベースイメージは、Composerで管理され、BitBucket、GitHub、またはGitLab (チームが使用しているもの)にホストされています。各ベースイメージには独自のリポジトリがあります。
メタパッケージ#
メタパッケージは、複数の他のコンポーネントを包括するComposerパッケージです。これには、例えば、LaravelやDrupalのコアファイル、必要なモジュールやテーマなどが含まれます。 これにより、プロジェクトの依存関係に Laravel や Drupal などを含める必要がありません。
以下は、Laravelのベースイメージを composer.json
から使用した例です:
私たちに必用なのはGitHubリポジトリを指すこのメタパッケージだけです。
docker-compose.yml
#
プロジェクトの他の部分は docker-compose.yml
で定義されています。例えば、Drupalプロジェクトを持っている場合、Drupal のイメージが必要ですが、MariaDB、Solr、Redis、Varnishも必要です。これらのサービスのバージョンはDrupalに最適化されており、すべてdocker-compose.yml
に含まれています。
Drupal#
Drupalベースのイメージには、Drupalコアに加えて以下のコントリビュートツールやモジュールが含まれています:
- Drupal Console
- Drush
- Configuration installer
- Redis
- Poll
- Search API
- Search API Solr
- Varnish Purge
- Purge
- Admin Toolbar
- CDN
- Password Policy
- Pathauto
- Ultimate Cron
Laravel#
設定#
ベースイメージは、Laravelで使用される環境変数のデフォルト値を提供しています。
これらは以下の値です:
DB_CONNECTION
DB_HOST
DB_PORT
DB_DATABASE
DB_USERNAME
DB_PASSWORD
REDIS_HOST
REDIS_PASSWORD
REDIS_PORT
設定ファイル(通常は/config
に位置しています)がこれらをデフォルトで使用するように確認してください。
キュー#
プロジェクトがキューを使用している場合、artisan-worker
サービスを使用できます。これはワーカーコンテナで、artisan queue:work
の実行に使用されます。これはデフォルトでは無効化されています。(docker-compose.yml
のコメントをご覧ください)
ビルドプロセスの理解 ベースイメージ#
ベースイメージを構築するプロセスにはいくつかの部分があります。主要なステップはすべてMakefileに記載されています。Jenkinsfileにはよりシンプルなビューが含まれています。これらのファイルを見ることで、このプロセス中に何が起こるかをよく理解することができます。ほとんどのステップはローカルでテストできます(これは新しいバージョンのベースイメージを構築する際に重要です)。ローカルで全てを作成し、テストした後にプッシュすると、実際のベースイメージはJenkinsによって構築され、Harborにプッシュされます。
Makefileとビルドの前提条件#
ローカルで実行する場合、ビルドするために最低限必用な環境変数がいくつかあります。
ベースイメージビルド変数#
ベースイメージビルドプロセスに注入される変数と、それを見つける場所です。
BUILD_NUMBER
- これは自動的にJenkinsによって注入されます。GIT_BRANCH
- これはJenkinsのビルドプロセス自体によって提供されます。その時点でビルドされているブランチ(develop、mainなど)に依存します。DOCKER_REPO
/DOCKER_HUB
- これはJenkinsfile自体内で定義されていて生成されたイメージがプッシュされるDockerプロジェクトとハブを指しています。DOCKER_USERNAME
/DOCKER_PASSWORD
- これらは、ビルドの早い段階でDockerリポジトリに実際にログインするために使用されます。これらの変数はJenkinsの認証情報内に保存されます。これらはJenkinsfile自体で使用され、Makefileの一部ではありません。つまり、Jenkins以外の場所(ローカルでテストするなど)でベースイメージをビルドする場合、docker login
を手動で実行する必要があります。
実際には、ローカルマシンでmake
ターゲットを実行している場合、これらが環境で利用可能であることを確認したいと思うでしょう - たとえば、コマンドラインからmakeを実行するときにこれらを設定するだけでも構いません:
GIT_BRANCH=example_branch_name DOCKER_HUB=the_docker_hub_the_images_are_pushed_to DOCKER_REPO=your_docker_repo_here BUILD_NUMBER=<some_integer> make images_remove
Makefile targets#
最も重要なターゲットは以下の通りです:
images_build
: 環境変数を指定すると、画像をビルドしてタグを付けて公開します。images_publish
: ビルドされた画像をDockerリポジトリにプッシュします。images_start
: テストなどのためにイメージを開始します。images_test
:イメージに対して基本的なテストを実行します。images_remove
:ビルド環境変数が与えられると、以前にビルドされたイメージを削除します。
ベースイメージの新リリースをビルドするワークフロー例#
ビルドプロセスにはいくつかのステップがあります。これらのほとんどは、様々なベースイメージ間で共有されています。これらは主に上記で説明したMakefileターゲットに対応しています。
- Docker Login - Dockerのユーザー名、パスワード、HarborのURLがDockerクライアントに渡されます。
- Docker Build -
make images_build
ステップが現在実行されます。これにより以下のことが行われます:- すべての環境変数がビルドのために準備されていることを確認します。
docker-compose build
を実行します。これにより、現在のGitブランチからいくつかの新しいDockerイメージが生成されます。
- Image Test - これにより
make images_test
ターゲットが実行されます。これはテストされるイメージにより異なります。ほとんどの場合、これはイメージを開始し、何らかの方法で対話できることを確認する非常に直感的なテストです(Drupalのインストール、ファイルのリスト表示など)。 - Docker Push - このステップでは、
images_publish
のmakeターゲットに含まれるロジックが実行され、その結果として生成されたイメージにタグが付けられます。 ステップ2のDocker BuildでそれらをHarborにプッシュします。これについては、本ガイドの他の場所で詳しく説明されています。 - Docker Clean Images -
images_remove
というmakeターゲットを実行し、これらがHarborにあるため、新しくビルドされたイメージをDockerホストから単純に削除します。
ベースイメージの新バージョンのリリース#
ベースイメージの新バージョンをリリースする理由は多々あります。DrupalやLaravel、Node.jsなどのイメージでは、機能やセキュリティのためにモジュールやパッケージをアップグレードまたはインストールするかもしれません。また、コンテナにバンドルされている基本ソフトウェアのバージョンを更新することもあります。例えば、PHPやNode.jsのバージョンを更新するなどです。また、ベースイメージがビルドされている実際の基本的なイメージを更新することもあります。
あなたのプロジェクトのベースとなるイメージは、Lagoonチームによって管理されているイメージです。これらのベースイメージは月に一回(またはそれ以上)の頻度で更新されます。これらが更新されたとき、あなたはアップストリームのイメージにバンドルされている変更とアップグレードを取り入れるために、自分自身のベースイメージの新バージョンをビルドする必要があります。
このセクションでは、そのプロセスを示します。 Drupal8のベースイメージの新リリースを更新およびタグ付けします。我々は新しいモジュール(ClamAV)を基に追加します。Drupalでデモを行うのは、ベースイメージの中で最も設定が複雑だからです。すべてのベースイメージに共通する手順を以下に記載します。
ステップ1 - ベースイメージをローカルにダウンロードする#
これは単にGitリポジトリをローカルにダウンロードすることです。Drupal8のベースイメージの場合では、Bitbucketを使用しているので次のコマンドを実行します:
ステップ2 - リポジトリに変更を加える#
情報
ここで示されていることはDrupal 8のベースイメージに特有のものです。しかし、あらゆる変更(ファイルの追加、基本的なDockerイメージの変更など)はすべてのベースイメージに対してこのステップで行われます。
我々の例では、ClamAVモジュールをDrupal 8のベースイメージに追加しています。これにはいくつかのステップが関与します。最初はパッケージを必要とすることで、これにより我々のcomposer.json
ファイルに追加されます。これはcomposer require
を実行することで行われます。
次のコマンドを実行します:
Composer requireのプロセスが完了すると、パッケージはcomposer.json
ファイルに表示されるべきです。
ここでは、composer.json
ファイルを開き、必要なパッケージのリストを見て、ClamAVパッケージがリストされていることを確認します。
ステップ2.2 - テンプレートベースの派生イメージで必要なDrupalモジュールが有効になっていることを確認する#
ベースイメージに追加された任意のモジュールは、テンプレートベースの派生イメージで有効にする必要があります。これは、モジュールをLagoon Bundleモジュールに追加することで行われます。これは具体的には、dependencies
セクションのlagoon_bundle.info.yml
ファイルに依存性として追加することを要求します。Lagoon Bundleモジュールは、派生イメージ間の依存関係を強制するためだけに存在するユーティリティモジュールです。
ここでは、web/modules/contrib/lagoon/lagoon_bundle/lagoon_bundle.info.yml
を開き、依存関係としてclamav:clamav
を追加します。
これに依存関係を追加することで、派生したイメージ上でLagoon Bundleモジュールが有効になるたびに、その依存関係(この場合、新たに追加されたClamAVモジュール)も有効になります。これは、ロールアウト時にlagoon_bundle
を派生イメージで有効にするポストロールアウトスクリプトで強制されます。
ステップ2.3 - テスト#
これはあなたが何をテストしているかによります。ClamAVモジュールを追加する場合、ベースイメージでモジュールがダウンロードされ、Lagoon Bundleモジュールが有効化されたときにClamAVも有効化されることを確認したいです。
ここでは、モジュールが/app/web/modules/contrib
にダウンロードされたことを確認します。
そして、lagoon_bundle
モジュールを有効化するときに、clamav
も有効化されることを確認するために、以下のコマンドを実行します。
警告
上記のコンテナでJWTエラーが発生していることが分かるでしょう。上のデモではこのエラーは無視してかまいません。背景として、あなたが作業しているサイトにLagoon環境が存在しない場合、このエラーが表示されます。
テストが終了したので、イメージをタグ付けしてビルドすることができます。
ステップ3 - イメージのタグ付け#
イメージは、Gitタグに基づいてバージョン管理されます - これらは標準的なセマンティックバージョニング(semver)のプラクティスに従うべきです。すべてのタグは vX.Y.Z の構造を持つべきであり、X、Y、Zは整数です(正確にはX.Y.Z自体がセマンティックバージョンであり、vX.Y.Zはタグです)。これはイメージタグを決定するために使用されるので必ず従う必要があります。
この例では、ClamAVを追加したことを示すDrupal8のベースイメージの新しいバージョンをタグ付けします。
ここでは、イメージのタグ付け方法を示します#
私たちは、git log
を使用して、通常のコミットやプッシュと同じように、変更をコミット(しかしプッシュはしない)したことを確認します。
- まだ変更をコミットしていなければ、コミットします。
- 次に、
git tag
を使用して、どのタグにいるのかを確認します。 - 次に、
git tag -a v0.0.9 -m “Adds clamAV to base.”
を使用してタグ付けします。- _git -a, --annotateを使うと 無署名の注釈付きタグオブジェクトを作成します。
- 次に、
git push --tags
でタグをプッシュします。 - 最後に、
git push
で全ての変更をプッシュします。
危険
タグはそれ自体のステップで明示的にプッシュしなければなりません!
Gitのタグがイメージのタグにどのようにマッピングされるか#
危険
ビルドワークフローによりますが、ほぼ確実にdevelopブランチ経由で変更をプッシュし、それをmainブランチにマージするでしょう。
ここで覚えておくべき重要な点は、Jenkinsのベースイメージのビルドプロセスは、最新のコミットタグに基づいてイメージをタグ付けするということです。
イメージは以下のルールでタグ付けされ、これに該当するものごとにイメージがビルドされます:
- mainブランチがビルドされると、
latest
としてタグ付けされます。 - developブランチがビルドされると、
development
としてタグ付けされます。 - ビルドされるコミットがタグ付けされていれば、そのブランチはそのコミットのタグ付けでビルドされます。
- 上で示したように、これが新しいバージョンをリリースする方法です。また、任意のタグでアドホックなビルドを行うためにも使用できます。タグ名には十分注意してください。これらはセマンティックバージョニングのタグでのみテストされています。
ステップ4 - 新しいベースイメージのビルド#
情報
一般的には、自動ビルドのためのトリガーストラテジーをここに設定することになりますが、それはあなたのニーズや設定によって異なるため、ここでは手動でビルドする方法を説明します。
- あなたのLagoon Jenkinsインスタンスにアクセスします。
- 作業中のプロジェクト(この場合、AIOBI Drupal 8 Base)を選択します。
- ビルドしたいブランチをクリックします。
- 「Build Now」をクリックします。
これにより、ビルドプロセスが開始され、成功すれば新しいイメージをHarborにプッシュします。
ビルドが成功しない場合は、ビルド自体をクリックしてログを読み、どこで失敗したかを理解することができます。
下のHarborからのスクリーンショットで示されているように、私たちがJenkinsでビルドしたばかりのイメージはHarborにアップロードされ、タグ付けされています。ここでは、それがv0.0.9とタグ付けされているため、そのタグのついたイメージが存在します。また、私たちはmainブランチをビルドしたので、「latest」イメージもビルドされました。この段階では、v0.0.9と「latest」イメージは同一です。
謝辞#
ベースイメージの構造は、実際には、 Denpalのフォークです。これは元のDrupal Composer Templateに基づいていますが、Lagoon(ローカル開発環境またはホストされたLagoon)で実行するために必要なすべてを含んでいます。