서론: CI/CD와 자동 배포의 중요성

효율적인 개발 워크플로우를 위한 자동 배포, 즉 CI/CD(Continuous Integration/Continuous Delivery)는 이제 선택이 아닌 필수가 되어가고 있습니다. 코드를 GitHub에 푸시(Push)했을 때, 빌드-테스트-배포 과정이 자동으로 이루어진다면 개발 생산성을 크게 높일 수 있죠.

이러한 자동 배포를 구현하는 방법에는 여러 가지가 있지만, 대표적으로 GitHub 자체에서 제공하는 GitHub Actions를 활용하는 방법과 GitHub의 Webhook 기능을 이용해 배포 로직을 직접 구현하는 방법이 있습니다.

왜 GitHub Actions 대신 직접 Webhook을 구현해야 할까?

GitHub 고양이가 Webhook 종이비행기를 Tux에게 날리는 장면

GitHub Actions는 분명 강력하고 편리한 CI/CD 도구입니다. 복잡한 워크플로우를 YAML 파일 몇 줄로 정의하고, 다양한 액션 마켓플레이스를 통해 빌드, 테스트, 배포 등 많은 과정을 자동화할 수 있습니다. 대부분의 프로젝트에서 GitHub Actions가 훌륭한 선택지임은 부정할 수 없습니다.

하지만 모든 경우에 GitHub Actions가 최적의 선택은 아닙니다. 특히 다음과 같은 상황에 계신 개발자라면, GitHub Webhook을 이용한 직접 구현 방식이 훨씬 매력적일 수 있습니다.

  • 비용에 민감한 개인 개발자 또는 소규모 팀: GitHub Actions는 공개 저장소의 경우 거의 무제한 무료이지만, 비공개 저장소에서는 일정량의 무료 할당량(minutes 및 storage)을 초과하면 과금됩니다. 아무리 소액이라도 예상치 못한 비용 발생 가능성을 완전히 차단하고 싶다면 직접 구현이 답입니다.

  • 라즈베리파이(Raspberry Pi 5)와 같은 자체 스테이징 서버를 운영 중인 개발자: 이미 물리적인 서버(VPS, 클라우드 인스턴스 포함)를 보유하고 있다면, 굳이 GitHub의 가상 환경(Runner)을 빌려 쓸 필요 없이 자체 서버의 리소스를 최대한 활용하는 것이 효율적입니다. 내 서버에서 직접 코드를 받고 배포하는 것이 비용 효율적이며, 자원 활용 측면에서도 유리합니다.

  • 배포 로직에 대한 완전한 통제와 자유를 원하는 개발자: GitHub Actions는 정형화된 워크플로우와 액션을 사용하지만, 직접 웹훅을 구현하면 배포 스크립트의 모든 부분을 원하는 대로 설계하고 제어할 수 있습니다. 특정 환경에 특화된 복잡한 커스텀 로직이나, 기존에 구축된 파이프라인과의 완벽한 통합이 필요할 때 강점을 가집니다.

이 시리즈에서는 바로 이러한 분들을 위해, GitHub Webhook을 활용하여 내 서버에 직접 배포 로직을 구현하는 방법을 상세히 다룰 것입니다. 우리는 Python 개발자를 대상으로 하며, 특히 간단하면서도 강력한 웹 프레임워크인 FastAPI를 사용하여 Webhook 엔드포인트를 구축할 예정입니다. DRF(Django REST Framework)도 훌륭한 선택이지만, 단지 Webhook 요청을 처리하는 매우 가벼운 로직이므로 FastAPI가 최적의 선택이라고 생각합니다. 슈퍼마켓에 단지 장보러 가는데 굳이 스포츠카를 타고 갈 필요없습니다. 경차로도 충분합니다.

자동 배포 시스템 구축을 위한 기본 준비물

