Docker executor
- プラン: Free、Premium、Ultimate
- 提供形態: GitLab.com、GitLab Self-Managed、GitLab Dedicated
GitLab Runnerは、Docker executorを使用してDockerイメージでジョブを実行します。
Docker executorを使用すると、次のことが可能になります:
- 各ジョブで同じビルド環境を維持する。
- イメージを使用してコマンドをローカルでテストする(CIサーバーでジョブを実行する必要はない)。
Docker executorはDocker Engineを使用して、個別の隔離されたコンテナ内で各ジョブを実行します。Docker Engineに接続するために、executorは以下を使用します:
.gitlab-ci.ymlで定義するイメージとサービス。config.tomlで定義する設定。
config.tomlでデフォルトのイメージを定義していないなら、RunnerとそのDocker executorを登録することはできません。.gitlab-ci.ymlで何も定義されていない場合、config.tomlで定義されているイメージを使用できます。.gitlab-ci.ymlでイメージが定義されている場合、それはconfig.tomlで定義されているイメージをオーバーライドします。
前提要件:
Docker executorのワークフロー
Docker executorは、Alpine LinuxをベースとするDockerイメージを使用します。このイメージには、準備、ジョブ実行前、およびジョブ実行後のステップを実行するためのツールが含まれています。特別なDockerイメージの定義を確認するには、GitLab Runnerリポジトリを参照してください。
Docker executorは、ジョブを複数のステップに分割します:
- Prepare(準備): サービスを作成して開始します。
- Pre-job(ジョブ実行前): クローン、キャッシュの復元、および前のステージからのアーティファクトのダウンロードを行います。特別なDockerイメージで実行されます。
- ジョブ: Runner用に設定したDockerイメージでビルドを実行します。
- Post-job(ジョブ実行後): キャッシュの作成、GitLabへのアーティファクトのアップロードを実行します。特別なDockerイメージで実行されます。
サポートされている設定
Docker executorは以下の設定をサポートしています。
Windows設定に関する既知のイシューと追加の要件については、Windowsコンテナを使用するを参照してください。
| Runnerがインストールされている場所: | executor: | コンテナの実行: |
|---|---|---|
| Windows | docker-windows | Windows |
| Windows | docker | Linux |
| Linux | docker | Linux |
| macOS | docker | Linux |
以下の設定はサポートnot(されていません):
| Runnerがインストールされている場所: | executor: | コンテナの実行: |
|---|---|---|
| Linux | docker-windows | Linux |
| Linux | docker | Windows |
| Linux | docker-windows | Windows |
| Windows | docker | Windows |
| Windows | docker-windows | Linux |
GitLab Runnerは、Docker Engine API v1.25を使用してDocker Engineと通信します。つまり、Linuxサーバーでサポートされる最小バージョンのDockerは1.13.0です。Windows Serverでは、Windows Serverのバージョンを識別するために、これよりも新しいバージョンが必要です。
Docker executorを使用する
Docker executorを使用するには、config.tomlでDockerをexecutorとして手動で定義するか、gitlab-runner register --executor "docker"コマンドを使用して自動的に定義します。
次に示すのは、Dockerをexecutorとして定義している設定例です。これらの値の詳細については、高度な設定を参照してください
concurrent = 4
[[runners]]
name = "myRunner"
url = "https://gitlab.com/ci"
token = "......"
executor = "docker"
[runners.docker]
tls_verify = true
image = "my.registry.tld:5000/alpine:latest"
privileged = false
disable_entrypoint_overwrite = false
oom_kill_disable = false
disable_cache = false
volumes = [
"/cache",
]
shm_size = 0
allowed_pull_policies = ["always", "if-not-present"]
allowed_images = ["my.registry.tld:5000/*:*"]
allowed_services = ["my.registry.tld:5000/*:*"]
[runners.docker.volume_driver_ops]
"size" = "50G"イメージとサービスを設定する
前提要件:
- ジョブが実行されるイメージには、オペレーティングシステムの
PATHに動作するShellが必要です。サポートされているShellは次のとおりです:- Linux:
shbash- PowerShell Core(
pwsh)。13.9で導入されました。
- Windows:
- PowerShell(
powershell) - PowerShell Core(
pwsh)。13.6で導入されました。
- PowerShell(
- Linux:
Docker executorを設定するには、.gitlab-ci.ymlとconfig.tomlでDockerイメージとサービスを定義します。
次のキーワードを使用します:
image: Runnerがジョブを実行するために使用するDockerイメージの名前。- ローカルDocker Engineのイメージ、またはDocker Hubの任意のイメージを入力します。詳細については、Dockerのドキュメントを参照してください。
- イメージのバージョンを定義するには、コロン(
:)を使用してタグを追加します。タグを指定しない場合、Dockerはこのバージョンとしてlatestを使用します。
services: 別のコンテナを作成し、imageにリンクする追加のイメージ。サービスの種類に関する詳細については、サービスを参照してください。
.gitlab-ci.ymlでイメージとサービスを定義する
Runnerがすべてのジョブに使用するイメージと、ビルド時に使用する一連のサービスを定義します。
次に例を示します:
image: ruby:3.3
services:
- postgres:9.3
before_script:
- bundle install
test:
script:
- bundle exec rake specジョブごとに異なるイメージとサービスを定義するには、次のようにします:
before_script:
- bundle install
test:3.3:
image: ruby:3.3
services:
- postgres:9.3
script:
- bundle exec rake spec
test:3.4:
image: ruby:3.4
services:
- postgres:9.4
script:
- bundle exec rake spec.gitlab-ci.ymlでimageを定義しない場合、Runnerはconfig.tomlで定義されたimageを使用します。
config.tomlでイメージとサービスを定義する
Runnerが実行するすべてのジョブにイメージとサービスを追加するには、config.tomlの[runners.docker]を更新します。
デフォルトの場合、.gitlab-ci.ymlで定義されているimageがDocker executorで使用されます。.gitlab-ci.ymlで定義していない場合、Runnerはconfig.tomlで定義されているイメージを使用します。
次に例を示します:
[runners.docker]
image = "ruby:3.3"
[[runners.docker.services]]
name = "mysql:latest"
alias = "db"
[[runners.docker.services]]
name = "redis:latest"
alias = "cache"この例では、テーブル構文の配列を使用しています。
プライベートレジストリのイメージを定義する
前提要件:
- プライベートレジストリのイメージにアクセスするには、GitLab Runnerを認証する必要があります。
プライベートレジストリのイメージを定義するには、.gitlab-ci.ymlでレジストリ名とイメージを指定します。
次に例を示します:
image: my.registry.tld:5000/namespace/image:tagこの例では、GitLab Runnerはレジストリmy.registry.tld:5000でイメージnamespace/image:tagを検索します。
ネットワーク設定
サービスをCI/CDジョブに接続するには、ネットワークを設定する必要があります。
ネットワークを設定するには、次のいずれかを実行します:
- (推奨)ジョブごとにネットワークを作成するようにRunnerを設定します。
- コンテナリンクを定義します。コンテナリンクは、Dockerのレガシー機能です。
ジョブごとにネットワークを作成する
ジョブごとにネットワークを作成するようにRunnerを設定できます。
このネットワーキングモードを有効にすると、Runnerはジョブごとにユーザー定義のDockerブリッジネットワークを作成して使用します。Docker環境変数は、コンテナ間で共有されません。ユーザー定義のブリッジネットワークの詳細については、Dockerのドキュメントを参照してください。
このネットワーキングモードを使用するには、config.tomlの機能フラグまたは環境変数でFF_NETWORK_PER_BUILDを有効にします。
network_modeは設定しないでください。
次に例を示します:
[[runners]]
(...)
executor = "docker"
environment = ["FF_NETWORK_PER_BUILD=1"]または:
[[runners]]
(...)
executor = "docker"
[runners.feature_flags]
FF_NETWORK_PER_BUILD = trueデフォルトのDockerアドレスプールを設定するには、dockerdでdefault-address-poolを使用します。CIDR範囲がネットワークですでに使用されている場合、Dockerネットワークは、ホスト上の他のネットワーク(他のDockerネットワークを含む)と競合する可能性があります。
この機能は、IPv6を有効にしてDockerデーモンが設定されている場合にのみ機能します。IPv6サポートを有効にするには、Docker設定でenable_ipv6をtrueに設定します。詳細については、Dockerのドキュメントを参照してください。
Runnerは、ジョブコンテナを解決するためにbuildエイリアスを使用します。
この機能を使用すると、Docker-in-Docker(
dind)サービスでDNSが正しく機能しない場合があります。この動作は、ネットワークを指定した場合に
dindコンテナがカスタムDNSエントリを継承しないという、Docker/Mobyの問題によるものです。回避策として、
dindサービスに対して、カスタムDNS設定を手動で指定してください。たとえば、カスタムDNSサーバーが1.1.1.1の場合、Dockerの内部DNSサービスである127.0.0.11を使用できます:services: - name: docker:dind command: [--dns=127.0.0.11, --dns=1.1.1.1]このアプローチでは、コンテナが同じネットワーク上のサービスを解決できるようになります。
Runnerがジョブごとにネットワークを作成する仕組み
ジョブが開始されると、Runnerは次の処理を行います:
- Dockerコマンド
docker network create <network>と同様に、ブリッジネットワークを作成します。 - サービスとコンテナをブリッジネットワークに接続します。
- ジョブの最後にネットワークを削除します。
ジョブを実行しているコンテナと、サービスを実行しているコンテナが、互いのホスト名とエイリアスを解決します。この機能はDockerによって提供されます。
コンテナリンクを使用してネットワークを設定する
DockerのレガシーコンテナリンクとデフォルトのDocker bridgeを使用して、ジョブコンテナをサービスにリンクするネットワークモードを設定できます。FF_NETWORK_PER_BUILDが有効になっていない場合、このネットワークモードがデフォルトです。
ネットワークを設定するには、config.tomlファイルでネットワーキングモードを指定します:
bridge: ブリッジネットワークを使用します。デフォルト。host: コンテナ内でホストのネットワークスタックを使用します。none: ネットワーキングなし。推奨されません。
次に例を示します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mode = "bridge"他のnetwork_mode値を使用すると、ビルドコンテナが接続する既存のDockerネットワークの名前として扱われます。
Dockerは名前の解決中にサービスコンテナのホスト名とエイリアスを使用して、コンテナ内の/etc/hostsファイルを更新します。ただし、サービスコンテナはコンテナ名を解決not(できません)。コンテナ名を解決するには、ジョブごとにネットワークを作成する必要があります。
リンクされたコンテナは、その環境変数を共有します。
作成されたネットワークのMTUを上書きする
OpenStackの仮想マシンなどの一部の環境では、カスタムMTUが必要です。Dockerデーモンは、docker.jsonのMTUに従いません(Mobyイシュー34981を参照)。Dockerデーモンが新しく作成されたネットワークに正しいMTUを使用できるようにするために、config.tomlでnetwork_mtuを有効な値に設定できます。上書きを有効にするには、FF_NETWORK_PER_BUILDも有効にする必要があります。
次の設定では、各ジョブ用に作成されたネットワークのMTUが1402に設定されます。この値は、特定の環境要件に合わせて調整してください。
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mtu = 1402
[runners.feature_flags]
FF_NETWORK_PER_BUILD = trueDockerイメージとサービスを制限する
Dockerイメージとサービスを制限するには、allowed_imagesおよびallowed_servicesパラメータでワイルドカードパターンを指定します。構文の詳細については、doublestarのドキュメントを参照してください。
たとえば、プライベートDockerレジストリのイメージのみを許可するには、次のようにします:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_images = ["my.registry.tld:5000/*:*"]
allowed_services = ["my.registry.tld:5000/*:*"]プライベートDockerレジストリのイメージのリストに制限するには、次のようにします:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_images = ["my.registry.tld:5000/ruby:*", "my.registry.tld:5000/node:*"]
allowed_services = ["postgres:9.4", "postgres:latest"]Kaliなどの特定のイメージを除外するには、次のようにします:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_images = ["**", "!*/kali*"]サービスホスト名にアクセスする
サービスホスト名にアクセスするには、.gitlab-ci.ymlでservicesにサービスを追加します。
たとえば、Wordpressインスタンスを使用してアプリケーションとのAPIインテグレーションをテストするには、tutum/wordpressをサービスイメージとして使用します:
services:
- tutum/wordpress:latestジョブの実行時にtutum/wordpressサービスが開始されます。ホスト名tutum__wordpressおよびtutum-wordpressの下のビルドコンテナからこのサービスにアクセスできます。
指定されたサービスエイリアスの他に、Runnerはサービスイメージの名前をエイリアスとしてサービスコンテナに割り当てます。これらのエイリアスはどれでも使用できます。
Runnerは以下のルールに従って、イメージ名に基づいてエイリアスを作成します:
:より後のすべての文字が削除されます。- 1番目のエイリアスでは、スラッシュ(
/)が2つのアンダースコア(__)に置き換えられます。 - 2番目のエイリアスでは、スラッシュ(
/)が1つのダッシュ(-)に置き換えられます。
プライベートサービスイメージを使用する場合、Runnerは指定されたポートをすべて削除し、ルールを適用します。サービスregistry.gitlab-wp.com:4999/tutum/wordpressの場合、ホスト名はregistry.gitlab-wp.com__tutum__wordpressおよびregistry.gitlab-wp.com-tutum-wordpressになります。
サービスを設定する
データベース名を変更する場合、またはアカウント名を設定する場合には、サービスに環境変数を定義します。
Runnerが変数を渡すときには、次のように渡されます:
- 変数はすべてのコンテナに渡されます。Runnerは、特定のコンテナに変数を渡すことができません。
- セキュア変数はビルドコンテナに渡されます。
設定変数の詳細については、対応するDocker Hubページで提供される各イメージのドキュメントを参照してください。
RAMにディレクトリをマウントする
tmpfsオプションを使用して、RAMにディレクトリをマウントできます。これにより、データベースなどのI/O関連の処理が多い場合にテストに必要な時間を短縮できます。
Runner設定でtmpfsオプションとservices_tmpfsオプションを使用する場合は、複数のパスをそれぞれ専用のオプションで指定できます。詳細については、Dockerのドキュメントを参照してください。
たとえば、公式のMySQLコンテナのデータディレクトリをRAMにマウントするには、config.tomlを設定します:
[runners.docker]
# For the main container
[runners.docker.tmpfs]
"/var/lib/mysql" = "rw,noexec"
# For services
[runners.docker.services_tmpfs]
"/var/lib/mysql" = "rw,noexec"サービスでディレクトリをビルドする
GitLab Runnerは、すべての共有サービスに/buildsディレクトリをマウントします。
さまざまなサービスの使用法の詳細については、以下を参照してください:
GitLab Runnerがサービスのヘルスチェックを実行する仕組み
サービスの開始後、GitLab Runnerはサービスが応答するまで待機します。Docker executorは、サービスコンテナで公開されているサービスポートへのTCP接続を開こうとします。
- GitLab 15.11以前では、最初に公開されたポートのみがチェックされます。
- GitLab 16.0以降では、最初に公開された20個のポートがチェックされます。
特定のポートでヘルスチェックを実行するには、HEALTHCHECK_TCP_PORTサービス変数を使用できます:
job:
services:
- name: mongo
variables:
HEALTHCHECK_TCP_PORT: "27017"これがどのように実装されているかを確認するには、ヘルスチェックのGoコマンドを使用します。
Dockerドライバーオペレーションを指定する
ビルドのボリュームを作成するときにDockerボリュームドライバーに渡す引数を指定します。たとえば、他のすべてのドライバー固有のオプションに加えて、これらの引数を使用して、各ビルドが実行されるスペースを制限できます。次の例は、各ビルドが消費できるスペースの制限が50 GBに設定されているconfig.tomlを示しています。
[runners.docker]
[runners.docker.volume_driver_ops]
"size" = "50G"ホストデバイスを使用する
GitLab Runnerホスト上のハードウェアデバイスを、ジョブを実行するコンテナに対して公開できます。このためには、Runnerのdevicesオプションとservices_devicesオプションを設定します。
- デバイスを
buildコンテナとヘルパーコンテナに公開するには、devicesオプションを使用します。 - デバイスをサービスコンテナに公開するには、
services_devicesオプションを使用します。サービスコンテナのデバイスアクセスを特定のイメージに制限するには、正確なイメージ名またはglobパターンを使用します。このアクションにより、ホストシステムデバイスへの直接アクセスが防止されます。
デバイスアクセスの詳細については、Dockerのドキュメントを参照してください。
ビルドコンテナの例
この例では、config.tomlセクションで/dev/bus/usbをビルドコンテナに公開します。この設定により、パイプラインはホストマシンに接続されたUSBデバイス(Android Debug Bridge(adb)を介して制御されるAndroidスマートフォンなど)にアクセスできます。
ビルドジョブコンテナがホストUSBデバイスに直接アクセスできるため、同じハードウェアにアクセスすると、同時パイプライン実行が互いに競合する可能性があります。このような競合を防ぐには、resource_groupを使用します。
[[runners]]
name = "hardware-runner"
url = "https://gitlab.com"
token = "__REDACTED__"
executor = "docker"
[runners.docker]
# All job containers may access the host device
devices = ["/dev/bus/usb"]プライベートレジストリの例
この例は、プライベートDockerレジストリから/dev/kvmデバイスと/dev/driデバイスをコンテナイメージに公開する方法を示します。これらのデバイスは通常、ハードウェアアクセラレーションによる仮想化とレンダリングに使用されます。ハードウェアリソースへの直接アクセスをユーザーに付与することに伴うリスクを軽減するには、デバイスアクセスを、myregistry:5000/emulator/*ネームスペース内の信頼できるイメージに制限します:
[runners.docker]
[runners.docker.services_devices]
# Only images from an internal registry may access the host devices
"myregistry:5000/emulator/*" = ["/dev/kvm", "/dev/dri"]イメージ名**/*は、任意のイメージにデバイスを公開する可能性があります。
コンテナのビルドとキャッシュ用のディレクトリを設定する
コンテナ内でデータが保存される場所を定義するには、config.tomlの[[runners]]セクションで/buildsディレクトリと/cacheディレクトリを設定します。
/cacheストレージパスを変更する場合は、パスを永続としてマークするために、config.tomlの[runners.docker]セクションでvolumes = ["/my/cache/"]にこのパスを定義する必要があります。
デフォルトでは、Docker executorは次のディレクトリにビルドとキャッシュを保存します:
- ビルド:
/builds/<namespace>/<project-name> - キャッシュ: コンテナ内の
/cache
Dockerキャッシュをクリアする
Runnerによって作成された未使用のコンテナとボリュームを削除するには、clear-docker-cacheを使用します。
オプションのリストを確認するには、helpオプションを指定してスクリプトを実行します:
clear-docker-cache helpデフォルトのオプションはprune-volumesです。これにより、未使用のコンテナ(ダングリングおよび未参照)とボリュームがすべて削除されます。
キャッシュストレージを効率的に管理するには、次の操作を行う必要があります:
cronを使用してclear-docker-cacheを定期的に実行します(たとえば週に1回)。- ディスクスペースを回収する際に、パフォーマンスのためにキャッシュに最近のコンテナをいくつか保持します。
どのオブジェクトが削除されるかはFILTER_FLAG環境変数によって制御されます。その使用例については、Docker imageプルーニングのドキュメントを参照してください。
Dockerビルドイメージをクリアする
DockerイメージはGitLab Runnerによってタグ付けされていないため、clear-docker-cacheスクリプトはDockerイメージを削除しません。
Dockerビルドイメージをクリアするには、次の手順に従います:
回収できるディスクスペースを確認します:
clear-docker-cache space Show docker disk usage ---------------------- TYPE TOTAL ACTIVE SIZE RECLAIMABLE Images 14 9 1.306GB 545.8MB (41%) Containers 19 18 115kB 0B (0%) Local Volumes 0 0 0B 0B Build Cache 0 0 0B 0B未使用のコンテナ、ネットワーク、イメージ(ダングリングおよび未参照)、およびタグ付けされていないボリュームをすべて削除するには、
docker system pruneを実行します。
永続ストレージ
Docker executorは、コンテナの実行時に永続ストレージを提供します。volumes =で定義されているすべてのディレクトリは、ビルド間で維持されます。
volumesディレクティブは、次の種類のストレージをサポートしています:
動的ストレージの場合は
<path>を使用します。<path>は、そのプロジェクトで同じ同時実行ジョブの後続の実行間で維持されます。runners.docker.cache_dirを設定しない場合、データはDockerボリュームに永続化されます。それ以外の場合は、ホスト上の設定されたディレクトリ(ビルドコンテナにマウントされている)に永続化されます。ボリュームベースの永続ストレージのボリューム名:
18.4.0バージョンより以前のGitLab Runnerの場合:
runner-<short-token>-project-<project-id>-concurrent-<concurrency-id>-cache-<md5-of-path>GitLab Runner 18.4.0:
runner-<runner-id-hash>-cache-<md5-of-path><protection>ボリューム名で人が判読できなくなったデータは、ボリュームのラベルに移動されます。
ホストベースの永続ストレージのホストディレクトリ:
- 18.4.0バージョンより以前のGitLab Runnerの場合:
<cache-dir>/runner-<short-token>-project-<project-id>-concurrent-<concurrency-id>/<md5-of-path> - GitLab Runner 18.4.0:
<cache-dir>/runner-<runner-id-hash>/<md5-of-path><protection>
各変数部の説明:
<short-token>: は、Runnerのトークンを短縮したものです(最初の8文字)。<project-id>: GitLabプロジェクトのID<concurrency-id>: Runnerのインデックス(同じプロジェクトのビルドを同時に実行しているすべてのRunnerのリストから)<md5-of-path>: コンテナ内のパスのMD5サム<runner-id-hash>: 次のデータのハッシュ:- Runnerのトークン
- RunnerのシステムID
<project-id><concurrency-id>
<protection>: 値は、保護ブランチのビルドでは空で、保護ブランチのビルドでは-protectedです<cache-dir>:runners.docker.cache_dirの設定
ホストにバインドされたストレージの場合は、
<host-path>:<path>[:<mode>]を使用します。GitLab Runnerは、ホストシステム上の<host-path>に<path>をバインドします。オプションの<mode>は、このストレージが読み取り専用であるか、読み取り/書き込み可能(デフォルト)であるかを指定します。
GitLab Runner 18.4.0では、動的ストレージのソースの命名(上記参照)は、Dockerボリュームベースとホストディレクトリベースの永続ストレージの両方で変更されました。18.4.0にアップグレードすると、GitLab Runnerは以前のRunnerバージョンからのキャッシュデータを無視し、新しいDockerボリュームまたは新しいホストディレクトリを介して、オンデマンドで新しい動的ストレージを作成します。
ホストバインドストレージ(<host-path>設定を使用)は、動的ストレージとは対照的に、影響を受けません。
ビルド用の永続ストレージ
/buildsディレクトリをホストにバインドされたストレージにすると、ビルドは/builds/<short-token>/<concurrent-id>/<namespace>/<project-name>に保存されます:
<short-token>は、Runnerのトークンの短縮バージョンです(最初の8文字)。<concurrent-id>は、プロジェクトのコンテキストで特定のRunnerのローカルジョブIDを識別する一意の番号です。
IPCモード
Docker executorでは、コンテナのIPCネームスペースを他の場所と共有できます。これはdocker run --ipcフラグにマップされます。IPC設定の詳細については、Dockerのドキュメントを参照してください。
特権モード
Docker executorは、ビルドコンテナのファインチューニングを可能にするさまざまなオプションをサポートしています。このようなオプションの1つがprivilegedモードです。
特権モードでDocker-in-Dockerを使用する
設定されたprivilegedフラグがビルドコンテナとすべてのサービスに渡されます。このフラグを使用すると、Docker-in-Dockerアプローチを使用できます。
まず、privilegedモードで実行するようにRunner(config.toml)を設定します:
[[runners]]
executor = "docker"
[runners.docker]
privileged = true次に、Docker-in-Dockerコンテナを使用するためのビルドスクリプト(.gitlab-ci.yml)を作成します:
image: docker:git
services:
- docker:dind
build:
script:
- docker build -t my-image .
- docker push my-image特権モードで実行されるコンテナには、セキュリティ上のリスクがあります。コンテナが特権モードで実行されている場合、コンテナセキュリティメカニズムを無効にし、ホストを特権エスカレーションに公開します。特権モードでコンテナを実行すると、コンテナのブレイクアウトが発生する可能性があります。詳細については、ランタイム特権とLinux機能に関するDockerドキュメントを参照してください。
次のようなエラーを回避するには、TLSを使用してDocker-in-Dockerを設定するか、またはTLSを無効にする必要があります:
Cannot connect to the Docker daemon at tcp://docker:2375. Is the docker daemon running?制限付き特権モードでルートレスDocker-in-Dockerを使用する
このバージョンではDocker-in-Dockerルートレスイメージのみを特権モードでサービスとして実行できます。
services_privilegedおよびallowed_privileged_services設定パラメータは、特権モードで実行できるコンテナを制限します。
制限付き特権モードでルートレスDocker-in-Dockerを使用するには、次の手順に従います:
config.tomlで、services_privilegedとallowed_privileged_servicesを使用するようにRunnerを設定します:[[runners]] executor = "docker" [runners.docker] services_privileged = true allowed_privileged_services = ["docker.io/library/docker:*-dind-rootless", "docker.io/library/docker:dind-rootless", "docker:*-dind-rootless", "docker:dind-rootless"].gitlab-ci.ymlで、Docker-in-Dockerルートなしコンテナを使用するようにビルドスクリプトを編集します:image: docker:git services: - docker:dind-rootless build: script: - docker build -t my-image . - docker push my-image
特権モードで実行できるのは、allowed_privileged_servicesにリストされているDocker-in-Dockerルートレスイメージのみです。ジョブとサービスのその他のコンテナはすべて、非特権モードで実行されます。
これらは非ルートとして実行されるため、Docker-in-DockerルートレスやBuildKitルートレスなどの特権モードのイメージとともに使用することは_ほぼ安全です_。
セキュリティの問題の詳細については、Docker executorのセキュリティリスクを参照してください。
Docker ENTRYPOINTを設定する
デフォルトの場合、Docker executorはDockerイメージのENTRYPOINTをオーバーライドしません。ジョブスクリプトを実行するコンテナを起動するために、shまたはbashをCOMMANDとして渡します。
ジョブを実行できるようにするには、そのDockerイメージが次の処理を行う必要があります:
shまたはbashとgrepを提供する。- 引数として
sh/bashが渡されるとShellを起動するENTRYPOINTを定義する。
Docker Executorは、次のコマンドと同等のコマンドでジョブのコンテナを実行します:
docker run <image> sh -c "echo 'It works!'" # or bashDockerイメージがこのメカニズムをサポートしていない場合は、プロジェクト設定で次のようにイメージのENTRYPOINTをオーバーライドできます:
# Equivalent of
# docker run --entrypoint "" <image> sh -c "echo 'It works!'"
image:
name: my-image
entrypoint: [""]詳細については、イメージのエントリポイントをオーバーライドするとDockerでのCMDとENTRYPOINTの相互作用の仕組みを参照してください。
ENTRYPOINTとしてのジョブスクリプト
ENTRYPOINTを使用して、カスタム環境またはセキュアモードでビルドスクリプトを実行するDockerイメージを作成できます。
たとえば、ビルドスクリプトを実行しないENTRYPOINTを使用するDockerイメージを作成できます。代わりにDockerイメージは、定義済みの一連のコマンドを実行して、ディレクトリからDockerイメージをビルドします。特権モードでビルドコンテナを実行し、Runnerのビルド環境を保護します。
新しいDockerfileを作成します:
FROM docker:dind ADD / /entrypoint.sh ENTRYPOINT ["/bin/sh", "/entrypoint.sh"]ENTRYPOINTとして使用されるbashスクリプト(entrypoint.sh)を作成します:#!/bin/sh dind docker daemon --host=unix:///var/run/docker.sock \ --host=tcp://0.0.0.0:2375 \ --storage-driver=vf & docker build -t "$BUILD_IMAGE" . docker push "$BUILD_IMAGE"イメージをDockerレジストリにプッシュします。
privilegedモードでDocker executorを実行します。config.tomlで次のように定義します:[[runners]] executor = "docker" [runners.docker] privileged = trueプロジェクトで次の
.gitlab-ci.ymlを使用します:variables: BUILD_IMAGE: my.image build: image: my/docker-build:image script: - Dummy Script
Podmanを使用してDockerコマンドを実行する
LinuxにGitLab Runnerがインストールされている場合、ジョブはPodmanを使用して、DockerをDocker executorのコンテナランタイムに置き換えることができます。
前提要件:
- Podman v4.2.0以降。
- Podmanをexecutorとして使用してサービスを実行するには、
FF_NETWORK_PER_BUILD機能フラグを有効にします。Dockerコンテナリンクはレガシー機能であり、Podmanではサポートされていません。ネットワークエイリアスを作成するサービスの場合、podman-pluginsパッケージをインストールする必要があります。
Podmanは、コンテナのDNSサーバーとしてaardvark-dnsを使用します。aardvark-dnsバージョン1.10.0以前は、CI/CDジョブでDNS解決の失敗が散発的に発生します。新しいバージョンがインストールされていることを確認してください。詳細については、GitHubイシュー389を参照してください。
LinuxホストにGitLab Runnerをインストールします。システムのパッケージマネージャーを使用してGitLab Runnerをインストールした場合、
gitlab-runnerユーザーが自動的に作成されます。GitLab Runnerを実行するユーザーとしてサインインします。これは、
pam_systemdを回避しない方法で行う必要があります。正しいユーザーでSSHを使用できます。これにより、このユーザーとしてsystemctlを実行できるようになります。システムが、ルートレスPodmanセットアップの前提要件を満たしていることを確認します。具体的には、
/etc/subuidおよび/etc/subgidにユーザーの正しいエントリがあることを確認します。LinuxホストにPodmanをインストールします。
Podmanソケットを有効にして起動します:
systemctl --user --now enable podman.socketPodmanソケットがリッスンしていることを検証します:
systemctl status --user podman.socketPodman APIへのアクセスに使用されている
Listenキーのソケット文字列をコピーします。GitLab Runnerユーザーがログアウトした後も、Podmanソケットが利用可能な状態であることを確認します:
sudo loginctl enable-linger gitlab-runnerGitLab Runnerの
config.tomlファイルを編集し、[runners.docker]セクションのhostエントリにソケット値を追加します。次に例を示します:[[runners]] name = "podman-test-runner-2025-06-07" url = "https://gitlab.com" token = "TOKEN" executor = "docker" [runners.docker] host = "unix:///run/user/1012/podman/podman.sock" tls_verify = false image = "quay.io/podman/stable" privileged = true
Podmanを使用してDockerfileからコンテナイメージをビルドする
次の例では、Podmanを使用してコンテナイメージをビルドし、このイメージをGitLabコンテナレジストリにプッシュします。
Runnerのconfig.tomlでデフォルトコンテナイメージがquay.io/podman/stableに設定されているため、CIジョブはそのイメージを使用して、含まれているコマンドを実行します。
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- podman login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
oci-container-build:
stage: build
script:
- podman build -t $IMAGE_TAG .
- podman push $IMAGE_TAG
when: manualBuildahを使用してDockerfileからコンテナイメージをビルドする
次の例は、Buildahを使用してコンテナイメージをビルドし、このイメージをGitLabコンテナレジストリにプッシュする方法を示しています。
image: quay.io/buildah/stable
variables:
IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG
before_script:
- buildah login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
oci-container-build:
stage: build
script:
- buildah bud -t $IMAGE_TAG .
- buildah push $IMAGE_TAG
when: manual既知の問題
Dockerとは異なり、PodmanはデフォルトでSELinuxポリシーを適用します。多くのパイプラインは問題なく実行されますが、ツールが一時ディレクトリを使用すると、SELinuxコンテキストの継承が原因で一部のパイプラインが失敗する場合があります。
たとえば、次のパイプラインはPodmanでは失敗します:
testing:
image: alpine:3.20
script:
- apk add --no-cache python3 py3-pip
- pip3 install --target $CI_PROJECT_DIR requests==2.28.2この失敗は、Pipが作業ディレクトリとして/tmpを使用することが原因で発生します。/tmpに作成されたファイルは、そのSELinuxコンテキストを継承し、コンテナがこれらのファイルを$CI_PROJECT_DIRに移動したときに変更できなくなります。
Solution:(解決策:)runners.dockerセクションの下のRunnerのconfig.tomlにあるボリュームに/tmpを追加します:
[[runners]]
[runners.docker]
volumes = ["/cache", "/tmp"]この追加により、マウントされたディレクトリ全体で一貫したSELinuxコンテキストが保証されます。
SELinuxのトラブルシューティング
その他のPodman/SELinuxの問題では、必要な設定の変更を特定するために、追加のトラブルシューティングが必要になる場合があります。
Podman Runnerの問題がSELinuxに関連しているかどうかをテストするには、次のディレクティブをRunnerのconfig.tomlのrunners.dockerセクションに一時的に追加します:
[[runners]]
[runners.docker]
security_opt = ["label:disable"]この追加により、コンテナでのSELinux適用が無効になります(これはDockerのデフォルトの動作です)。この設定は、セキュリティ上の影響がある可能性があるため、テスト目的でのみ使用し、永続的な解決策としては使用しないでください。
SELinux MCSの設定
SELinuxが一部の書き込み操作(既存のGitリポジトリの再初期化など)をブロックする場合は、Runnerによって起動されたすべてのコンテナでマルチカテゴリセキュリティ(MCS)を強制できます:
[[runners]]
[runners.docker]
security_opt = ["label=level:s0:c1000"]このオプションはSELinuxを無効にしませんが、コンテナのMCSレベルを設定します。このアプローチは、label:disableを使用するよりも安全です。
同じMCSカテゴリを使用する複数のコンテナは、そのカテゴリでタグ付けされた同じファイルにアクセスできます。
ジョブを実行するユーザーを指定する
デフォルトでは、Runnerはコンテナ内のrootユーザーとしてジョブを実行します。ジョブを実行する別の非rootユーザーを指定するには、DockerイメージのDockerfileでUSERディレクティブを使用します。
FROM amazonlinux
RUN ["yum", "install", "-y", "nginx"]
RUN ["useradd", "www"]
USER "www"
CMD ["/bin/bash"]そのDockerイメージを使用してジョブを実行すると、指定されたユーザーとして実行されます:
build:
image: my/docker-build:image
script:
- whoami # wwwRunnerがイメージをプルする方法を設定する
RunnerがレジストリからDockerイメージをプルする方法を定義するには、config.tomlでプルポリシーを設定します。1つのポリシー、ポリシーのリスト 、または特定のプルポリシーを許可できます。
pull_policyには次の値を使用します:
always: デフォルト。ローカルイメージが存在する場合でもイメージをプルします。このプルポリシーは、ディスク上にすでに存在するSHA256で指定されたイメージには適用されません。if-not-present: ローカルバージョンが存在しない場合にのみ、イメージをプルします。never: イメージをプルせずに、ローカルイメージのみを使用します。
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always" # available: always, if-not-present, neveralwaysプルポリシーを設定する
alwaysオプションはデフォルトで有効になっており、常にコンテナの作成前にプルを開始します。このオプションにより、イメージが最新の状態になり、ローカルイメージが存在する場合でも古いイメージの使用を回避できます。
このプルポリシーは、次の場合に使用します:
- Runnerが常に最新のイメージをプルする必要がある。
- Runnerが公開されており、オートスケール向けに設定されているか、またはGitLabインスタンスのインスタンスRunnerとして設定されている。
Runnerがローカルに保存されているイメージを使用する必要がある場合は、このポリシーをDo not use(使用しないでください)。
config.tomlでalwaysをpull policyとして設定します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always"if-not-presentプルポリシーを設定する
プルポリシーをif-not-presentに設定すると、Runnerは最初にローカルイメージが存在するかどうかを確認します。ローカルイメージがない場合、Runnerはレジストリからイメージをプルします。
if-not-presentポリシーは、次の場合に使用します:
- ローカルイメージを使用するが、ローカルイメージが存在しない場合はイメージをプルする。
- 負荷が高いイメージやほとんど更新されないイメージのイメージレイヤの差分をRunnerが分析する時間を短縮する。この場合、イメージの更新を強制的に実行するために、ローカルのDocker Engineストアから定期的に手動でイメージを削除する必要があります。
次の場合にはこのポリシーをDo not use(使用しないでください):
- Runnerを使用するさまざまなユーザーがプライベートイメージにアクセスできるインスタンスRunnerの場合。セキュリティの問題の詳細については、if-not-presentプルポリシーでのプライベートDockerイメージの使用をご覧ください。
- ジョブが頻繁に更新され、最新のイメージバージョンでジョブを実行する必要がある場合。これにより実現するネットワーク負荷の軽減の価値は、ローカルイメージを頻繁に削除する価値を上回る可能性があります。
config.tomlでif-not-presentポリシーを設定します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "if-not-present"neverプルポリシーを設定する
前提要件:
- ローカルイメージには、インストール済みのDocker Engineと、使用されているイメージのローカルコピーが含まれている必要があります。
プルポリシーをneverに設定すると、イメージのプルが無効になります。ユーザーはRunnerが実行されているDockerホストで、手動でプルされたイメージのみを使用できます。
次の場合にneverプルポリシーを使用します:
- Runnerユーザーが使用するイメージを制御する場合。
- レジストリで公開されていない特定のイメージのみを使用できるプロジェクト専用のプライベートRunnerの場合。
オートスケールされたDocker executorには、neverプルポリシーをDo not use(使用しないでください)。neverプルポリシーは、選択したクラウドプロバイダーに定義済みのクラウドインスタンスイメージを使用する場合にのみ使用できます。
config.tomlでneverポリシーを設定します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "never"複数のプルポリシーを設定する
プルが失敗した場合に実行する複数のプルポリシーをリストできます。Runnerは、プルが成功するか、リストされたポリシーがすべて処理されるまで、リストされた順にプルポリシーを処理します。たとえば、Runnerがalwaysプルポリシーを使用している場合にレジストリが利用できない場合は、2番目のプルポリシーとしてif-not-presentを追加できます。この設定により、RunnerはローカルにキャッシュされているDockerイメージを使用できます。
このプルポリシーのセキュリティへの影響について詳しくは、if-not-presentプルポリシーでのプライベートDockerイメージの使用を参照してください。
複数のプルポリシーを設定するには、config.tomlでプルポリシーをリストとして追加します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = ["always", "if-not-present"]Dockerプルポリシーを許可する
.gitlab-ci.ymlファイルでプルポリシーを指定できます。このポリシーは、CI/CDジョブがイメージをフェッチする方法を決定します。
.gitlab-ci.ymlファイルで指定されているものの中から使用できるプルポリシーを制限するには、allowed_pull_policiesを使用します。
たとえば、alwaysおよびif-not-presentプルポリシーのみを許可するには、それらをconfig.tomlに追加します:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
allowed_pull_policies = ["always", "if-not-present"]allowed_pull_policiesを指定しない場合、リストはpull_policyキーワードで指定された値と一致します。pull_policyを指定しない場合、デフォルトはalwaysです。pull_policyとallowed_pull_policiesの両方に含まれているプルポリシーだけがジョブによって使用されます。有効なプルポリシーは、pull_policyキーワードで指定されているポリシーをallowed_pull_policiesと比較することによって決定されます。GitLabでは、これら2つのポリシーリストの共通部分が使用されます。たとえば、pull_policyが["always", "if-not-present"]、allowed_pull_policiesが["if-not-present"]の場合、ジョブでは、両方のリストで定義されている唯一のプルポリシーであるif-not-presentだけが使用されます。- 既存の
pull_policyキーワードには、allowed_pull_policiesで指定されているプルポリシーが少なくとも1つ含まれている必要があります。pull_policyの値の中にallowed_pull_policiesと一致するものがない場合、ジョブは失敗します。
イメージのプルエラーメッセージ
| エラーメッセージ | 説明 |
|---|---|
Pulling docker image registry.tld/my/image:latest ... ERROR: Build failed: Error: image registry.tld/my/image:latest not found | Runnerはイメージを見つけることができません。alwaysプルポリシーが設定されている場合に表示されます。 |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found | イメージがローカルでビルドされており、パブリックまたはデフォルトのDockerレジストリに存在していません。alwaysプルポリシーが設定されている場合に表示されます。 |
Pulling docker image registry.tld/my/image:latest ... WARNING: Cannot pull the latest version of image registry.tld/my/image:latest : Error: image registry.tld/my/image:latest not found WARNING: Locally found image will be used instead. | Runnerは、イメージをプルする代わりに、ローカルイメージを使用しました。 |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found | イメージをローカルで見つけることができません。neverプルポリシーが設定されている場合に表示されます。 |
WARNING: Failed to pull image with policy "always": Error response from daemon: received unexpected HTTP status: 502 Bad Gateway (docker.go:143:0s) Attempt #2: Trying "if-not-present" pull policy Using locally found image version due to "if-not-present" pull policy | Runnerはイメージのプルに失敗し、次にリストされているプルポリシーを使用してイメージのプルを試行します。複数のプルポリシーが設定されている場合に表示されます。 |
失敗したプルを再試行する
失敗したイメージのプルを再試行するようにRunnerを設定するには、config.tomlで同じポリシーを複数回指定します。
たとえば次の設定では、プルを1回再試行します:
[runners.docker]
pull_policy = ["always", "always"]この設定は、個々のプロジェクトの.gitlab-ci.ymlファイルのretryディレクティブと似ていますが、Dockerのプルが最初に失敗した場合にのみ有効になります。
Windowsコンテナを使用する
Docker executorでWindowsコンテナを使用するには、制限事項、サポートされているWindowsバージョン、およびWindows Docker executorの設定に関する次の情報に注意してください。
Nanoserverのサポート
Windowsヘルパーイメージで導入されたPowerShell Coreのサポートにより、ヘルパーイメージのnanoserverバリアントを利用できるようになりました。
Windows上のDocker executorに関する既知のイシュー
以下は、Docker executorでWindowsコンテナを使用する場合の制限事項の一部です:
Docker-in-DockerはDocker自体でサポートされていないため、サポートされていません。
インタラクティブWebターミナルはサポートされていません。
ホストデバイスのマウントはサポートされていません。
ボリュームディレクトリをマウントする場合、ディレクトリが存在している必要があります。そうでない場合、Dockerはコンテナを起動できません。詳細については、#3754を参照してください。
docker-windowsexecutorは、Windowsで実行されているGitLab Runnerのみを使用して実行できます。Windows上のLinuxコンテナはまだ実験的機能であるため、サポートされていません。詳細については、関連するイシューを確認してください。
Dockerでの制限により、宛先パスのドライブ文字が
c:ではない場合、以下ではパスがサポートされません:つまり、
f:\\cache_dirなどの値はサポートされていませんが、f:はサポートされています。ただし、宛先パスがc:ドライブ上にある場合は、パスもサポートされます(c:\\cache_dirなど)。Dockerデーモンがイメージとコンテナを保持する場所を設定するには、Dockerデーモンの
daemon.jsonファイルでdata-rootパラメータを更新します。詳細については、設定ファイルを使用してDockerを設定するを参照してください。
サポートされているWindowsバージョン
GitLab Runnerは、Windowsのサポートライフサイクルに従う次のバージョンのWindowsのみをサポートします:
- Windows Server 2022 LTSC(21H2)
- Windows Server 2019 LTSC(1809)
将来のWindows Serverバージョンについては、将来のバージョンサポートポリシーがあります。
Dockerデーモンが実行されているOSバージョンに基づいたコンテナのみを実行できます。たとえば、次のWindows Server Coreイメージを使用できます:
mcr.microsoft.com/windows/servercore:ltsc2022mcr.microsoft.com/windows/servercore:ltsc2022-amd64mcr.microsoft.com/windows/servercore:1809mcr.microsoft.com/windows/servercore:1809-amd64mcr.microsoft.com/windows/servercore:ltsc2019
サポートされているDockerのバージョン
GitLab RunnerはDockerを使用して、実行されているWindows Serverのバージョンを検出します。したがって、GitLab Runnerを実行しているWindows Serverで、最新バージョンのDockerが実行されている必要があります。
GitLab Runnerで機能しない既知のDockerのバージョンはDocker 17.06です。DockerはWindows Serverのバージョンを識別しないため、次のエラーが発生します:
unsupported Windows Version: Windows Server Datacenterこの問題のトラブルシューティングの詳細については、こちらを参照してください。
Windows Docker executorを設定する
ソースディレクトリとしてc:\\cacheを指定してRunnerが登録されている場合に--docker-volumesまたはDOCKER_VOLUMES環境変数を渡すときの既知のイシューがあります。
Windowsを実行しているDocker executorの設定の例を次に示します。
[[runners]]
name = "windows-docker-2019"
url = "https://gitlab.com/"
token = "xxxxxxx"
executor = "docker-windows"
[runners.docker]
image = "mcr.microsoft.com/windows/servercore:1809_amd64"
volumes = ["c:\\cache"]Docker executorのその他の設定オプションについては、高度な設定セクションを参照してください。
サービス
ジョブごとにネットワークを有効にすることによって、サービスを使用することができます。
ネイティブステップRunnerインテグレーション
Docker executorは、step-runnerが提供するgRPC APIを使用してCI/CDステップをネイティブに実行することをサポートしています。
この実行モードを有効にするには、従来のscriptキーワードの代わりにrunキーワードを使用してCI/CDジョブを指定する必要があります。さらに、FF_USE_NATIVE_STEPS機能フラグを有効にする必要があります。この機能フラグは、ジョブレベルまたはパイプラインレベルで有効にできます。
step job:
stage: test
variables:
FF_USE_NATIVE_STEPS: true
image:
name: alpine:latest
run:
- name: step1
script: pwd
- name: step2
script: env
- name: step3
script: ls -Rlah ../既知の問題
GitLab 17.9以降では、ビルドイメージで
ca-certificatesパッケージがインストールされている必要があります。インストールされていないと、step-runnerがジョブで定義されているステップのプルに失敗します。たとえば、DebianベースのLinuxディストリビューションは、デフォルトではca-certificatesをインストールしません。17.9より前のGitLabバージョンでは、ビルドイメージで
$PATHにstep-runnerバイナリが含まれている必要があります。これを実現するには、次のいずれかを実行します:- 独自のカスタムビルドイメージを作成し、
step-runnerバイナリを含めます。 registry.gitlab.com/gitlab-org/step-runner:v0イメージに、ジョブの実行に必要な依存関係が含まれている場合は、このイメージを使用します。
- 独自のカスタムビルドイメージを作成し、
Dockerコンテナを実行するステップの実行は、従来の
scriptsと同じ設定パラメータと制約に従う必要があります。たとえば、Docker-in-Dockerを使用する必要があります。この実行モードでは、
Github Actionsの実行はサポートされていません。