Blog

GitHub Actions 파이프라인 속도 올리고 비용 줄이는 4가지 빌드 최적화 기법

2026-10-09

Close-up of a computer screen displaying programming code in a dark environment.

Photo by luis gomes on Pexels

1. 느린 CI/CD 파이프라인이 팀에 미치는 비효율과 진단 방법

소프트웨어 개발 과정에서 CI/CD(지속적 통합/지속적 배포) 파이프라인은 코드를 검증하고 배포하는 핵심 축입니다. 하지만 프로젝트 규모가 커짐에 따라 파이프라인 실행 시간이 5분에서 15분, 심하게는 30분 이상으로 늘어나는 현상을 자주 목격하게 됩니다. 개발자가 Pull Request(PR)를 올린 후 빌드 결과를 기다리느라 맥락 전환(Context Switching) 비용이 발생하고, 하루에도 수십 번 실행되는 워크플로 때문에 클라우드 서비스 요금이 가파르게 증가합니다.

가상의 중소 IT 기업인 A사의 사례를 살펴보겠습니다. A사는 백엔드 개발자 12명이 하루 평균 40개의 PR을 작성하고 있었습니다. 각 PR당 CI 파이프라인 실행 시간은 평균 18분이 소요되었습니다. 개발자들은 빌드가 완료될 때까지 다른 작업을 시작하지 못하고 대기하거나, 다른 작업을 하다가 다시 돌아와 오류를 확인해야 했습니다. 이로 인해 유실되는 시간을 조사한 결과, 개발자 1인당 하루 약 45분의 순수 대기 시간이 발생하고 있었습니다. 또한, GitHub Actions의 기본 러너 사용 요금이 월 120만 원 이상 청구되고 있었습니다.

파이프라인 최적화를 시작하기 전 가장 먼저 해야 할 일은 병목 구간을 진단하는 것입니다. GitHub Actions의 'Summary' 탭에서 각 작업(Job)과 단계(Step)별 소요 시간을 수집하고, 어떤 단계에서 가장 많은 시간이 소비되는지 파악해야 합니다.

진단 항목 주요 관찰 포인트 개선 목표 지표
의존성 설치 시간 npm install, pip install 등 패키지 다운로드 소요 시간 전체 파이프라인 시간의 10% 이하로 축소
테스트 실행 시간 단위 테스트 및 통합 테스트 순차 실행에 따른 지연 병렬 실행 및 변경 파일 선별 실행으로 50% 감축
도커 이미지 빌드 베이스 이미지 다운로드 및 레이어 재빌드 반복 여부 Docker BuildKit 및 캐시 레지스트리 활용으로 최적화
러너 대기 시간 동시 실행 직렬화로 인한 대기열(Queue) 정체 러너 사양 조정 및 동시성(Concurrency) 제어 설정

2. 의존성 패키지 캐싱 기법으로 패키지 설치 시간 90% 줄이기

CI/CD 환경은 기본적으로 격리된 가상 머신(VM)에서 매번 새로운 컨테이너를 띄워 실행됩니다. 따라서 소스 코드가 한 줄만 바뀌어도 수백 메가바이트에 달하는 외부 의존성 라이브러리를 매번 새로 인터넷에서 다운로드하는 비효율이 발생합니다. 이를 해결하기 위해 의존성 캐싱을 정확히 설정해야 합니다.

Node.js 환경을 예로 들면, 단순 `npm ci` 명령어만 실행할 경우 매번 레지스트리에서 패키지를 다운로드합니다. 하지만 `actions/setup-node`에서 제공하는 자체 캐시 옵션이나 `actions/cache`를 사용하면 라이브러리 파일이 저장된 디렉토리를 이전 실행 건에서 가져와 재사용할 수 있습니다.

setup-node 액션을 활용한 간편 캐싱 기법

가장 단순하면서 강력한 방식은 언어별 공식 setup 액션의 캐시 기능을 활성화하는 것입니다. `package-lock.json`이나 `pnpm-lock.yaml` 파일의 해시값을 기준으로 캐시 키가 생성되며, 의존성 변경이 없을 때 패키지 다운로드 과정을 완전히 건너뜁니다.

다음은 Node.js 프로젝트의 최적화된 워크플로 예시입니다.

- uses: actions/setup-node@v4

  with:

    node-version: '20'

    cache: 'npm'

- run: npm ci

actions/cache를 이용한 세부 디렉토리 직접 지정

Java의 Gradle이나 Python의 pip, Poetry처럼 복잡한 빌드 캐시를 다루어야 할 때는 `actions/cache`를 직접 구성합니다. 캐시 키 설정 시 `runner.os`와 잠금 파일의 해시값(`hashFiles`)을 조합하고, 정확히 일치하는 키가 없을 경우 차선책으로 사용할 복원 키(`restore-keys`)를 지정합니다.

