サーバレスのサムネイル

サーバレス

Gitlab Registryを使ってGitlab pagesでpipeline時間を短縮・節約する

公開日: 2019.11.1

Gitlab pagesでSPAアプリをホスティングするのに、Gitlab CI/CDの毎回のビルドが時間がかかって、割り当てをモリモリ使ってしまうので、独自dockerイメージを作ってビルド時間を短縮し、割り当てを節約する方法を試してみました。

編集ノート:SERVERSUSでは、パートナーリンクからコミッションを得ています。コミッションが記事の意見や、サービスの評価に影響を与えることはありません。

はじめに

Gitlab pagesとGitlab CI/CDってなにが違うの?というかたは、まずこちらの記事を読んでいただくと、下記の記事をより理解できるかと思いますので、ぜひどうぞ。

Gitlab CI/CDのビルドが遅い理由

これは単純で、レポジトリにpushされる度に、全てのスクリプトを実行しているからです。つまり、多くのケースでGitlab側の問題でなく、自分が書いた設定(.gitlab-ci.yml)が適切でないということがほとんどでしょう。

同じ静的サイト向けサービスでも、Netlifyはログを見る限りキャッシュできるところはNetlify側が勝手にキャッシュしてくれています。同じ感覚でGitlab pagesで静的サイトをホスティングしようとすると、Pipeline quota(Pipelineの割り当て/無料ユーザーは月間2,000分)をモリモリ使ってしまいます。

ちなみに、Gitlab pagesでもNetlifyと同じようにキャッシュを使うことができます。

Gitlab CI cache

キャッシュを利用したビルド時間の短縮については、下記の記事をどうぞ。

サンプルアプリ

  • Vue.jsのSPAアプリ
  • パッケージマネージャーはYarn

という感じです。

node.jsコンテナを使った場合

Gitlabレポジトリに下記の.gitlab-ci.ymlを追加するだけで自動的にビルド&デプロイしてくれます。

image: node:latest
pages:
  stage: deploy
  only:
    - master
  before_script:
    - 'yarn config set cache-folder .yarn'
    - 'yarn install'
  script:
    - 'yarn build'
    - 'cp -pr dist public'
  artifacts:
    paths:
      - public

やってることは、

  • node.jsの公式コンテナイメージをpullしてコンテナ作成
  • Yarnをインストールして
  • yarn installで必要なモジュールをインストール
  • 最後にyarn buildでアプリをビルドして
  • artifactsでGitlab pagesへリリース

という感じです。

このやり方だと

  • 毎回yarnのインストールをしているのがまず無駄
  • パッケージ内容に変更がなくても、毎回yarn installでパッケージインストールを行うのも無駄

と無駄なことが多めで、ビルド&デプロイ時間も長めになります。

ビルド&デプロイ時間:00:04:11

独自コンテナ

続いては、yarn installの部分を内包したオリジナルコンテナを作成するケースです。

Dockerの知識が必要になりますが、Dockerfileさえ用意できれば簡単です。

独自コンテナイメージ用のDockerfileを作成する

まずは、Gitlabで使うオリジナルコンテナイメージを作成します。

Dockerがローカルマシンに入っている状態で、Vue.jsアプリのプロジェクトルートに、Dockerfileを作成します。

FROM node:12.6-alpine

WORKDIR /app

RUN apk update && \
    apk add git && \
    apk add --no-cache curl && \
    curl -o- -L https://yarnpkg.com/install.sh | sh

ENV PATH $HOME/.yarn/bin:$HOME/.config/yarn/global/node_modules/.bin:$PATH
ADD package.json .
RUN yarn install
CMD ["sh"]

今回は、Vue.jsアプリのなので、node.js用の公式イメージでも軽量のAlpline Linuxをベースに、

  • Yarnをインストール
  • プロジェクトディレクトリからpackage.jsonをコンテナに追加
  • yarn installコマンドを実行

という感じで処理を追加しています。

これで、構築したVue.jsアプリに必要なnode_modulesを、コンテナ内の/app/以下にインストールしてくれます。

dockerイメージのビルドとGitlab Registryへのデータ送信をする

Dockerfileができたら、dockerイメージをビルドをしてGitlab Registryにプッシュします。

まずはコマンドラインからGitlab Registryにログインします。

docker login registry.gitlab.com

ログインができたら、ビルドとGitlab Registryへのプッシュをします。

docker build -t registry.gitlab.com/ユーザー名/プロジェクト名 .
docker push registry.gitlab.com/ユーザー名/プロジェクト名

GitlabのプロジェクトページからPackage > Container Registryページを開いてdockerイメージがあることを確認します。

.gitlab-ci.ymlを編集

先ほどの.gitlab-ci.ymlとほぼ同じなのですが、imageの部分を独自のものにします。

Gitlab Registry内のコンテナの指定方法は、

registry.gitlab.com/ユーザー名/プロジェクト名:タグ

になります。

.gitlab-ci.ymlは下記の通り。

image: registry.gitlab.com/ユーザー名/プロジェクト名:latest
pages:
  stage: deploy
  only:
    - dev
  before_script:
    - 'mkdir public && mv /app/node_modules .'
  script:
    - 'yarn build'
    - 'cp -pR dist/* ../../public'
  artifacts:
    paths:
      - public

imageの部分を変更して、先ほどのコンテナでビルドしたnode_modules(/app/node_modules)をプロジェクトディレクトリのルートに移動にしています。

変更したら自動的にpipelineがジョブを生成して、ビルド&デプロイがスタートするはずです。

ビルド&デプロイ時間:00:01:20

Yarnのインストールとパッケージのインストールがないため、かなりビルド&デプロイ時間を短縮できました。

結果 ビルド&デプロイ&リリース時間の比較

nodeコンテナ & yarn install独自コンテナ
デプロイ&ビルド時間00:04:1100:01:20

結果的に、1/3ほどに短縮することができました。

ただし、毎回ローカルでDocker build&pushをするのは手間なので、アプリのパッケージの追加・更新は少ないWebアプリに向いてますね。GatsbyJSやHUGOのような静的サイトジェネレータの場合は、かなり効果があるのではないでしょうか?


Gitlab Registryを使ってGitlab pagesでpipeline時間を節約する方法を見てきました。

Dockerの知識が少し必要なので、誰でも簡単に導入できるというわけではありませんが、Dockerが使える方にとっても、アリな方法ではないでしょうか。


価格は記載がある場合を除き、すべて税込みです。

関連キーワード

サーバレスの新着記事