GitLab Runner (운영 기준)¶
0. 전제¶
다음 환경 기준으로 작성:
- 규모: 프로젝트 5~20개 / 서버 소수
- 인력: 1~2명 (소수 정예)
- 멀티 스택 환경: Node.js, Express, Next.js, Nuxt.js, PHP, Laravel, C++ 등
- 운영 서버: Linux / Windows 혼합 가능
- Docker 사용 범위: Runner 빌드 환경 및 Release Storage 서버의 AIStor 실행 용도
- 배포 방식: 운영 서버가 Release Storage에서 빌드 결과물을 직접 가져가는 pull 배포
인프라 전제:
- GitLab 서버, Runner 서버, Release Storage 서버, 운영 서버는 논리적, 물리적으로 분리 가능한 구성으로 보며, 분리 운영을 전제로 작성함.
- GitLab 서버는 외부 비공개로 유지하며, 운영 서버는 GitLab 서버에 직접 접근하지 않음.
- Release Storage 서버는 운영 서버가 접근 가능한 별도 서버로 구성함.
운영 원칙:
- build -> publish -> operation server pull deploy 구조 유지
{YYYYMMDD-HHMMSS}-{declared_version}-{CI_COMMIT_SHORT_SHA}기반 immutable package version 운영- 인증은 목적별 계정 및 Access Key로 분리
- 빌드: Runner 서버
- CI 내부 산출물 보관: GitLab Generic Package Registry
- 운영 배포 기준 저장소: Release Storage (S3-compatible Object Storage)
- 운영: download, verify, extract, activate, report 수행
금지 사항:
- 운영 서버에 write 권한 Access Key 배치 금지
.env및 서버 고유 설정 파일을 패키지에 포함 금지- 운영 서버에서 배포 파일을 수동 수정한 뒤 재사용 금지
- Generic Package Registry에 업로드된 package version/file overwrite 금지
- Release Storage 의 releases 경로 Release Object overwrite 금지
- Release Storage 의
current/{RELEASE_ENV}.json외 object overwrite 금지 - 운영 서버가 GitLab 서버에 직접 접근하도록 구성 금지
위 전제를 기반으로
GitLab Runner를 실제로 사용할 수 있는 상태까지 준비하는 단계를 정의함.
1. 개요¶
1.1 중요¶
- Runner 는 GitLab 서버와 동일 서버 또는 별도 서버에 설치 가능
- Runner가 별도 서버에 설치되는 구조까지 포함하여 작성하며, 설치 위치에 따라 네트워크 접근 및 권한 설정이 달라질 수 있음
1.2 Runner 구성 및 분리 정책¶
- 프로젝트별로 Runner를 신뢰 경계(Trust Boundary) 즉, 실행 코드의 신뢰 수준 기준으로 분리하여 구성.
Untrusted Runner (Merge Request)와Trusted Runner (Build)는 반드시 분리함
Runner 구성:
| 구분 | Merge Request Runner | Build Runner |
|---|---|---|
| 신뢰 수준 | Untrusted | Trusted |
| 대상 | 작업 브랜치 / Merge Request | Protected release target branch |
| 실행 Pipeline | merge_request_event |
push / Web(New Pipeline) |
| Executor | Docker | Docker |
| 역할 | 최소 검증 (lint / test / MR route check) | build / package / release-state publish |
| 실제 배포 수행 | ❌ | ❌ |
| Generic Package Registry 접근 | ❌ | ⭕ (write 가능) |
| Release Storage 접근 | ❌ | ⭕ (write 가능) |
| 운영 서버 접근 | ❌ | ❌ |
| Protected Runner | ❌ | ⭕ |
| Protected Branch 실행 | ❌ | ⭕ |
| 민감 정보 접근 | ❌ | ⭕ |
운영 기준:
-
필요 시 동일 서버에 함께 설치할 수 있으나, 운영 환경에서는 별도 서버 분리 구성을 우선 고려함
-
예를 들어,
- Merge Request Runner 는 A 서버에 구성
- Build Runner 는 B 서버에 구성
-
Merge Request Runner: Docker Executor
- Merge Request 단계에서 실행되는 검증 전용 Runner
- 최소 검증(lint, test, syntax check 등)만 수행
- "Pipelines must succeed" 조건 충족을 위한 CI gate 역할
- 제한 사항:
- 배포 토큰 사용 금지
- Registry write 권한 금지
- build / package / release publish 작업 금지
- 운영 서버 접근 금지
-
Build Runner: Docker Executor
- release target branch 의 build / package / release-state publish 작업을 수행함
- release target branch 는
.ops/ci/release-branch-versions/{branch}.yaml존재 여부로 결정함 pushpipeline 에서는 release target branch commit 반영 시 실행됨Web(New Pipeline)pipeline 에서는 release target branch 를 선택하면 수동 release 실행 요청으로 처리됨- Build Runner 는 Protected Runner 로 구성함
- Protected Variable 을 사용하는 구조이므로 release target branch 도 Protected Branch 로 등록해야 함
- GitLab은 실제 운영 서버 deploy 를 수행하지 않음
- 운영 서버 접근 권한을 가지지 않음
-
Runner 간 Tag 공유 금지
- Run untagged jobs 사용 금지
- 모든 Job은 명시적으로 Runner Tag를 지정해야 함
2. Runner 설치 (Runner가 설치될 서버에서 실행)¶
curl -fsSL -o /tmp/gitlab-runner-repo.sh https://packages.gitlab.com/install/repositories/runner/gitlab-runner/script.rpm.sh
cat /tmp/gitlab-runner-repo.sh
sudo bash /tmp/gitlab-runner-repo.sh
sudo dnf install -y gitlab-runner
sudo systemctl enable gitlab-runner
sudo systemctl start gitlab-runner
sudo systemctl status gitlab-runner
3. Docker 설치 (Merge Request Runner / Build Runner 서버에서만 실행)¶
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo systemctl enable docker
sudo systemctl start docker
sudo systemctl status docker
sudo usermod -aG docker gitlab-runner
sudo systemctl restart docker
sudo systemctl restart gitlab-runner
sudo -u gitlab-runner docker ps # 에러 없이 명령이 실행됐다는 것 자체가 gitlab-runner 유저가 docker 그룹에 정상 추가됐다는 의미
확인:
sudo docker version
sudo docker run --rm hello-world
4. Token 관리 규칙¶
Runner, Tag, Token 는 다음 규칙:
| 구분 | 명명 규칙 | 예시 |
|---|---|---|
| Runner | [SERVICE_NAME]_[MergeRequestOrBuild]_runner |
example.com_mr_runner, example.com_build_runner |
| Tag | [SERVICE_NAME]_[MergeRequestOrBuild]_runner_tag |
example.com_mr_runner_tag, example.com_build_runner_tag |
| Token | [SERVICE_NAME]_[MergeRequestOrBuild]_RUNNER_TOKEN |
STREAUM_COM_MR_RUNNER_TOKEN, STREAUM_COM_BUILD_RUNNER_TOKEN |
운영 기준:
- Project 별로
SERVICE_NAME을 prefix 로 고정 - 역할 명확히 구분
- 환경 변수명은 대문자 사용
- 환경 변수명에서는
.대신_를 사용함
5. Runner 생성 (UI)¶
- 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.
경로:
Project → Settings → CI/CD → Runners → Create project runner
Tags¶
- Tags : [SERVICE_NAME]_[MergeRequestOrBuild]_runner_tag
- Run untagged jobs :
비활설화
Configuration (optional)¶
- Runner description : [SERVICE_NAME] [MergeRequestOrBuild] Runner
- Paused:
비활설화 - Protected:
- Merge Request Runner: ❌ 비활성화
- any work branch 및 Merge Request pipeline 실행을 위해 필요
- Protected Branch 외부에서도 실행 가능해야 함
- Build Runner: ⭕ 활성화
- Protected Branch / Protected Tag 에서만 Runner 실행 허용
- release target branch 의 build / package / release-state publish pipeline 용도
- release target branch 는
.ops/ci/release-branch-versions/{branch}.yaml존재 여부로 결정함 - 예:
pre-production,production,ko-dev-test - Protected Variable 을 사용하는 경우 해당 release target branch 도 Protected Branch 로 등록해야 함
- release publish 전용 Runner 로 분리하여 실수 실행 범위를 제한하는 안전장치 역할 수행
- Merge Request Runner: ❌ 비활성화
- Lock to current projects:
활설화
생성¶
- Create runner 클릭
- 생성 후 Authentication Token 무조건 복사 및 저장
6. Runner 등록 (서버)¶
- 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.
- GitLab UI에서 생성한 Runner 정보를 기준으로 제공하는
sudo gitlab-runner register명령어를gitlab-runner가 설치된 서버에서 그대로 사용함 - Runner 유형별 executor 및 image 정책을 구분하여 등록함
- 실행 시 아래 기준에 따라 입력
- Runner 이름은 중복되도 괜찮음
6.1 Merge Request Runner (Docker)¶
입력 기준:
- GitLab instance URL:
gitlab.example.com - runner name:
example.com_mr_runner - executor:
docker - default image:
- 운영 서버 런타임 기준으로 결정
- 예: 운영 서버
node -v가v22.x인 경우node:22
운영 기준:
- Merge Request Runner 는 any work branch / Merge Request pipeline 전용
- 최소 검증(lint/test/MR route check) 용도로 사용
- package 생성 및 release 처리 금지
※ tag, run untagged jobs, protected, lock to current projects 설정은 GitLab UI에서 Runner 생성 시 설정됨
6.2 Build Runner (Docker)¶
Docker Executor 사용 시 Build Runner 는 Job 실행 환경이 되는 기본 이미지를 지정해야 함.
Build Runner의 기본 이미지는 단순 최신 버전이 아니라, 운영 서버와 런타임 및 시스템 라이브러리 호환성을 기준으로 선택함.
즉, Build 환경과 운영 서버의 런타임 및 시스템 라이브러리가 호환되어야 함
특히 Alpine(musl) 기반 이미지와 일반 Linux(glibc) 기반 운영 서버 간 차이는 사전 검토가 필요함.
Runner 등록 시 입력하는 default image 는 기본값이며, Runner의 default image보다 .gitlab-ci.yml 의 image: 설정으로 우선 결정할 수 있음.
이미지 선정 전 운영 서버 확인 (필수)¶
runner 등록 전 반드시 운영 서버에서 아래를 확인한 후 이미지를 결정함.
# 런타임 버전 확인
node -v # Node.js 계열
php -v # PHP / Laravel 계열
gcc --version # C 계열
g++ --version # C++ 계열 (gcc와 별도 패키지로 설치되는 경우 있음)
# OS 확인
cat /etc/os-release
확인 결과를 기준으로 이미지 버전을 결정함:
| 확인 항목 | 예시 결과 | 선택 이미지 |
|---|---|---|
| node -v | v22.x | node:22 |
| node -v | v23.x | node:23 |
| php -v | 8.2.x | php:8.2 |
운영 기준:
- major 버전 일치를 기본으로 함
- 네이티브 모듈 또는 C++ 바인딩이 포함된 경우 minor 버전까지 일치시킴
- 순수 JS/PHP 스택은 major 버전 일치로 충분함
- 프로젝트별 운영 서버 버전이 다르면
.gitlab-ci.yml에서image:를 각각 명시함
예:
# 프로젝트별 .gitlab-ci.yml 에서 이미지 오버라이드
# runner 등록 시 default image는 fallback 용도임
# example.com (Next.js, 운영 서버 node v22)
image: node:22
# backend.example.com (Express, 운영 서버 node v23)
image: node:23
기본 원칙:
- 프로젝트 스택에 맞는 공식 이미지를 사용함
- Docker Official Image 또는 공식 이미지를 우선 사용함
latest태그 사용 금지 (재현성 문제)- 버전은 가능한 명시적으로 고정 (
<major>.<minor>이상 권장) - Docker Hub의 공식 이미지 목록에서 선택함
- 프로젝트 런타임 버전과 일치하도록 설정
스택별 예시:
| 스택 | 예시 이미지 | 비고 |
|---|---|---|
| Node.js / Express / Next.js / Nuxt.js | node:<version> |
npm, yarn, pnpm |
| PHP / Laravel | php:<version> |
composer 필요 시 별도 구성 |
| C++ | gcc:<version> 또는 ubuntu:<version> |
빌드 도구 포함 여부 확인 |
| 멀티 스택 | custom image | 도구 조합 고정 |
공식 이미지 확인 경로:
-
Docker Official Images:
https://hub.docker.com/search?q=&type=image&image_filter=official -
Node.js 이미지:
https://hub.docker.com/_/node -
PHP 이미지:
https://hub.docker.com/_/php -
GCC 이미지:
https://hub.docker.com/_/gcc
운영 기준:
- 빌드 결과물이 운영 서버에서 그대로 실행되어야 하므로, Build 환경과 운영 환경의 런타임 및 시스템 라이브러리가 호환되어야 함
- 가능하면 운영 서버와 동일한 major 버전의 런타임을 사용함
- 네이티브 모듈 또는 바이너리 빌드가 포함되는 경우, OS 계열 및 libc(glibc / musl) 차이까지 검토함
- 이미지 변경 시 CI / 로컬 / 운영 환경 호환성 함께 검증
- 필요 시 custom image를 별도로 관리하여 빌드 시간 단축 및 안정성 확보
입력 기준:
- GitLab instance URL:
gitlab.example.com- GitLab이 설치된 서버의 기본 접근 URL 입력
- Runner가 통신할 대상 GitLab 서버의 URL이며, 실제 운영 URL 기준으로 입력
- AWS 등 Cloud 인프라 환경에서는 Runner와 GitLab 간 통신을 Private IP 또는 Private DNS로 구성하여 외부 트래픽 비용 발생을 방지함
- runner name:
example.com_build_runner - executor:
docker - default image:
- 운영 서버 런타임 기준으로 결정
- 예: 운영 서버
node -v가v22.x인 경우node:22
※ tag, run untagged jobs, protected, lock to current projects 설정은 GitLab UI에서 Runner 생성 시 설정됨
7. Runner 상태 확인¶
- 최고 관리자 계정(Admin) 또는 운영 책임자 계정 으로 수행함.
7.1 서버 확인¶
sudo systemctl status gitlab-runner
sudo gitlab-runner verify
운영 기준:
- gitlab-runner 서비스가 active (running) 상태
- verify 실행 시 등록된 Runner가 조회됨
7.2 GitLab UI 확인¶
경로:
Project → Settings → CI/CD → Runners → Assigned project runners
확인 항목:
- example.com_mr_runner 표시 확인
- example.com_build_runner 표시 확인
- 상태가 online 인지 확인
8. 실행 정책¶
- Merge Request 검증 Job →
example.com_mr_runner_tagTag 사용 - release 감지 / build / package / release-state publish Job →
example.com_build_runner_tagTag 사용 - 모든 Job은 Tag 필수
- Run untagged jobs 비활성 유지
Pipeline source 기준:
| Pipeline source | Runner | 동작 |
|---|---|---|
merge_request_event |
Merge Request Runner | branch 승격 경로 검증만 수행 |
push |
Build Runner | release target branch 이면 build / package / release-state publish 수행 |
Web(New Pipeline) |
Build Runner | release target branch 이면 수동 release publish 수행 |
release target 기준:
.ops/ci/release-branch-versions/{CI_COMMIT_BRANCH}.yaml
운영 기준:
develop,feature/*는 release job 실행 대상에서 제외함- release target branch 는 Protected Branch 로 등록함
- Build Runner 는 Protected Runner 로 구성함
- GitLab은 release package 와 release state publish 까지만 수행함
- 운영 서버 deploy 는 수행하지 않음
예:
mr_sanity_check:
tags:
- example.com_mr_runner_tag
detect_release_targets:
tags:
- example.com_build_runner_tag
build_target:
tags:
- example.com_build_runner_tag
package_target:
tags:
- example.com_build_runner_tag
set_release_state:
tags:
- example.com_build_runner_tag
9. Runner 서버 운영 관리¶
9.1 Docker Runner 디스크 정리¶
Merge Request Runner 와 Build Runner 는 Docker Executor 를 사용하므로 사용하지 않는 이미지, 컨테이너, 볼륨이 누적될 수 있음.
1. 수동 정리 (테스트 실행)¶
sudo docker system prune -af --volumes
설명:
-a: 사용하지 않는 모든 이미지 제거-f: 확인 없이 강제 실행--volumes: 사용하지 않는 볼륨까지 제거
주의:
- 이 명령어는 실제로 리소스를 삭제함
- 반드시 Runner 서버에서 실행해야 함
- 운영 서버에서는 실행 금지
2. 현재 디스크 사용량 확인¶
sudo docker system df
출력 예:
TYPE TOTAL ACTIVE SIZE RECLAIMABLE
Images 0 0 0B 0B
Containers 0 0 0B 0B
Local Volumes 0 0 0B 0B
Build Cache 0 0 0B 0B
운영 기준:
- RECLAIMABLE 수치가 높을 경우 정리 필요
- 디스크 사용량 증가 추세 지속 시 자동화 필요
3. 자동 정리 (crontab 등록)¶
sudo tee /etc/cron.d/docker-prune >/dev/null <<'EOF'
# GitLab Runner Docker cleanup
# 매일 03:00 에 사용하지 않는 Docker 리소스 정리
0 3 * * * root /usr/bin/docker system prune -af --volumes
EOF
확인:
cat /etc/cron.d/docker-prune
4. 운영 기준¶
- Runner 서버 디스크 사용량을 주기적으로 확인함
- 기본적으로
--volumes포함하여 항시 깨끗한 상태 유지 - Build cache가 필요한 경우에만
--volumes사용 여부 재검토 - 디스크 부족 장애 발생 시:
- prune 주기 단축
- Runner 서버 디스크 증설
- 캐시 전략 분리 검토
9.2 config.toml 기본 확인¶
Runner 등록 후 /etc/gitlab-runner/config.toml을 확인함.
sudo cat /etc/gitlab-runner/config.toml
운영 기준:
- Runner별
name,executor,url확인 - Docker Runner 는
image확인 및pull_policy설정 검토 - 서버 사양에 맞게
concurrent및limit설정 검토
기본 설정 예시¶
[[runners]]
name = "example.com_mr_runner"
limit = 1
executor = "docker"
[runners.docker]
image = "node:22"
pull_policy = "if-not-present" # 선택 설정 (성능 최적화)
volumes = ["/cache"]
pull_policy¶
always(기본값): 매 job마다 이미지 pull (안정성 높음, 느림)if-not-present: 로컬에 없을 때만 pull (빠름, 운영 안정화 이후 권장)never: 로컬 이미지만 사용 (특수한 경우만 사용)
운영 기준:
- 초기 구축 단계에서는 기본값(
always) 사용 - CI 안정화 이후
if-not-present적용 검토
적용 후 반영¶
sudo systemctl restart gitlab-runner
sudo gitlab-runner verify
주의¶
- 단순 파일 빌드(npm build 등): 보안을 위해
/var/run/docker.sock바인딩을 금지함. - Docker 이미지 빌드가 필요한 경우에만 Build Runner에 한해 아래 설정을 적용함:
volumes = ["/var/run/docker.sock:/var/run/docker.sock", "/cache"]
- docker.sock 바인딩은 Runner 서버의 root 권한 탈취 가능성이 있으므로 필요한 경우에만 제한적으로 사용함
- Job 내부에서
docker build,docker push등이 필요한 경우에만 별도 검토 후 적용함.