구분 적용 전 (캐시 미사용) 적용 후 (의존성 캐싱 적용)
패키지 설치 소요 시간 3분 40초 12초
네트워크 트래픽 사용량 약 450MB 다운로드 0MB (내부 네트워크 캐시 로드)
빌드 성공 안정성 외부 npm 레지스트리 장애 시 빌드 실패 캐시 로드로 외부 장애의 영향 감소

3. Docker 빌드 속도를 높이는 레이어 캐싱과 BuildKit 활용법

애플리케이션을 컨테이너 이미지로 빌드하여 배포하는 파이프라인에서는 Docker 이미지 빌드가 전체 소요 시간의 절반 이상을 차지하는 경우가 많습니다. Docker는 이미지를 계층적 레이어(Layer)로 저장하므로, 변경되지 않은 레이어는 재사용하도록 구성해야 합니다.

1) Multi-stage Build 적용으로 빌드 환경과 실행 환경 분리

Dockerfile 작성 시 소스 코드 컴파일에 필요한 도구(SDK, 컴파일러)와 실제 실행에 필요한 최소한의 런타임 환경을 분리해야 합니다. Multi-stage 빌드를 적용하면 최종 이미지 용량이 1GB에서 100MB 이하로 줄어들며, 빌드 및 푸시 속도가 크게 향상됩니다.

2) GitHub Actions용 Docker BuildKit 캐시 설정

`docker/build-push-action`을 사용할 때 `cache-from`과 `cache-to` 파라미터를 지정하면 GitHub Actions의 캐시 백엔드(GHA)를 활용하여 이전 빌드 레이어를 그대로 재사용할 수 있습니다.

다음은 Docker BuildKit 캐시를 적용하는 핵심 구성 예시입니다.

- uses: docker/setup-buildx-action@v3

- uses: docker/build-push-action@v5

  with:

    context: .

    push: true

    tags: my-registry/my-app:latest

    cache-from: type=gha

    cache-to: type=gha,mode=max

여기서 `mode=max` 옵션은 최종 실행 단계뿐만 아니라 빌드 과정 중간에 생성된 모든 레이어의 캐시를 저장하도록 지시하므로, 다음 빌드 시 소스 코드가 일부 수정되더라도 그 전 단계까지의 빌드 레이어를 모두 재활용하게 됩니다.

4. 변경 파일 감지 경로 필터링과 병렬 작업 매트릭스 구성

모든 PR이나 커밋마다 전체 테스트와 빌드를 수행하는 것은 심각한 자원 낭비입니다. 예를 들어 프론트엔드 코드만 수정되었거나 문서(Markdown) 파일만 수정되었을 때 백엔드 통합 테스트나 도커 빌드가 실행될 필요는 없습니다.

경로 필터링(Path Filtering)을 통한 불필요한 작업 건너뛰기

GitHub Actions의 `paths`나 `paths-ignore` 키워드를 사용하거나, 오픈소스 액션인 `dorny/paths-filter`를 도입하면 변경된 파일의 위치에 따라 실행할 작업을 제어할 수 있습니다.

on:

  pull_request:

    paths-ignore:

      - '**.md'

      - 'docs/**'

위 설정을 적용하면 문서 수정 PR이 생성되었을 때 CI 파이프라인 전체가 실행되지 않으므로 러너 시간 소비를 즉시 0분으로 줄일 수 있습니다.

매트릭스(Matrix) 전략과 병렬 실행 최적화

테스트 수백 개를 하나의 서버에서 순차적으로 실행하면 시간이 오래 걸립니다. `strategy.matrix` 기능을 사용하여 테스트 그룹을 분할하고 병렬로 실행하면 전체 실행 시간을 대폭 단축할 수 있습니다.

최적화 기법 적용 방식 단축 효과 및 장점
경로 필터링 (Path Filter) 수정된 파일의 확장자 및 디렉토리 추적 불필요한 빌드 완전히 건너뜀 (시간 100% 절감)
매트릭스 병렬화 (Matrix) 테스트 suite를 N개 파티션으로 분할 실행 실행 시간을 1/N 수준으로 단축
동시성 제어 (Concurrency) 동일 PR의 이전 빌드 자동 취소 (cancel-in-progress) 낭비되는 계산 자원 즉시 회수

특히 동시성 제어는 개발자가 푸시를 연속으로 여러 번 할 때 유용합니다. `concurrency` 그룹을 설정하고 `cancel-in-progress: true`를 부여하면, 이미 진행 중이던 이전 커밋의 빌드가 즉시 중단되어 무의미한 러너 사용 요금이 발생하는 것을 방지합니다.

