GitHub·자동화

Windows Runner를 AWS로 옮기면서 자동화를 끊지 않기 위해 확인한 것

개발 자동화를 집의 Windows PC에서 오래 돌리다 보니 한계가 생겼다. 절전이나 재부팅, 로컬 환경 변화에 따라 작업이 끊길 수 있었고, 내가 자리를 비운 동안에도 일정하게 돌아가는 개발 서버가 필요했다.

그래서 self-hosted GitHub Actions Runner를 AWS의 Ubuntu ARM64 서버로 옮기기 시작했다.

실제로 옮긴 서버 환경

이번 전환은 일반적인 “Ubuntu에 Runner 설치하기” 예제가 아니라 기존 자동화 도구가 모두 같은 방식으로 돌아가는지 확인하는 작업이었다. 당시 새 서버는 다음 구성으로 맞췄다.

  • OS: Ubuntu 24.04 ARM64
  • 자원: 2 vCPU / 2GB RAM + 4GB swap
  • Node: 22.23.3
  • npm / pnpm: 10.9.9 / 12.6.0
  • Git / GitHub CLI: 2.43.0 / 2.45.0
  • OpenCode: 1.18.32
  • codex-cli: 0.157.1
  • PowerShell: 7.6.6 ARM64

버전 숫자 자체보다 중요한 것은 대화형 셸에서 설치됐다는 사실과 Runner 서비스가 실제로 실행할 수 있다는 사실이 다르다는 점이었다.

새 Runner를 만들었다고 기존 Runner를 바로 끄지 않았다

전환에서 가장 먼저 정한 원칙은 교체가 아니라 병행 검증이었다.

기존 Windows Runner는 그대로 두고 AWS 전용 label을 가진 새 Runner를 추가했다. 실제 workflow가 새 label을 명시할 때만 AWS에서 실행되게 했다.

이렇게 하면 문제가 생겼을 때 기존 경로로 돌아갈 수 있고, 의도하지 않은 작업이 새 서버에서 실행되는 것도 막을 수 있다.

ARM64에서는 설치보다 PATH가 더 자주 문제였다

설치 자체가 성공해도 systemd로 실행되는 Runner가 로그인 셸과 같은 PATH를 보는 것은 아니었다. NVM으로 설치한 Node가 대화형 터미널에서는 보이는데 Runner에서는 찾지 못하는 식의 차이가 생겼다.

그래서 “설치됨”이 아니라 Runner 서비스 계정에서 실제 명령이 실행되는지를 기준으로 확인했다.

ARM64용 PowerShell처럼 아키텍처에 맞는 바이너리도 별도로 확인했다. Windows Runner에서 Linux 명령이 섞여 실패했던 이전 경험 때문에, OS와 shell 정보 역시 작업 packet에 명시하도록 했다. 이 문제는 Windows Runner에서 Linux 명령이 나왔을 때 알게 된 것에 따로 정리했다.

작은 서버에서는 자원 부족도 실패 원인이 된다

2 vCPU, 2GB RAM 정도의 작은 인스턴스에서는 여러 도구가 동시에 뜨면 메모리가 빠듯해질 수 있었다. 그래서 4GB swap을 추가하고, 한 번에 실행되는 작업 수와 재시도 범위를 제한했다.

AI 작업은 실패했을 때 무한히 다시 실행하는 것보다 언제 멈추고 복구할지 정하는 편이 중요했다.

전환의 마지막 검증은 격리와 알림이었다

새 Runner에서 한 작업이 끝난 뒤 토큰이나 임시 상태가 다음 작업에 남지 않는지 확인했다. 그리고 작업 시작·완료·실패가 외부 알림으로 제대로 전달되는지도 smoke test로 확인했다.

최종적으로 확인한 것은 다음과 같다.

  • AWS 전용 label로만 작업이 들어오는가
  • 작업 종료 뒤 민감한 상태가 남지 않는가
  • 실패 시 bounded retry와 복구가 동작하는가
  • 기존 Windows Runner로 돌아갈 수 있는가
  • 사람이 작업 상태를 외부에서 확인할 수 있는가

Runner 이전에서 중요한 것은 서버를 한 대 더 만드는 일이 아니었다.

자동화가 실행되는 장소가 바뀌어도 작업의 경계와 복구 방식이 그대로 유지되는지 확인하는 것이 실제 cutover였다.

How this note was made

이 글은 실제 개발 기록을 바탕으로 작성했습니다

일반적인 개발 팁을 재구성한 글이 아니라 Yeomflow의 실제 제품 개발, 배포, 장애 대응, 자동화 과정에서 나온 문제와 결정을 정리합니다. 이후 구현이나 운영 기준이 바뀌면 기존 글도 보강합니다.

작성 원칙과 프로젝트 소개 보기 →