GitLab CI/CDとは、リポジトリ直下に置いた.gitlab-ci.ymlにステージとジョブを書き、コミットやマージリクエストをきっかけにビルド・テスト・デプロイを自動で実行するGitLab標準の仕組みです。本記事では、パイプラインとRunnerの関係を押さえたうえで、build・test・deployの3ステージを組む設定例、rulesとworkflowでの実行条件、needsでの並列化、cacheとartifactsの使い分け、マスク変数、CI/CDコンポーネントの取り込み方までを、公式ドキュメントの該当箇所へのリンクつきで解説します。仕様と料金は2026年11月12日時点の公式情報です。
まとめ:GitLab CI/CDは.gitlab-ci.yml1枚でパイプラインを定義する仕組み
GitLab CI/CDは、GitLabに標準で入っているCI/CD機能です。別のサービスと連携しなくても、.gitlab-ci.ymlをpushした時点でパイプラインが作られ、GitLab Runnerがジョブを実行します。
書き方で押さえるべき設定は、次の4つです。共通設定はdefaultにまとめ、実行条件はonly・exceptではなくrulesで書きます。ブランチとマージリクエストで同じパイプラインが2本走らないようworkflow:rulesを入れ、待ち時間が気になったらneedsでステージ待ちを飛ばします。
GitLab.comのFreeプランで使えるのは月400分までです。GitLabでコードを管理しているなら第一候補にしてよく、GitHub中心の組織で分数の上限に毎月当たる場合は別の選択肢と比べます。
GitLab CI/CDとは:パイプライン・ステージ・ジョブ・Runnerの関係
パイプラインはstagesで順番を、jobsで作業内容を決める構造
GitLab CI/CDの入門ドキュメントは、パイプラインを「ステージとジョブでできている」と説明しています。ステージは実行の順番、ジョブは各ステージで行う作業です。典型的なステージはbuild・test・deployの3つで、同じステージのジョブは並列に、ステージ同士は前から順に実行されます。
1つのジョブが失敗すると、既定では後ろのステージへ進みません。テストが落ちたコミットがデプロイされないのは、この順番の仕組みによるものです。CI/CDという考え方そのもの、継続的インテグレーションとデリバリーの違いはCI/CDの仕組みとパイプライン構成で整理しています。
.gitlab-ci.ymlをpushするとRunnerがジョブを受け取り実行する流れ
パイプラインが作られるきっかけは、ブランチへのpush、マージリクエストの作成・更新、スケジュール、画面からの手動実行などです。GitLab本体は作ったジョブを待ち行列に入れるだけで、実際にコマンドを動かすのはGitLab Runnerという別のアプリケーションです。
GitLab.comではLinux・Windows・macOS向けのRunnerをGitLabが用意しているので、.gitlab-ci.ymlを置くだけで動きます。社内ネットワークのDBへ届かせたい、GPUが要るといった理由で自前のRunnerを立てる手順とexecutorの選び方はGitLab Runnerのexecutorの選び方と登録手順にまとめました。
GitLab.comの無料枠はFree月400分、Premiumは月1万分の計算分数
GitLab.comのホステッドRunnerの利用は計算分数で数えます。GitLabの料金ページに載っている月間の上限は次のとおりです。
| プラン | 月間の計算分数 | 料金(2026年11月時点) |
|---|---|---|
| Free | 400分 | 無料 |
| Premium | 10,000分 | 1ユーザー月29ドル(年払い) |
| Ultimate | 50,000分 | 個別見積もり |
追加の分数は1,000分あたり10ドルで買えます。計算分数のドキュメントによると、Linuxのsmallは実行時間がそのまま1倍、mediumは2倍で数えられます。10分のジョブをmediumで回すと20分の消費です。Freeで1回5分のパイプラインなら、月80回で上限に届きます。
.gitlab-ci.ymlの3ステージ例:stages・default・cacheの設定
build・test・deployの3段階の.gitlab-ci.yml全文と行別設定
Node.jsのWebアプリを例に、ビルド、テストとLintの並列実行、mainブランチだけのデプロイを1ファイルにまとめた設定です。キーワードの意味はCI/CD YAML構文リファレンスで確かめられます。
stages:
- build
- test
- deploy
default:
image: node:22
before_script:
- npm ci --cache .npm --prefer-offline
cache:
key:
files:
- package-lock.json
paths:
- .npm/
build-job:
stage: build
script:
- npm run build
artifacts:
paths:
- dist/
expire_in: 1 week
unit-test:
stage: test
script:
- npm test
lint:
stage: test
script:
- npm run lint
deploy-staging:
stage: deploy
script:
- ./scripts/deploy.sh staging
environment: staging
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
defaultに書いたイメージとnpmの準備は、全ジョブに適用される共通設定です。unit-testとlintは同じtestステージなので同時に走り、両方が成功したときだけdeployステージへ進みます。deploy-stagingはrulesの条件により、既定ブランチへのpushのときだけパイプラインに入ります。
stagesを省略したときの既定5ステージとstage未指定のジョブ
stagesを書かなかった場合、既定のステージは.pre・build・test・deploy・.postの5つです。stageを書き忘れたジョブはtestに入ります。
ビルドジョブでstage: buildを書き忘れると、テストと同時に走ってしまいます。成果物がまだ無い状態でテストが始まり、ファイルが見つからずに失敗する典型例です。小さな設定でもstagesを先頭に明示し、全ジョブにstageを書いておくと、読む側も順番を追えます。
グローバルのimage指定は非推奨、共通設定はdefaultにまとめる
imageやbefore_scriptをファイルの最上位に直接書く古い書き方は、非推奨キーワードの一覧に載っています。代わりにdefaultの下に書くのがいまの形式です。最上位に書けるのはdefault・include・stages・variables・workflowの5つに絞られます。
古い記事や社内の雛形をコピーした設定には、最上位のimageやcacheが残っていることがあります。今は動いても、将来のメジャー版で削除される可能性がある書き方なので、新しく書くファイルでは最初からdefaultに寄せてください。
rules・workflow・needsでジョブの実行条件と順番を制御する設定例
rulesは上から順に評価、only・exceptは非推奨のキーワード
ジョブをいつパイプラインに入れるかはrulesで決めます。rulesのドキュメントのとおり、ルールはパイプライン作成時に上から順に評価され、最初に一致した行で扱いが決まります。どの行にも一致しなければ、そのジョブはパイプラインに入りません。
e2e-test:
stage: test
script:
- npm run test:e2e
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
changes:
- src/**/*
deploy-production:
stage: deploy
script:
- ./scripts/deploy.sh production
environment: production
rules:
- if: $CI_COMMIT_TAG
when: manual
1つ目はマージリクエストでsrc配下が変わったときだけE2Eテストを走らせる設定、2つ目はタグを打ったときだけ本番デプロイを手動ボタンとして出す設定です。タグからリリースを自動作成する設定はGitLab Releaseの作り方で解説しています。whenを省いた場合の扱いは、on_successが既定です。onlyとexceptは非推奨になっており、公式はrulesへの置き換えを案内しています。環境ブランチごとにデプロイ先を変える組み方はGitLab Flowの環境ブランチの組み方が参考になります。
ブランチとMRの二重パイプラインをworkflow:rulesで止める設定
ジョブのrulesにpushとマージリクエストの両方の条件を並べると、マージリクエストを開いたブランチへのpushで、ブランチ用とMR用のパイプラインが2本同時に作られます。計算分数が2倍消えるうえ、結果も2つ並んで紛らわしくなります。
これを防ぐのが最上位のworkflow:rulesです。workflowキーワードのドキュメントにある切り替えの設定をそのまま先頭に置きます。
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
MRがあるブランチではMR用のパイプラインだけが走り、MRが無いブランチではブランチ用のパイプラインが走ります。注意したいのは、ブランチ名を表すCI_COMMIT_BRANCHがMR用のパイプラインでは空になる点です。MRのジョブでブランチ名が要るときはCI_MERGE_REQUEST_SOURCE_BRANCH_NAMEを使います。
needsでステージ待ちを飛ばす書き方と1ジョブ50件までの上限
ステージ単位の順番だと、フロントエンドのテストはバックエンドのビルドが終わるまで待たされます。needsで依存するジョブを名指しすれば、そのジョブが終わった時点で次へ進めます。
build-frontend:
stage: build
script:
- npm run build --workspace frontend
build-backend:
stage: build
script:
- go build ./...
test-frontend:
stage: test
needs: ["build-frontend"]
script:
- npm test --workspace frontend
test-backend:
stage: test
needs: ["build-backend"]
script:
- go test ./...
needsに並べられるジョブはGitLab.comで最大50件です。Self-Managedでは管理者がこの上限を変えられます。依存関係はパイプラインエディタの図でも確認できるので、ジョブが10本を超えたら図で見てからneedsを足すと、意図しない待ちを見落としません。
cache・artifacts・CI/CD変数の使い分けと秘密情報の安全な渡し方
依存パッケージはcache、ステージ間の成果物はartifactsに置く理由
どちらもファイルを次のジョブへ残す仕組みですが、キャッシュのドキュメントは役割をはっきり分けています。
| 項目 | cache | artifacts |
|---|---|---|
| 入れるもの | npmやpipで取得した依存パッケージ | ビルド結果やテストレポート |
| 保存場所 | Runnerのホスト(分散キャッシュならS3) | GitLab本体 |
| 取得の確実さ | 無いこともある前提で使う | 後続ジョブへ確実に渡る |
| 画面からのダウンロード | 不可 | 可 |
ビルドしたdist/をcacheで渡すと、別のRunnerに割り当てられたテストジョブからは見えないことがあります。後続が必ず使うものはartifactsに置いてください。cache:keyを書かないと全ジョブがdefaultという同じキーを共有するので、前の例のようにpackage-lock.jsonをキーにすると依存が変わったときだけ作り直されます。
APIトークンはマスク変数と保護変数で渡す、8文字以上の条件
デプロイ用のトークンやパスワードは.gitlab-ci.ymlに書かず、プロジェクトの「Settings」→「CI/CD」→「Variables」で登録します。登録にはMaintainer以上の権限が要ります。CI/CD変数のドキュメントにある設定の意味は次のとおりです。
- Protect variable:保護ブランチと保護タグで動くパイプラインだけに値を渡す
- Masked:ジョブログに値が出たとき伏せ字にする。1行でスペースを含まず、8文字以上の値に限る
- Masked and hidden:伏せ字に加え、保存後は画面でも値を再表示できなくする
本番用のトークンはProtectとMaskedの両方を付けます。Protectを付けないと、誰かが作業ブランチでechoを書き換えたジョブを流すだけで値に触れられるからです。公式もマスクは確実な防御ではないと注記しており、ログに出さない書き方と保護ブランチの運用を組み合わせて守ります。
定義済み変数CI_COMMIT_SHORT_SHAでコンテナイメージにタグを付ける例
GitLabは、ブランチ名やコミットのハッシュなどを自動で変数に入れてジョブへ渡します。定義済み変数の一覧から、コンテナイメージのビルドでよく使うものを組み合わせた例です。
docker-build:
stage: build
image: docker:27
services:
- docker:27-dind
variables:
DOCKER_TLS_CERTDIR: "/certs"
script:
- echo "$CI_REGISTRY_PASSWORD" | docker login -u "$CI_REGISTRY_USER" --password-stdin "$CI_REGISTRY"
- docker build -t "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA" .
- docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA"
CI_COMMIT_SHORT_SHAはコミットハッシュの先頭8文字、CI_REGISTRY_IMAGEはプロジェクトのコンテナレジストリのアドレスです。タグにハッシュを使うと、本番で動いているイメージがどのコミットか追えます。Docker-in-Dockerは特権コンテナを使うため、自前Runnerで動かす場合は専用のRunnerに分けてください。作ったイメージの脆弱性検査はDockerの脆弱性診断をCI/CDに組み込む手順で扱っています。
.gitlab-ci.ymlの検証とCI/CDコンポーネントによる設定の再利用
パイプラインエディタのValidateで構文誤りをpush前に見つける
インデントの1文字違いでもパイプラインは作られません。パイプラインエディタのドキュメントのとおり、左サイドバーの「Build」→「Pipeline editor」で開くと、編集中の構文が自動で検証されます。
- Validateタブの「Validate pipeline」:pushした場合にどのジョブが作られるかを試算する
- Visualizeタブ:ステージとneedsの依存を図で表示する
- Full configurationタブ:includeやextendsを展開した最終形を表示する
rulesを書き換えたときはValidateで、includeで部品を取り込んだときはFull configurationで確かめるのが確実です。エディタからのコミットはそのままパイプラインを起動するので、試すだけなら作業ブランチで開いてください。
include:componentでCI/CDカタログの部品を版指定で取り込む
複数のプロジェクトで同じジョブを書いているなら、CI/CDコンポーネントにまとめます。CI/CDコンポーネントのドキュメントは、コンポーネントを再利用できるパイプライン設定の単位と説明しており、CI/CDカタログで公開・検索できます。
include:
- component: $CI_SERVER_FQDN/my-org/security-components/[email protected]
inputs:
stage: build
@の後ろは版の指定です。~latestも書けますが、公式は互換性のない変更まで取り込む可能性があると注記しています。本番のパイプラインでは1.0.0のように版を固定し、上げるときはMRで差分を確認する運用にしてください。GitLab Pagesで静的サイトを公開するジョブの書き方はGitLab Pagesの.gitlab-ci.ymlでの公開手順にあります。
GitLab CI/CDを採用する条件と別のCIサービスを選ぶべき場面
GitLabでコードを管理するチームはGitLab CI/CDが第一候補
リポジトリがGitLabにあるなら、CIもGitLab CI/CDに揃えるのが素直です。MRの画面にテスト結果が並び、保護ブランチと保護変数で本番デプロイの権限まで同じ画面で管理できます。外部のCIサービスと連携するためのトークン発行やWebhookの設定は要りません。
Self-Managedで社外に出せないコードを扱う場合も、Runnerを社内に置けば閉じた環境でCIが完結します。GitLab本体の提供形態とCE・EEの違いはGitLabの構成要素と3つの提供形態で確認できます。
GitHub中心の組織や分数の上限超過が続く場合に見送る判断基準
次に当てはまるなら、GitLab CI/CDを新たに入れる前に他の選択肢と比べてください。
- コードの大半がGitHubにあり、GitLab CI/CDのためだけにミラーを作ろうとしている
- Freeの月400分を毎月使い切り、自前Runnerを保守する人手も無い
- 既存のJenkinsやGitHub Actionsのジョブが数百本あり、書き換えの工数が見積もれていない
1つ目は見送りです。GitHubのリポジトリならGitHub Actionsのほうが設定も権限管理も1か所で済み、書き方の対応はGitHubとGitLabの違いとActionsとの対応表で比べられます。2つ目は、Premiumの1万分か自前Runnerかを、CI/CDツール比較の無料枠と料金と並べて試算してから決めます。
3つ目のように移行の範囲が大きい場合や、パイプライン設計とRunnerの保守を社内で回せない場合は、一創のDevOps・CI/CD導入支援のように、移行計画と基盤の構築を外部に任せる形も検討してください。
よくある質問
GitLab CI/CDについて調べている方から多い質問に、2026年11月時点の公式情報をもとに回答します。
GitLab CI/CDは無料で使えますか?
使えます。GitLab.comのFreeプランでも、ホステッドRunnerを月400分まで利用できます。上限を超えると、追加の分数を1,000分あたり10ドルで買うか、自前のRunnerを登録してジョブを回すかのどちらかです。自前Runnerの利用は計算分数の計測対象ではないため、マシン代だけで動かせます。Self-Managed版のGitLabでは、Runnerを自分で用意する前提で分数の上限はありません。
.gitlab-ci.ymlはどこに置けばよいですか?
リポジトリのルートに.gitlab-ci.ymlという名前で置きます。ファイル名の先頭のドットを落とすとGitLabに認識されません。別の場所や名前にしたい場合は、プロジェクトの「Settings」→「CI/CD」の「General pipelines」でCI/CD設定ファイルのパスを変更できます。ファイルが長くなったらincludeで複数のファイルに分割できます。
GitLab CI/CDとGitHub Actionsの書き方は何が違いますか?
GitLabは1つの.gitlab-ci.ymlにステージとジョブを並べ、GitHub Actionsは.github/workflows/の下にワークフローを複数置きます。実行条件はGitLabがrules、GitHubがonとifです。ジョブ間の依存はGitLabのneedsとGitHubのneedsが対応し、共通部品はGitLabのCI/CDコンポーネント、GitHubの再利用可能ワークフローやアクションが受け持ちます。
パイプラインが作られず、ジョブが1つも表示されないのはなぜですか?
多いのはrulesとworkflow:rulesの条件にどれも一致していないケースです。どのルールにも一致しないジョブはパイプラインに入らず、全ジョブが外れるとパイプライン自体が作られません。YAMLの構文誤りでも同じ症状になります。パイプラインエディタのValidateで、そのブランチでどのジョブが作られるかを試算して確かめてください。
ジョブが「pending」のまま実行されないのはなぜですか?
ジョブを受け取れるRunnerがいない状態です。ジョブにtagsを書いたのに同じタグのRunnerが無い、自前Runnerが停止している、GitLab.comで計算分数を使い切った、といった原因が考えられます。プロジェクトの「Settings」→「CI/CD」→「Runners」で、使えるRunnerとそのタグを確認してください。タグの付け方とRunnerの登録手順はRunnerの記事で解説しています。
関連記事
- GitLabの使い方:プロジェクト作成からIssue・MR・CI/CDまでの手順【2026年10月】:プロジェクト作成からMRでパイプラインを動かすまでの画面操作をたどれます
- GitLab Runnerとは:executorの選び方と登録手順・config.tomlの設定例【2026年11月】:ジョブを動かす自前Runnerの登録とconfig.tomlの設定を確認できます
- GitHubとGitLabの違い|ActionsとGitLab CIの対応表・料金・セルフホスト比較:GitHub ActionsからGitLab CI/CDへ書き換えるときの対応表があります
- CI/CDとは:仕組み・パイプライン構成・GitHub Actionsの設定例と導入判断の基準を解説:CI/CDの考え方と導入判断から整理したいときの入口です
- CI/CDツール比較|主要11製品の無料枠・料金と選び方【2026年10月】:GitLab CI/CD以外のサービスと無料枠を比べられます