5. 셀프 호스티드 러너(Self-Hosted Runner) 도입을 통한 요금 절감

GitHub에서 제공하는 기본 러너(GitHub-hosted runner)는 관리가 필요 없지만, 사양이 올라갈수록 분당 과금 단가가 비싸집니다. 워크플로 실행량이 많은 팀이라면 클라우드 인프라(AWS EC2, GCP Compute Engine 등)를 활용하여 셀프 호스티드 러너를 구축하는 것이 비용 측면에서 유리합니다.

A사의 경우 월간 GitHub Actions 사용 시간이 30,000분에 달했습니다. 표준 2코어 러너 사용 시 월 240 달러 수준이었으나, 8코어 고성능 러너를 도입하자 비용이 4배로 증가하는 문제에 직면했습니다. 이를 해결하기 위해 AWS의 스팟 인스턴스(Spot Instance)를 활용한 셀프 호스티드 러너 오토스케일링 환경을 구축했습니다.

비교 항목 GitHub 호스팅 러너 (2코어) AWS EC2 스팟 인스턴스 러너 (c6i.xlarge 4코어)
분당 사용 요금 $0.008 / 분 약 $0.0007 / 분 (스팟 할인 적용 시)
빌드 수행 속도 기준 속도 (1.0x) 고사양 CPU 및 Disk I/O로 약 2.2배 향상
인프라 관리 공수 없음 (완전 관리형) 초기 오토스케일링(ARC 등) 설정 공수 필요
추천 대상 팀 월 사용량 3,000분 미만의 소규모 팀 월 사용량이 많고 빌드 속도 개선이 시급한 팀

쿠버네티스 환경을 보유하고 있다면 'Actions Runner Controller(ARC)'를 사용하여 빌드 요청이 들어올 때만 Pod 형태의 러너를 즉시 생성하고, 작업이 끝나면 삭제하는 방식으로 인프라 비용을 극적으로 줄일 수 있습니다.

6. CI/CD 파이프라인 성능 점검 및 적용 체크리스트

파이프라인 최적화 작업을 실제로 진행할 때 현업 담당자가 체크해야 할 항목들을 정리했습니다. 아래 목록을 바탕으로 현재 팀의 워크플로 파일을 하나씩 검토해 보시기 바랍니다.

  1. 의존성 캐시 적용 여부 확인: Node.js, Python, Java, Go 등 언어별 패키지 매니저의 캐싱 설정이 활성화되어 있는가?
  2. 도커 빌드 캐시 백엔드 활성화: Docker buildx 적용 시 `cache-from: type=gha` 옵션을 사용하여 레이어를 재활용하고 있는가?
  3. 경로 필터링 설정: 단순 문서 수정이나 리드미 변경 시 불필요한 전체 빌드가 실행되고 있지 않는가?
  4. 동시 실행 제어(Concurrency): 새로운 커밋이 푸시되었을 때 이전 커밋의 진행 중인 빌드를 자동 취소하고 있는가?
  5. 러너 타임아웃 지정: 모든 job에 `timeout-minutes`를 설정하여 무한 루프나 대기 상태로 인한 과금을 방지하고 있는가?
  6. 아티팩트(Artifact) 보존 기간 조정: 빌드 결과물이나 로그 파일의 보존 기간을 기본 90일에서 7일~14일 수준으로 줄여 저장소 용량을 관리하고 있는가?

7. 지금 바로 업무에 적용할 핵심 실행 항목 요약

CI/CD 파이프라인의 시간과 비용을 줄이기 위해 오늘 바로 실행할 수 있는 핵심 조치 4가지는 다음과 같습니다.

  • 빌드 워크플로 상단에 Concurrency 설정 추가: 파일 변경이 자주 일어나는 PR 환경에서 중복 실행되는 빌드를 자동 취소하도록 설정합니다.
  • Setup 액션에 cache 파라미터 추가: `actions/setup-node` 또는 `actions/setup-java` 사용 시 패키지 매니저 이름을 지정하여 캐싱을 즉시 활성화합니다.
  • Job 및 Step 레벨에 timeout-minutes 부여: 예기치 못한 스크립트 중단으로 러너가 최대 시간(6시간) 동안 과금되는 위험을 차단합니다.
  • 주요 빌드 단계별 소요 시간 측정 및 시각화: 주 1회 빌드 소요 시간을 모니터링하여 병목이 발생하는 스텝을 선별하고 우선순위를 정해 개선합니다.

인클루드웹 솔루션이 궁금하신가요?

건설관리, 프로젝트관리, 영업관리 솔루션 도입을 무료로 상담해 드립니다.