본격적인 구현은 다음 편부터 시작됩니다. 이번 편에서는 원활한 진행을 위해 미리 준비해야 할 것들을 정리해 드립니다.

  1. GitHub 저장소:

    • 자동 배포를 적용하고자 하는 Python 프로젝트가 담긴 GitHub 저장소가 필요합니다. (공개/비공개 모두 무관)

    • 이 저장소에 코드를 푸시할 때마다 배포가 시작됩니다.

  2. 스테이징 서버 (Self-hosted Server):

    • 실제 배포가 이루어질 서버가 필요합니다. 라즈베리파이 5, 개인용 VPS(가상 사설 서버), 클라우드 인스턴스(AWS EC2, GCP Compute Engine 등) 모두 좋습니다.

    • 공용 IP 주소 또는 도메인을 통해 외부(GitHub)에서 접근 가능해야 합니다. (방화벽 설정에 유의해야 합니다.)

    • 운영체제는 Ubuntu Server와 같은 Linux 환경을 권장합니다.

    • Docker 설치: 배포되는 애플리케이션이 Docker 컨테이너 기반으로 빌드되거나 실행될 수 있도록 Docker가 서버에 미리 설치되어 있어야 합니다.

  3. Python 개발 환경:

    • 스테이징 서버에 Python 3.8 이상 버전이 설치되어 있어야 합니다. (가상 환경 사용 권장)
  4. Git:

    • 스테이징 서버에 Git이 설치되어 있어야 합니다. GitHub 저장소에서 최신 코드를 git pull 명령으로 가져올 때 사용됩니다.
  5. FastAPI 및 Uvicorn:

    • 파이썬 웹훅 엔드포인트를 구현하기 위한 프레임워크인 FastAPI와 ASGI 서버인 Uvicorn이 필요합니다. 다음 편에서 설치 및 기본 설정을 다룰 예정입니다.
  6. SSH 키:

    • 스테이징 서버에서 GitHub 저장소에 안전하게 접근하여 코드를 가져오기 위해 SSH 키 설정이 필요합니다. 대부분 이미 자신의 계정에 SSH 키등록이 되어 있을 것으로 생각합니다. (아직 등록 안되신 분들은 GitHub에 등록해두세요. 배포 키 Deploy key를 사용하는 것이 일반적입니다.)
  7. 웹 서버 (Nginx 또는 Apache2) 및 도메인/HTTPS 설정에 대한 이해:

    • GitHub Webhook은 일반적으로 HTTPS로 안전한 통신을 권장합니다. 따라서 웹훅을 받을 deployer.example.com과 같은 서브도메인을 미리 준비하고, 이 도메인에 대한 HTTPS 인증서(예: Let's Encrypt를 통한 무료 인증서) 를 발급받아 적용하는 것을 강력히 권장합니다.

    • 설마 인터넷 ISP의 라우터에서 FastAPI 애플리케이션을 직접 포트포워딩으로 연결하시는 분은 없을 것이라고 생각합니다만, 그래도 만약을 위해 부연 설명드리면, 애플리케이션은 외부에 직접 노출하기보다는, Nginx 또는 Apache2와 같은 웹 서버를 리버스 프록시(Reverse Proxy) 로 사용하여 웹훅 요청을 FastAPI 애플리케이션으로 전달하는 구성이 일반적이고 보안상 안전합니다. 반드시 서버 프로그램을 이용해서 리버스프록시로 연결하세요. 이에 대한 기본적인 이해와 설정 경험이 있다면 큰 도움이 될 것입니다.

  8. Systemd Service에 대한 이해 (선택 사항이지만 권장):

    • 이 FastAPI 웹훅 서버는 스테이징 서버에 항상 상주하며 실행되어야 합니다. 이를 위해 서버 재부팅 시에도 자동으로 시작되고, 서비스 관리(시작/중지/재시작)가 용이하도록 Systemd Service로 등록하여 운영하는 것을 권장합니다.

    • 참고: Docker 컨테이너 내부에서 git이나 docker 명령어를 직접 실행해야 하는 복잡한 배포 로직을 구성하는 것은 컨테이너 설계 목적에도 부합하지 않고, docker-in-docker 또는 docker-out-of-docker와 같은 복잡한 설정이 필요하며 보안에도 좋지 않습니다. 이미 서버에 gitdocker가 설치되어 있다면, FastAPI 웹훅 서버를 가볍게 Systemd Service로 구동하고, 배포 스크립트에서 시스템의 gitdocker 명령어를 직접 활용하는 것이 훨씬 효율적이고 간결합니다. 이 시리즈에서는 이 방식을 중심으로 설명할 것입니다.


이제 모든 준비가 되었습니다. 다음 편에서는 준비된 스테이징 서버에 FastAPI 웹훅 엔드포인트를 구축하고, GitHub Webhook을 설정하여 첫 자동 배포를 성공시키는 과정을 상세히 다루겠습니다. 기대해주세요!