Docker executor
Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
GitLab Runner는 Docker 이미지에서 작업을 실행하기 위해 Docker executor를 사용합니다. Docker executor를 사용하면 다음을 할 수 있습니다: Docker executor는 Docker Engine을 사용하여 각 작업을 별도의 격리된 컨테이너에서 실행합니다.
GitLab Runner는 Docker 이미지에서 작업을 실행하기 위해 Docker executor를 사용합니다.
Docker executor를 사용하면 다음을 할 수 있습니다:
- 각 작업에 동일한 빌드 환경을 유지합니다.
- CI 서버에서 작업을 실행할 필요 없이 동일한 이미지를 사용하여 로컬에서 명령을 테스트합니다.
Docker executor는 Docker Engine을 사용하여 각 작업을 별도의 격리된 컨테이너에서 실행합니다. Docker Engine에 연결하기 위해 executor는 다음을 사용합니다:
.gitlab-ci.yml에서 정의한 이미지와 서비스.config.toml에서 정의한 구성.
config.toml에 기본 이미지를 정의하지 않으면 러너와 Docker executor를 등록할 수 없습니다.
config.toml에 정의된 이미지는 .gitlab-ci.yml에 정의된 이미지가 없을 때 사용될 수 있습니다.
.gitlab-ci.yml에 이미지가 정의되면 config.toml에 정의된 이미지를 재정의합니다.
사전 요구 사항:
- Docker를 설치합니다.
Docker executor 워크플로#
Docker executor는 prepare, pre-job, post-job 단계를 실행하는 도구를 포함한 Alpine Linux 기반 Docker 이미지를 사용합니다. 특수 Docker 이미지의 정의를 보려면 GitLab Runner 리포지터리를 참조하세요.
Docker executor는 작업을 여러 단계로 나눕니다:
- Prepare: 서비스를 생성하고 시작합니다.
- Pre-job: 복제, 캐시 복원 및 이전 단계에서 아티팩트를 다운로드합니다. 특수 Docker 이미지에서 실행됩니다.
- Job: 러너에 구성된 Docker 이미지에서 빌드를 실행합니다.
- Post-job: 캐시를 생성하고 GitLab에 아티팩트를 업로드합니다. 특수 Docker 이미지에서 실행됩니다.
지원되는 구성#
Docker executor는 다음 구성을 지원합니다.
Windows 구성의 알려진 이슈 및 추가 요구 사항은 Windows 컨테이너 사용을 참조하세요.
| 러너가 설치된 위치: | Executor: | 컨테이너 실행: |
|---|---|---|
| Windows | docker-windows |
Windows |
| Windows | docker |
Linux |
| Linux | docker |
Linux |
| macOS | docker |
Linux |
다음 구성은 지원되지 않습니다:
| 러너가 설치된 위치: | 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에 작동하는 셸이 있어야 합니다. 지원되는 셸:
Docker executor를 구성하려면 .gitlab-ci.yml과
config.toml에서 Docker 이미지와 서비스를 정의합니다.
다음 키워드를 사용합니다:
image: 러너가 작업을 실행하는 데 사용하는 Docker 이미지 이름.- 로컬 Docker Engine 또는 Docker Hub의 이미지를 입력합니다. 자세한 내용은 Docker 문서를 참조하세요.
- 이미지 버전을 정의하려면 콜론(
:)을 사용하여 태그를 추가합니다. 태그를 지정하지 않으면 Docker는latest를 버전으로 사용합니다.
services: 다른 컨테이너를 생성하고image에 링크하는 추가 이미지. 서비스 유형에 대한 자세한 내용은 서비스를 참조하세요.
.gitlab-ci.yml에서 이미지 및 서비스 정의#
러너가 모든 작업에 사용할 이미지와 빌드 시간에 사용할 서비스 목록을 정의합니다.
예시:
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를 정의하지 않으면 러너는 config.toml에 정의된 image를 사용합니다.
config.toml에서 이미지 및 서비스 정의#
러너가 실행하는 모든 작업에 이미지와 서비스를 추가하려면 config.toml의 [runners.docker]를 업데이트합니다.
기본적으로 Docker executor는 .gitlab-ci.yml에 정의된 image를 사용합니다. .gitlab-ci.yml에 정의하지 않으면 러너는 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 작업에 연결하려면 네트워크를 구성해야 합니다.
네트워크를 구성하려면 다음 중 하나를 선택할 수 있습니다:
- 권장. 각 작업에 대한 네트워크를 생성하도록 러너를 구성합니다.
- 컨테이너 링크를 정의합니다. 컨테이너 링크는 Docker의 레거시 기능입니다.
각 작업에 대한 네트워크 생성#
각 작업에 대한 네트워크를 생성하도록 러너를 구성할 수 있습니다.
이 네트워킹 모드를 활성화하면 러너는 각 작업에 대해 사용자 정의 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 네트워크를 포함하여 호스트의 다른 네트워크와 충돌할 수 있습니다.
이 기능은 Docker 데몬이 IPv6가 활성화된 상태로 구성된 경우에만 작동합니다.
IPv6 지원을 활성화하려면 Docker 구성에서 enable_ipv6을 true로 설정합니다.
자세한 내용은 Docker 문서를 참조하세요.
러너는 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]
이 방법은 컨테이너가 동일한 네트워크의 서비스를 확인할 수 있게 해줍니다.
러너가 각 작업에 대한 네트워크를 생성하는 방법#
작업이 시작되면 러너는:
docker network create <network>Docker 명령과 유사하게 브리지 네트워크를 생성합니다.- 서비스와 컨테이너를 브리지 네트워크에 연결합니다.
- 작업이 끝나면 네트워크를 제거합니다.
작업을 실행하는 컨테이너와 서비스를 실행하는 컨테이너는 서로의 호스트명과 별칭을 확인합니다. 이 기능은 Docker에서 제공합니다.
컨테이너 링크로 네트워크 구성#
GitLab Runner 18.7.0 이전에는 기본 Docker bridge와 레거시 컨테이너 링크를 사용하여 작업 컨테이너와 서비스를 연결했습니다. Docker가 링크 기능을 지원 중단했으므로, GitLab Runner 18.7.0 이상에서는 Docker의 extra_hosts 기능을 사용하여 서비스 별칭을 확인할 수 있도록 하여 레거시 컨테이너 링크 동작을 에뮬레이션합니다. 이 네트워크 모드는 FF_NETWORK_PER_BUILD가 비활성화된 경우 기본값입니다.
GitLab Runner 에뮬레이션된 링크 동작은 레거시 컨테이너 링크와 약간 다릅니다:
icc를 비활성화하면 컨테이너 간 통신이 비활성화되고 컨테이너가 서로 통신할 수 없습니다.- 링크된 컨테이너에 대한 환경 변수가 더 이상 없습니다(
<name>_PORT_<port>_<protocol>).
네트워크를 구성하려면 config.toml 파일에서 네트워킹 모드를 지정합니다:
bridge: 브리지 네트워크 사용. 기본값.host: 컨테이너 내부에서 호스트의 네트워크 스택 사용.none: 네트워킹 없음. 권장하지 않음.
예시:
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mode = "bridge"
다른 network_mode 값을 사용하면 빌드 컨테이너가 연결하는 이미 존재하는 Docker 네트워크의 이름으로 사용됩니다.
이름 확인 중에 Docker는 서비스 컨테이너 호스트명 및 별칭으로 컨테이너의 /etc/hosts 파일을 업데이트합니다. 그러나 서비스 컨테이너는 컨테이너 이름을 확인할 수 없습니다. 컨테이너 이름을 확인하려면 각 작업에 대한 네트워크를 생성해야 합니다.
링크된 컨테이너는 환경 변수를 공유합니다.
생성된 네트워크의 MTU 재정의#
OpenStack의 가상 머신과 같은 일부 환경에서는 사용자 정의 MTU가 필요합니다.
Docker 데몬은 docker.json의 MTU를 존중하지 않습니다(Moby 이슈 34981 참조).
config.toml의 network_mtu를 유효한 값으로 설정하면
Docker 데몬이 새로 생성된 네트워크에 올바른 MTU를 사용할 수 있습니다.
재정의가 적용되려면 FF_NETWORK_PER_BUILD도 활성화해야 합니다.
다음 구성은 각 작업에 대해 생성된 네트워크의 MTU를 1402로 설정합니다.
특정 환경 요구 사항에 맞게 값을 조정하세요.
[[runners]]
(...)
executor = "docker"
[runners.docker]
network_mtu = 1402
[runners.feature_flags]
FF_NETWORK_PER_BUILD = true
Docker 이미지 및 서비스 제한#
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에 서비스를 추가합니다.
services:
- valkey/valkey:latest
작업이 실행되면 valkey/valkey 서비스가 시작됩니다. 호스트명
valkey__valkey와 valkey-valkey로 빌드 컨테이너에서 접근할 수 있습니다.
지정된 서비스 별칭 외에도 러너는 서비스 이미지 이름을 서비스 컨테이너의 별칭으로 할당합니다. 이러한 별칭 중 하나를 사용할 수 있습니다.
러너는 이미지 이름을 기반으로 별칭을 생성하기 위해 다음 규칙을 사용합니다:
:이후의 모든 것은 제거됩니다.- 첫 번째 별칭의 경우 슬래시(
/)가 이중 밑줄(__)로 대체됩니다. - 두 번째 별칭의 경우 슬래시(
/)가 단일 대시(-)로 대체됩니다.
프라이빗 서비스 이미지를 사용하면 러너는 지정된 포트를 제거하고 규칙을 적용합니다.
서비스 registry.example.com:4999/valkey/valkey는 호스트명
registry.example.com__valkey__valkey와 registry.example.com-valkey-valkey를 만듭니다.
서비스 구성#
데이터베이스 이름을 변경하거나 계정 이름을 설정하려면 서비스의 환경 변수를 정의할 수 있습니다.
러너가 변수를 전달할 때:
- 변수는 모든 컨테이너에 전달됩니다. 러너는 특정 컨테이너에만 변수를 전달할 수 없습니다.
- 보안 변수는 빌드 컨테이너에 전달됩니다.
구성 변수에 대한 자세한 내용은 해당 Docker Hub 페이지에서 제공하는 각 이미지의 문서를 참조하세요.
RAM에 디렉터리 마운트#
tmpfs 옵션을 사용하여 RAM에 디렉터리를 마운트할 수 있습니다. 이렇게 하면 데이터베이스와 같이 많은 I/O 관련 작업이 있을 때 테스트 시간이 단축됩니다.
러너 구성에서 tmpfs와 services_tmpfs 옵션을 사용하면
각각 고유한 옵션이 있는 여러 경로를 지정할 수 있습니다. 자세한 내용은
Docker 문서를 참조하세요.
예를 들어, 공식 MySQL 컨테이너의 데이터 디렉터리를 RAM에 마운트하려면
config.toml을 구성합니다:
[runners.docker]
# 메인 컨테이너의 경우
[runners.docker.tmpfs]
"/var/lib/mysql" = "rw,noexec"
# 서비스의 경우
[runners.docker.services_tmpfs]
"/var/lib/mysql" = "rw,noexec"
서비스에서 디렉터리 빌드#
GitLab Runner는 /builds 디렉터리를 모든 공유 서비스에 마운트합니다.
다양한 서비스 사용에 대한 자세한 내용:
GitLab Runner가 서비스 상태 확인을 수행하는 방법#
히스토리
- GitLab 16.0에서 여러 포트 확인이 도입되었습니다.
서비스가 시작된 후 GitLab Runner는 서비스가 응답할 때까지 기다립니다. Docker executor는 서비스 컨테이너에서 노출된 서비스 포트에 TCP 연결을 열려고 합니다.
처음 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 17.10에서 도입.
GitLab Runner 호스트의 하드웨어 장치를 작업을 실행하는 컨테이너에 노출할 수 있습니다.
이를 위해 러너의 devices와 services_devices 옵션을 구성합니다.
build및 헬퍼 컨테이너에 장치를 노출하려면devices옵션을 사용합니다.- 서비스 컨테이너에 장치를 노출하려면
services_devices옵션을 사용합니다. 서비스 컨테이너의 장치 접근을 특정 이미지로 제한하려면 정확한 이미지 이름이나 glob 패턴을 사용합니다. 이 작업은 호스트 시스템 장치에 대한 직접 접근을 방지합니다.
장치 접근에 대한 자세한 내용은 Docker 문서를 참조하세요.
빌드 컨테이너 예시#
이 예제에서 config.toml 섹션은 /dev/bus/usb를 빌드 컨테이너에 노출합니다.
이 구성은 파이프라인이 Android Debug Bridge(adb)로
제어되는 Android 스마트폰과 같이 호스트 머신에 연결된 USB 장치에 접근할 수 있도록 합니다.
빌드 작업 컨테이너가 호스트 USB 장치에 직접 접근할 수 있으므로 동시 파이프라인 실행이 동일한 하드웨어에 접근할 때 서로 충돌할 수 있습니다. 이러한 충돌을 방지하려면 resource_group을 사용하세요.
[[runners]]
name = "hardware-runner"
url = "https://gitlab.com"
token = "__REDACTED__"
executor = "docker"
[runners.docker]
# 모든 작업 컨테이너가 호스트 장치에 접근할 수 있습니다
devices = ["/dev/bus/usb"]
프라이빗 레지스트리 예시#
이 예제는 프라이빗 Docker 레지스트리의 컨테이너 이미지에 /dev/kvm과 /dev/dri 장치를 노출하는 방법을 보여줍니다. 이 장치들은 하드웨어 가속 가상화 및 렌더링에 일반적으로 사용됩니다. 사용자가 하드웨어 리소스에 직접 접근하는 것과 관련된 위험을 완화하려면 myregistry:5000/emulator/* 네임스페이스의 신뢰할 수 있는 이미지로 장치 접근을 제한합니다:
[runners.docker]
[runners.docker.services_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 캐시 지우기#
러너가 생성한 사용하지 않는 컨테이너와 볼륨을 제거하려면
clear-docker-cache를 사용합니다.
옵션 목록을 보려면 help 옵션으로 스크립트를 실행합니다:
clear-docker-cache help
기본 옵션은 prune-volumes로, 모든 사용하지 않는 컨테이너(dangling 및 참조되지 않은 것)와
볼륨을 제거합니다.
캐시 스토리지를 효율적으로 관리하려면:
cron으로clear-docker-cache를 정기적으로 실행합니다(예: 주 1회).- 디스크 공간을 회수하면서 성능을 위해 캐시에 일부 최근 컨테이너를 유지합니다.
FILTER_FLAG 환경 변수는 정리할 객체를 제어합니다. 사용 예시는
Docker 이미지 정리 문서를 참조하세요.
Docker 빌드 이미지 지우기#
clear-docker-cache 스크립트는 GitLab Runner에 의해 태그가 지정되지 않으므로 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 -
사용하지 않는 모든 컨테이너, 네트워크, 이미지(dangling 및 참조되지 않은 것) 및 태그가 없는 볼륨을 제거하려면
docker system prune을 실행합니다.
영구 스토리지#
Docker executor는 컨테이너를 실행할 때 영구 스토리지를 제공합니다.
volumes =에 정의된 모든 디렉터리는 빌드 간에 영구적입니다.
volumes 지시문은 다음 유형의 스토리지를 지원합니다:
-
동적 스토리지의 경우
<path>를 사용합니다.<path>는 해당 프로젝트의 동일한 동시 작업의 후속 실행 간에 영구적입니다.runners.docker.cache_dir을 설정하지 않으면 데이터가 Docker 볼륨에 유지됩니다. 그렇지 않으면 호스트의 구성된 디렉터리(빌드 컨테이너에 마운트됨)에 유지됩니다.볼륨 기반 영구 스토리지의 볼륨 이름:
-
GitLab Runner 18.4.0 이전:
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>볼륨 이름에서 더 이상 사람이 읽을 수 없는 데이터는 볼륨의 레이블로 이동됩니다.
호스트 기반 영구 스토리지의 호스트 디렉터리:
- GitLab Runner 18.4.0 이전:
<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>: 러너 토큰의 단축 버전(처음 8글자)<project-id>: GitLab 프로젝트의 ID<concurrency-id>: 동일한 프로젝트에 대한 빌드를 동시에 실행하는 모든 러너 목록에서 러너의 인덱스(CI_CONCURRENT_PROJECT_ID사전 정의 변수로 접근 가능).<md5-of-path>: 컨테이너 내 경로의 MD5 합계<runner-id-hash>: 다음 데이터의 해시:- 러너의 토큰
- 러너의 시스템 ID
<project-id><concurrency-id>
<protection>: 보호되지 않은 브랜치의 빌드에는 값이 비어 있고 보호된 브랜치 빌드에는-protected<cache-dir>:runners.docker.cache_dir의 구성
-
-
호스트 바인딩 스토리지의 경우
<host-path>:<path>[:<mode>]를 사용합니다. GitLab Runner는 호스트 시스템에서<path>를<host-path>에 바인딩합니다. 선택적<mode>는 이 스토리지가 읽기 전용인지 읽기-쓰기(기본값)인지를 지정합니다.
GitLab Runner 18.4 이상에서는 동적 스토리지(위 참조)의 소스 이름이 Docker 볼륨 기반과 호스트 디렉터리 기반 영구 스토리지 모두 변경되었습니다. 18.4.0으로 업그레이드하면 GitLab Runner는 이전 러너 버전의 캐시된 데이터를 무시하고 새 Docker 볼륨 또는 새 호스트 디렉터리를 통해 온디맨드로 새 동적 스토리지를 생성합니다.
동적 스토리지와 달리 <host-path> 구성을 가진 호스트 바인딩 스토리지는
영향을 받지 않습니다.
빌드를 위한 영구 스토리지#
/builds 디렉터리를 호스트 바인딩 스토리지로 만들면 빌드가 다음에 저장됩니다:
/builds/<short-token>/<concurrent-id>/<namespace>/<project-name>, 여기서:
<short-token>은 러너 토큰의 단축 버전(처음 8글자)입니다.<concurrent-id>는 동일한 프로젝트에 대한 빌드를 동시에 실행하는 모든 러너 목록에서 러너의 인덱스입니다(CI_CONCURRENT_PROJECT_ID사전 정의 변수로 접근 가능).
IPC 모드#
Docker executor는 컨테이너의 IPC 네임스페이스를 다른 위치와 공유하는 것을 지원합니다. 이는 docker run --ipc 플래그에 매핑됩니다.
Docker 문서의 IPC 설정에 대한 자세한 내용을 참조하세요.
권한 있는 모드#
Docker executor는 빌드 컨테이너의 미세 조정을 허용하는 여러 옵션을 지원합니다. 이러한 옵션 중 하나는 privileged 모드입니다.
권한 있는 모드로 Docker-in-Docker 사용#
구성된 privileged 플래그는 빌드 컨테이너와 모든 서비스에 전달됩니다. 이 플래그를 사용하면 Docker-in-Docker 방식을 사용할 수 있습니다.
먼저 privileged 모드에서 실행하도록 러너(config.toml)를 구성합니다:
[[runners]]
executor = "docker"
[runners.docker]
privileged = true
그런 다음 빌드 스크립트(.gitlab-ci.yml)가 Docker-in-Docker 컨테이너를 사용하도록 만듭니다:
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?
제한된 권한 있는 모드로 rootless Docker-in-Docker 사용#
이 버전에서는 Docker-in-Docker rootless 이미지만 권한 있는 모드에서 서비스로 실행할 수 있습니다.
services_privileged와 allowed_privileged_services 구성 파라미터는
어떤 컨테이너가 권한 있는 모드에서 실행될 수 있는지 제한합니다.
제한된 권한 있는 모드로 rootless Docker-in-Docker를 사용하려면:
-
config.toml에서services_privileged와allowed_privileged_services를 사용하도록 러너를 구성합니다:[[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 rootless 컨테이너를 사용하도록 빌드 스크립트를 편집합니다:image: docker:git services: - docker:dind-rootless build: script: - docker build -t my-image . - docker push my-image
allowed_privileged_services에 나열하는 Docker-in-Docker rootless 이미지만 권한 있는 모드에서 실행할 수 있습니다.
작업과 서비스의 다른 모든 컨테이너는 권한 없는 모드에서 실행됩니다.
non-root로 실행되기 때문에 Docker-in-Docker rootless 또는 BuildKit rootless와 같은 권한 있는 모드 이미지와 함께 사용하기에 거의 안전합니다.
보안 이슈에 대한 자세한 내용은 Docker executor에 대한 보안 위험을 참조하세요.
Docker ENTRYPOINT 구성#
기본적으로 Docker executor는 Docker 이미지의 ENTRYPOINT를 재정의하지 않습니다. 작업 스크립트를 실행하는 컨테이너를 시작하기 위해 sh 또는 bash를 COMMAND로 전달합니다.
작업이 실행될 수 있도록 Docker 이미지는 다음을 해야 합니다:
sh또는bash와grep제공sh/bash를 인수로 전달받을 때 셸을 시작하는ENTRYPOINT정의
Docker Executor는 다음 명령과 동일하게 작업 컨테이너를 실행합니다:
docker run <image> sh -c "echo 'It works!'" # 또는 bash
Docker 이미지가 이 메커니즘을 지원하지 않으면 프로젝트 구성에서 다음과 같이 이미지의 ENTRYPOINT를 재정의할 수 있습니다:
# 다음과 동일
# docker run --entrypoint "" <image> sh -c "echo 'It works!'"
image:
name: my-image
entrypoint: [""]
자세한 내용은 이미지의 Entrypoint 재정의와 Docker에서 CMD와 ENTRYPOINT가 상호작용하는 방법을 참조하세요.
ENTRYPOINT로서의 작업 스크립트#
ENTRYPOINT를 사용하여 사용자 정의 환경 또는 보안 모드에서 빌드 스크립트를 실행하는
Docker 이미지를 만들 수 있습니다.
예를 들어, 빌드 스크립트를 실행하지 않는 ENTRYPOINT를 사용하는 Docker 이미지를 만들 수 있습니다. 대신 Docker 이미지는 디렉터리에서 Docker 이미지를 빌드하기 위한 미리 정의된 명령 집합을 실행합니다. 권한 있는 모드에서 빌드 컨테이너를 실행하고 러너의 빌드 환경을 보호합니다.
-
새 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 executor의 컨테이너 런타임으로 Docker를 대체할 수 있습니다.
사전 요구 사항:
- 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을 실행할 수 있습니다. -
시스템이 rootless Podman 설정의 전제 조건을 충족하는지 확인합니다. 특히 사용자가
/etc/subuid와/etc/subgid에 올바른 항목을 가지고 있는지 확인합니다. -
Linux 호스트에서 Podman을 설치합니다.
-
Podman 소켓을 활성화하고 시작합니다:
systemctl --user --now enable podman.socket -
Podman 소켓이 수신 중인지 확인합니다:
systemctl status --user podman.socket -
Podman API가 접근되는
Listen키의 소켓 문자열을 복사합니다. -
GitLab Runner 사용자가 로그아웃된 후에도 Podman 소켓이 계속 사용 가능한지 확인합니다:
sudo loginctl enable-linger gitlab-runner -
GitLab 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 = false[!note] 표준 Podman 사용에는
privileged = false로 설정합니다. 작업 내에서 Docker-in-Docker 서비스를 실행해야 하는 경우에만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: manual
Buildah를 사용하여 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로 이동할 때 수정할 수 없게 됩니다.
해결 방법: runners.docker 섹션 아래 러너의 config.toml의 볼륨에 /tmp를 추가합니다:
[[runners]]
[runners.docker]
volumes = ["/cache", "/tmp"]
이 추가 사항은 마운트된 디렉터리 전반에 걸쳐 일관된 SELinux 컨텍스트를 보장합니다.
SELinux 이슈 문제 해결#
다른 Podman/SELinux 이슈는 필요한 구성 변경을 식별하기 위한 추가 문제 해결이 필요할 수 있습니다.
Podman 러너 이슈가 SELinux와 관련이 있는지 테스트하려면 runners.docker 섹션 아래 러너의 config.toml에 다음 지시문을 일시적으로 추가합니다:
[[runners]]
[runners.docker]
security_opt = ["label:disable"]
이 추가 사항은 컨테이너에서 SELinux 적용을 끕니다(Docker의 기본 동작입니다). 보안에 영향을 미칠 수 있으므로 이 구성은 테스트 목적으로만 사용하고 영구적인 해결책으로 사용하지 마세요.
SELinux MCS 구성#
SELinux가 일부 쓰기 작업을 차단하는 경우(예: 기존 Git 리포지터리 재초기화), 러너가 시작하는 모든 컨테이너에 Multi-Category Security(MCS)를 강제할 수 있습니다:
[[runners]]
[runners.docker]
security_opt = ["label=level:s0:c1000"]
이 옵션은 SELinux를 비활성화하지 않고 컨테이너의 MCS 레벨을 설정합니다. 이 방법은 label:disable을 사용하는 것보다 더 안전합니다.
동일한 MCS 카테고리를 사용하는 여러 컨테이너는 해당 카테고리로 태그된 동일한 파일에 접근할 수 있습니다.
작업을 실행하는 사용자 지정#
기본적으로 러너는 컨테이너에서 root 사용자로 작업을 실행합니다. 작업을 실행할 다른 non-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 # www
러너가 이미지를 pull하는 방법 구성#
config.toml의 pull 정책을 구성하여 러너가 레지스트리에서 Docker 이미지를 pull하는 방법을 정의합니다. 단일 정책, 여러 정책 목록 또는 특정 pull 정책 허용을 설정할 수 있습니다.
pull_policy에 다음 값을 사용합니다:
always: 기본값. 로컬 이미지가 있어도 이미지를 pull합니다. 이 pull 정책은 이미 디스크에 있는SHA256으로 지정된 이미지에는 적용되지 않습니다.if-not-present: 로컬 버전이 없는 경우에만 이미지를 pull합니다.never: 이미지를 pull하지 않고 로컬 이미지만 사용합니다.
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always" # 사용 가능: always, if-not-present, never
always pull 정책 설정#
기본으로 활성화된 always 옵션은 컨테이너를 생성하기 전에 항상 pull을 시작합니다. 이 옵션은 로컬 이미지가 있더라도 이미지가 최신 상태인지 확인하고 오래된 이미지를 사용하지 않도록 합니다.
이 pull 정책을 사용하는 경우:
- 러너가 항상 최신 이미지를 pull해야 하는 경우.
- 러너가 공개적으로 사용 가능하고 자동 확장을 위해 구성되었거나 GitLab 인스턴스의 인스턴스 러너인 경우.
러너가 로컬에 저장된 이미지를 사용해야 하는 경우 이 정책을 사용하지 마세요.
config.toml에서 always를 pull policy로 설정합니다:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "always"
if-not-present pull 정책 설정#
pull 정책을 if-not-present로 설정하면 러너는 먼저 로컬 이미지가 있는지 확인합니다. 로컬 이미지가 없으면 러너는 레지스트리에서 이미지를 pull합니다.
if-not-present 정책을 사용하는 경우:
- 로컬 이미지를 사용하되 로컬 이미지가 없는 경우 이미지를 pull하려는 경우.
- 크고 드물게 업데이트되는 이미지의 이미지 레이어 차이 분석에 걸리는 시간을 줄이려는 경우. 이 경우 이미지 업데이트를 강제하기 위해 로컬 Docker Engine 스토어에서 이미지를 정기적으로 수동으로 제거해야 합니다.
다음 경우에는 이 정책을 사용하지 마세요:
- 러너를 사용하는 다양한 사용자가 프라이빗 이미지에 접근할 수 있는 인스턴스 러너의 경우. 보안 이슈에 대한 자세한 내용은 if-not-present pull 정책으로 프라이빗 Docker 이미지 사용을 참조하세요.
- 작업이 자주 업데이트되고 최신 이미지 버전에서 실행되어야 하는 경우. 이로 인해 로컬 이미지의 빈번한 삭제보다 네트워크 부하 감소가 더 중요해질 수 있습니다.
config.toml에서 if-not-present 정책을 설정합니다:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "if-not-present"
never pull 정책 설정#
사전 요구 사항:
- 로컬 이미지에 설치된 Docker Engine과 사용된 이미지의 로컬 복사본이 있어야 합니다.
pull 정책을 never로 설정하면 이미지 pulling이 비활성화됩니다. 사용자는 러너가 실행되는 Docker 호스트에 수동으로 pull된 이미지만 사용할 수 있습니다.
never pull 정책을 사용하는 경우:
- 러너 사용자가 사용하는 이미지를 제어하려는 경우.
- 공개 레지스트리에서 공개적으로 사용할 수 없는 특정 이미지만 사용할 수 있는 프로젝트 전용 프라이빗 러너의 경우.
자동 확장 Docker executor에는 never pull 정책을 사용하지 마세요. never pull 정책은 선택한 클라우드 공급자의 미리 정의된 클라우드 인스턴스 이미지를 사용할 때만 사용할 수 있습니다.
config.toml에서 never 정책을 설정합니다:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = "never"
여러 pull 정책 설정#
pull이 실패할 경우 실행할 여러 pull 정책을 나열할 수 있습니다. 러너는 pull 시도가 성공하거나 목록이 소진될 때까지 나열된 순서대로 pull 정책을 처리합니다. 예를 들어 러너가 always pull 정책을 사용하고 레지스트리를 사용할 수 없는 경우 두 번째 pull 정책으로 if-not-present를 추가할 수 있습니다. 이 구성을 통해 러너가 로컬에 캐시된 Docker 이미지를 사용할 수 있습니다.
이 pull 정책의 보안 함의에 대한 정보는 if-not-present pull 정책으로 프라이빗 Docker 이미지 사용을 참조하세요.
여러 pull 정책을 설정하려면 config.toml에 목록으로 추가합니다:
[[runners]]
(...)
executor = "docker"
[runners.docker]
(...)
pull_policy = ["always", "if-not-present"]
Docker pull 정책 허용#
.gitlab-ci.yml 파일에서 pull 정책을 지정할 수 있습니다. 이 정책은 CI/CD 작업이 이미지를 가져오는 방법을 결정합니다.
.gitlab-ci.yml 파일에 지정된 pull 정책 중 어떤 것을 사용할 수 있는지 제한하려면 allowed_pull_policies를 사용합니다.
예를 들어 always와 if-not-present pull 정책만 허용하려면 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 정책만 사용합니다. 유효한 pull 정책은pull_policy키워드에 지정된 정책과allowed_pull_policies를 비교하여 결정됩니다. GitLab은 이 두 정책 목록의 교집합을 사용합니다. 예를 들어pull_policy가["always", "if-not-present"]이고allowed_pull_policies가["if-not-present"]인 경우, 작업은 두 목록 모두에 정의된 유일한 pull 정책이므로if-not-present만 사용합니다. - 기존
pull_policy키워드에는allowed_pull_policies에 지정된 pull 정책이 하나 이상 포함되어야 합니다.pull_policy값이allowed_pull_policies와 일치하지 않으면 작업이 실패합니다.
이미지 pull 오류 메시지#
| 오류 메시지 | 설명 |
|---|---|
Pulling docker image registry.tld/my/image:latest ... ERROR: Build failed: Error: image registry.tld/my/image:latest not found |
러너가 이미지를 찾을 수 없습니다. always pull 정책이 설정된 경우 표시됩니다. |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found |
이미지가 로컬에서 빌드되었으며 공개 또는 기본 Docker 레지스트리에 존재하지 않습니다. always pull 정책이 설정된 경우 표시됩니다. |
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. |
러너가 이미지를 pull하는 대신 로컬 이미지를 사용했습니다. |
Pulling docker image local_image:latest ... ERROR: Build failed: Error: image local_image:latest not found |
이미지를 로컬에서 찾을 수 없습니다. never pull 정책이 설정된 경우 표시됩니다. |
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 |
러너가 이미지 pull에 실패하고 다음에 나열된 pull 정책을 사용하여 이미지를 pull하려 합니다. 여러 pull 정책이 설정된 경우 표시됩니다. |
실패한 pull 재시도#
실패한 이미지 pull을 재시도하도록 러너를 구성하려면 config.toml에서 동일한 정책을 두 번 이상 지정합니다.
예를 들어, 이 구성은 pull을 한 번 재시도합니다:
[runners.docker]
pull_policy = ["always", "always"]
이 설정은 개별 프로젝트의 .gitlab-ci.yml 파일에 있는 retry 지시문과 유사하지만, 특히 Docker pull이 처음에 실패하는 경우에만 적용됩니다.
Windows 컨테이너 사용#
Docker executor에서 Windows 컨테이너를 사용하려면 제한 사항, 지원되는 Windows 버전 및 Windows Docker executor 구성에 대한 다음 정보를 참고하세요.
Nanoserver 지원#
Windows 헬퍼 이미지에 PowerShell Core 지원이 도입되면서 이제 헬퍼 이미지에
nanoserver 변형을 활용할 수 있게 되었습니다.
Windows에서 Docker executor의 알려진 이슈#
다음은 Docker executor에서 Windows 컨테이너를 사용할 때의 몇 가지 제한 사항입니다:
-
Docker-in-Docker는 Docker 자체에서 지원하지 않으므로 지원되지 않습니다.
-
호스트 장치 마운팅은 지원되지 않습니다.
-
볼륨 디렉터리를 마운트할 때 해당 디렉터리가 존재해야 합니다. 그렇지 않으면 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 2025 LTSC (24H2)
- Windows Server 2022 LTSC (21H2)
- Windows Server 2019 LTSC (1809)
Windows 컨테이너는 호스트 OS와 격리 모드를 기반으로 하위 호환성을 지원합니다. 최신 호스트는 이전 컨테이너 이미지를 실행할 수 있습니다. 호환성 세부 정보는 Microsoft Windows 컨테이너 버전 호환성 가이드라인을 참조하세요.
Server Core, Nano Server, Server, Windows를 포함한 다양한 Windows 기본 이미지를 사용할 수 있습니다. 예를 들어 호환되는 OS 버전의 Windows Server Core 이미지를 사용하세요:
mcr.microsoft.com/windows/servercore:ltsc2025mcr.microsoft.com/windows/servercore:ltsc2025-amd64mcr.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 구성#
--docker-volumes 또는 DOCKER_VOLUMES 환경 변수를 전달할 때
c:\\cache를 소스 디렉터리로 사용하여 러너를 등록할 때
알려진 이슈가 있습니다.
다음은 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에 대한 다른 구성 옵션은 고급 구성 섹션을 참조하세요.
서비스#
각 작업에 대한 네트워크를 활성화하여 서비스를 사용할 수 있습니다.
Native Step 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가 작업에 정의된 단계를 pull하지 못합니다. 예를 들어 Debian 기반 Linux 배포판은 기본적으로ca-certificates를 설치하지 않습니다. -
GitLab 17.9 이전 버전에서는 빌드 이미지에
$PATH에step-runner바이너리가 포함되어 있어야 합니다. 이를 위해 다음 중 하나를 수행할 수 있습니다:- 자체 사용자 정의 빌드 이미지를 만들고
step-runner바이너리를 포함합니다. - 작업을 실행하는 데 필요한 의존성이 포함된 경우
registry.gitlab.com/gitlab-org/step-runner:v0이미지를 사용합니다.
- 자체 사용자 정의 빌드 이미지를 만들고
-
Docker 컨테이너를 실행하는 단계를 실행하는 것은 기존
script와 동일한 구성 파라미터와 제약 조건을 준수해야 합니다. 예를 들어 Docker-in-Docker를 사용해야 합니다. -
이 실행 모드는 아직
Github Actions실행을 지원하지 않습니다.
