개발괴발/Devops

[GitHub Actions] EC2에서 막힌 CI/CD, Self-hosted Runner로 자동화하기

nourzoo 2025. 8. 1. 08:47

 

 

 

이 글은 우아한테크코스 레벨3 프로젝트에서 EC2를 이용해 CI/CD를 구축하던 중 발생한 문제를 해결하기 위해 Self-hosted runner를 도입한 과정을 정리한 글이다.

 

1. Self-hosted runner가 필요해진 이유

1) AWS 자격증명 유지가 어렵다

기본적으로 GitHub Actions에서 기본적으로 제공하는 ubuntu-latest는 ci/cd 실행 시마다 새로운 인스턴스를 생성하고 삭제한다.

이로 인해 aws 자격증명(~/.aws/credentials) 같은 환경설정 파일이 유지되지 않으며, AWS Access Key와 Secret Key를 매번 env:로 주입해야 한다.

하지만 실수로 키를 누락하거나 권한이 부족하면 에러가 자주 발생한다.

(Aws Access Key와, Aws Secret Key를 받을 수 없다.)

 

2) 외부에서 EC2로 SSH 접속할 수 없다

우테코에서 제공한 EC2는 외부망에서 SSH 접속이 차단되어 있다.

집에서 SSH 접속을 시도했지만 실패했던 경험이 있다. 이를 통해 EC2가 내부 네트워크에서만 접근 가능단 것을 알 수 있었다.

 

이러한 환경에서는 집에서 직접 서버에 접속하거나, 수동으로 코드를 업데이트하거나, 서버가 죽었을 때 재부팅하는 것이 불가능하다.

외부에서 EC2에 접근할 수 없기 때문에, ubuntu-latest와 같은 GitHub-hosted runner는 EC2에 SSH로 접속할 수 없다.

 

3) 외부 포트 접근이 제한된다

GitHub Actions에서 EC2에 접근해 배포하거나 테스트를 수행하려면 다음과 같은 포트가 필요하다.

 

예시 1️⃣: 배포 (포트 22, SSH)

[GitHub Actions]

        ↓ (SSH 접속 시도: 포트 22)

        ↓

     [EC2 서버]

  • 목적: GitHub Actions가 EC2에 SSH 접속하여 deploy.sh 실행 및 jar 파일 복사
  • 문제: EC2의 22번 포트가 외부에 열려 있지 않아 접속이 실패한다

 

예시 2️⃣: API 테스트 (포트 8080)


[GitHub Actions]

        ↓ (HTTP 요청 시도: 포트 8080 or 3000)

        ↓

     [EC2 서버에서 실행 중인 API 서버]

  • 목적: 배포 후 /health 등의 API 엔드포인트 호출
  • 문제: EC2에서 외부 요청에 대한 포트를 차단하여 헬스체크에 실패한다

 

예시 3️⃣: DB 접속 (포트 3306)

[GitHub Actions]

        ↓ (DB 접속 시도: 포트 3306)

        ↓

     [EC2 서버에서 실행 중인 MySQL]

  • 목적: 테이블 생성, 데이터 수정, 테스트 데이터 삽입
  • 문제: DB 포트가 차단되어 있어 커넥션 실패 및 앱 오류가 발생한다

 

→ GitHub Actions가 외부에서 EC2의 특정 포트에 접속해야 하는 상황이다.

→ 즉, 이 말은 GitHub Actions가 EC2에 연결해야 할 때 포트가 막혀 있어서 접근 자체가 안 되는 상태라는 뜻.

 

 

2. Self-hosted runner로 문제 해결

Self-hosted runner란

Self-hosted runner는 EC2 내부에 직접 설치하는 GitHub Actions runner이다.

GitHub에서 작업 명령을 내리면, runner가 EC2 내부에서 이를 직접 실행한다.

따라서 포트 개방 없이도 모든 작업을 처리할 수 있다.

 

 

Polling 방식

Self-hosted runner는 2~5초마다 GitHub에 작업이 있는지 polling 요청을 보낸다.

변경 사항이 없으면 204 No Content, 변경 사항이 있으면 runner가 작업을 실행한다.

이 방식은 EC2가 능동적으로 GitHub에 요청을 보내므로, GitHub가 EC2에 직접 접속할 필요가 없다.

 

3. Self-hosted runner 도입

  1. GitHub 리포지토리의 Settings → Actions → Runners에서 New self-hosted runner를 클릭한다
  2. 제공되는 명령어를 EC2에 복사하여 실행한다
참고한 블로그: ks-peter 블로그
 

GitHub Actions self-hosted runner 설정하기

GitHub Actions를 이용하여 테스트 자동화, 배포 자동화, 기타 자동화 기능을 설정하기 위해서 Runner를 세팅하는 방법에 대한 글입니다. 기본적이 이론을 다루고 실제 세팅하는 방법에 대한 글을 작

ks-peter.tistory.com

 

4. .github/workflows 파일 수정

 

Workflow 파일에서 아래와 같이 runs-on을 self-hosted로 지정한다.

jobs:
  build:
    runs-on: self-hosted

 

 

5. Runner를 백그라운드 서비스로 등록

EC2 재시작 후에도 Runner가 자동으로 실행되도록 systemd에 등록한다.

cd actions-runner


# 서비스 등록
sudo ./svc.sh install

# 서비스 시작
sudo ./svc.sh start


# 서버 재부팅 시 자동 실행
sudo systemctl enable actions.runner.<org>-<repo>-<runner>.service

 

6. Runner 상태 확인

서비스 이름 확인

ls /etc/systemd/system/actions.runner.*.service

 

/etc/systemd/system/actions.runner.woowacourse-teams-2025-yagu-bogu.backend-runner.service

 

- org: `woowacourse-teams-2025`

- repo: `yagu-bogu`

- runner: `backend-runner`

 

 

상태 확인 명령어

sudo systemctl status actions.runner.woowacourse-teams-2025-yagu-bogu.backend-runner.service