Gitlab CI/CD && pagesがどのように動いているのかを確認してみた
公開日: 2019.11.1
静的サイトをビルド&デプロイ&ホスティングできるGitlab CI/CDとGitlab pagesがどのような仕組みになっているか、まとまっているサイトがなかったので調査してみました。
Gitlab CI/CDとGitlab pagesは別物
Gitlab pagesで静的サイトをホスティングするとなると、GatsbyJSやHugoなどの静的サイトジェネレータを使うことが多いので、ビルド&デプロイを担うGitlab CI/CDの部分も含めて、同じ文脈で解説されることが多いですが、厳密には、
- Gitlab CI/CD -> dockerコンテナを利用したビルド&デプロイサービス
- Gitlab pages -> 完成したレポジトリをホスティングするサービス
となります。
Gitlab CI/CDのビルドの流れ
まずは、Gitlab pagesのビルドの流れを確認しておきます。
以下は、Gitlab CI/CDのログですが、
Running with gitlab-runner 12.3.0 (a8a019e0)
on docker-auto-scale fa6cab46
Using Docker executor with image node:latest ...
Pulling docker image node:latest ...
Using docker image sha256:4ac0e187278933b7a0da55f06b837027a6c3fe67661f43058c76774cfdf311c0 for node:latest ...
Running on runner-fa6cab46-project-15061835-concurrent-0 via runner-fa6cab46-srm-1572587627-23359604...
Fetching changes with git depth set to 50...
Initialized empty Git repository in /builds/ユーザー名/プロジェクト名/.git/
Created fresh repository.
From https://gitlab.com/ユーザー名/プロジェクト名
* [new ref] refs/pipelines/92998241 -> refs/pipelines/92998241
* [new branch] dev -> origin/dev
Checking out e043404c as dev...
Skipping Git submodules setup
ログから推測すると、
- (1) 指定されたdockerコンテナイメージをpullする
- (2) Gitレポジトリを作成する
- (3) プロジェクトのGitレポジトリをクローンする
- (4) 一時的なブランチを作成してcheckout
- (5) Git submodulesを同期
- (6) 指定されたスクリプトを実行
という流れのようです。
ちなみに、(2)以降は、全てpullしたdockerコンテナ内で実行されています。
image(Dockerコンテナイメージ)はオリジナルのものも使える
Gitlab CI/CDでは、Gitlabのコンテナレジストリサービス・Gitlab Registryに登録したオリジナルコンテナを実行イメージに指定することも可能なので、予め必要なものをインストールしたオリジナルコンテナイメージをGitlab Registryにアップしておけば、ビルド時間を短縮できます。
Gitlab CI/CDとGitlab Registryの連携については下記の記事をどうぞ。
Gitlab Registryを使ってGitlab pagesでpipeline時間を短縮・節約する
Gitlab pagesでSPAアプリをホスティングするのに、Gitlab CI/CDの毎回のビルドが時間がかかって、割り当てをモリモリ使ってしまうので、独自dockerイメージを作ってビルド時間を短縮し、割り当てを節約する方法を試してみました。
レポジトリのディレクトリはdockerコンテナ内のどこに展開されるか?
ビルドログを見ていると、
Initialized empty Git repository in /builds/ユーザー名/プロジェクト名/.git/
と出てきてるので、ここにレポジトリの内容をcloneしているようです。
試しにscriptで一覧表示(ls -ld $PWD/*)を実行してみると、
ls -ld $PWD/*
drwxrwxrwx 4 root root 4096 Nov 1 06:34 /builds/ユーザー名/プロジェクト名/app
-rw-rw-rw- 1 root root 4918 Nov 1 06:34 /builds/ユーザー名/プロジェクト名/config.json
drwxrwxrwx 4 root root 4096 Nov 1 06:34 /builds/ユーザー名/プロジェクト名/content
drwxrwxrwx 3 root root 4096 Nov 1 06:34 /builds/ユーザー名/プロジェクト名/data
drwxrwxrwx 2 root root 4096 Nov 1 06:34 /builds/ユーザー名/プロジェクト名/i18n
となっているので、(2)でGitレポジトリを作成したあとは、「/builds/ユーザー名/プロジェクト名/」をworking directoryにしてscriptを実行しているようです。
scriptではdockerコンテナ内で出来ることを全て指定できる
.gitlab-ci.ymlで指定するscriptブロックは、指定したdockerコンテナ内でできることは全て実行できます。
また、scriptは連想配列で複数実行できますが、
- カレントディレクトリは初期で「/builds/ユーザー名/プロジェクト名/」
- ディレクトリ移動は維持される
というルールがあります。
後述のGitlab pages用のpublicディレクトリの生成や中身の移動などは、この点を留意してscriptで指定する必要があります。
Gitlab pagesの流れ
Gitlab pagesは特別なことはしていなくて、実は、出来上がったものをpublicディレクトリで公開してホスティングするだけのサービスです。
ですので、ビルド&デプロイが必要ない場合は、Gitlabに登録したレポジトリルートに、下記のような.gitlab-ci.ymlファイルを設置すれば、即時サイト構築完了です。
pages:
script:
- mkdir .public
- cp -r * .public
- mv .public public
artifacts:
paths:
- public
only:
- master
.gitlab-ci.yml for plain HTML websites | Gitlab
publicディレクトリの扱い
Gitlab pagesでは、レポジトリのルートディレクトリのpublicディレクトリを公開ディレクトリとして処理します。
例えば、下記のようにレポジトリのルートが公開ディレクトリになっていた場合は、
- index.html
- main.css
- title.png
.gitlab-ci.ymlのscriptで、publicディレクトリを作成&中身を移動する必要があります。
上記の.gitlab-ci.ymlでいうと、
script:
- mkdir .public
- cp -r * .public
- mv .public public
この部分です。
このscriptで、いきなりpublicディレクトリに移動させるのではなくて、
- .publicというディレクトリを作成
- カレントディレクトリの中身を.publicディレクトリにコピー
- .publicディレクトリをpublicディレクトリにリネーム
という面倒な作業をしてるのは、カレントディレクトリの中身をそれ自身にコピーさせることが出来ないから一時的に.publicという隠しディレクトリを使っているというだけです。
予めpublicというディレクトリでサイト内容を展開していれば、このscriptは必要ありません。
また、すでにプロジェクトにpublicディレクトリがある場合は、ビルドしたファイルをpublicディレクトリにコピーor移動させる必要があります。
リダイレクト&リライトはできない
通常のサーバーであれば、.htaccessなどでリダイレクトやリライト設定ができます。同じホスティングサービスでも、Netlifyでは_redirectsファイルを設置することで、擬似的に同じようなことができます。
しかし、Gitlab pagesは、このような機能が一切なく、公式ドキュメントにも「HTTP meta refreshを使え」と書いてあります。
SPAサイトなど、全てをドキュメントルートにリダイレクトする必要があるサイトでは、別途ファイルを設置するなど対応が必要です。
簡単にですが、Gitlab CI/CD && pagesの動きを見ていきました。
使い方次第でかなり使えるサーバーレスサービスなので、ぜひ試してみてください。
価格は記載がある場合を除き、すべて税込みです。
関連キーワード
サーバレスの新着記事
- サーバレスCloudflare R2の料金体系・無料枠まとめ 2024.8.21
- サーバレスCloudflare R2をCyberduckで使う方法 2024.7.31
- サーバレスAIの学習ボット・クローラーからサイトを守るメリットとブロックする方法 2024.7.19
- サーバレスCloudFlare Pagesのビルド環境の違い 2024.5.9
- サーバレスCloudflare D1の料金体系・無料枠まとめ 2024.3.25
- サーバレスCloudflare PagesでNuxt3のビルド時に「ENOENT: no such file or directory」エラーの対象方法 2024.3.21
- サーバレスGitlab CLIでpush時に「glab auth not found」となった際の対処方法 2024.3.19
- サーバレスCloudFlare Workers AIの料金体系・無料枠まとめ 2024.2.2