GitHub 자동배포 방식 3가지 요약

  • SSH 연동(서버에서 git pull + 재시작): 제일 단순, 빨리 붙음. 대신 운영/보안/롤백/가시성이 약해지기 쉬움.
  • GitHub Actions Runner(자가 호스팅 러너): CI/CD 표준에 가깝고 확장성 좋음. 대신 러너 운영/보안/네트워크 설계가 필요.
  • Watchtower(Docker 이미지 감시 자동 업데이트): “이미지 태그만 갱신되면 알아서 교체”라 편함. 대신 제어력/안정성/승인 프로세스가 약해 운영환경엔 제약이 큼.

1) SSH 연동 방식 (서버 Pull 방식)

핵심 구조

GitHub에 push → (GitHub Actions or Webhook) → 서버 SSH 접속 → git pull → 빌드/재시작(또는 docker compose restart)

사용법(대표 패턴 2개)

A. GitHub Actions에서 SSH로 서버 명령 실행

  1. 서버 준비
  • 배포 계정 생성(예: deploy)
  • 앱 디렉터리 권한/소유자 정리
  • (선택) docker, docker-compose 설치
  • 방화벽에서 SSH(22) 접근 제어(사내 IP/VPN만 허용 권장)
  1. SSH 키 준비
  • 로컬에서 deploy 전용 키 생성
  • 서버 ~deploy/.ssh/authorized_keys 등록
  • GitHub Repo Secrets에 SSH_PRIVATE_KEY, HOST, USER, PORT 저장
  1. Actions Workflow 구성
  • main 브랜치 push 시
  • SSH 접속해서:
    • cd /srv/app && git pull
    • ./gradlew build 또는 docker compose pull && docker compose up -d --build
    • 헬스체크(예: /actuator/health) 호출

B. 서버가 “스스로” 땡겨가는 방식(크론/웹훅)

  1. 서버에 webhook 수신기(간단한 endpoint) 설치 또는 cron으로 주기적 pull
  2. 트리거되면 git pull + 재시작
  3. GitHub Webhook에서 서버 endpoint 호출

장점

  • 붙이기 제일 빠름 (학습/구성 최소)
  • 서버가 단일대/소규모일 때 생산성 좋음
  • 네트워크 단순(서버가 GitHub 접근만 가능하면 됨)

단점(운영에서 터지는 지점)

  • “서버에 소스코드가 직접 존재” → 권한/비밀키/환경변수 관리가 지저분해지기 쉬움
  • 빌드가 서버에서 돌면 서버 자원 소모 + 빌드 재현성 약함
  • 롤백/버전 관리가 대충 되기 쉬움(태그/릴리즈 강제하지 않으면 더 심함)
  • 여러 서버로 확장 시 스크립트 지옥(순서/동기화/부분 실패 처리)

언제 추천?

  • 개인 프로젝트 / PoC / 내부 유틸 / 서버 1대
  • “오늘 당장 자동배포 붙여야 한다” 수준의 긴급 대응

 

2) GitHub Actions Runner(자가 호스팅 러너) 방식

핵심 구조

GitHub에 push → GitHub Actions 실행 → 내 서버(또는 사내망)의 self-hosted runner가 job을 직접 수행 → 빌드/배포/재시작

사용법(실전 흐름)

  1. Runner 설치 위치 결정
  • 배포 대상 서버에 러너 설치(단순)
  • 또는 별도 CI 서버에 러너 설치 후 대상 서버로 배포(더 안전/표준)
  1. 러너 설치/등록
  • GitHub Repo/Org Settings → Actions → Runners → self-hosted 등록
  • 서버에 러너 패키지 설치 후 토큰으로 등록
  • 러너 계정 권한 최소화(필요한 명령만 sudo 허용)
  1. 배포 파이프라인 구성(권장)
  • CI 단계: 테스트/빌드/이미지 빌드/취약점 스캔
  • CD 단계:
    • docker image push(ghcr.io 등)
    • 서버에서 docker compose pull && up -d
    • 헬스체크 통과 시 성공 처리
    • 실패 시 자동 롤백(이전 태그로 되돌리기)
  1. 보안/운영 필수 체크
  • 러너는 “코드 실행 권한”이므로 신뢰할 수 있는 브랜치/워크플로만 실행되게 제한
  • PR에서 러너가 돌아가면 위험(특히 public repo) → protected branch + required reviews + environments 승인 같은 가드 필요
  • 러너 업데이트/재시작/로그 관리 필요

장점

  • GitHub Actions의 표준 기능을 그대로 활용(조건, 매트릭스, 환경승인, 시크릿, 아티팩트)
  • 폐쇄망/사내망 배포에 강함 (러너가 내부에 있으니 GitHub가 직접 내부 접근 안 해도 됨)
  • 단계별 로그/감사추적이 좋아서 운영/협업에 유리
  • 멀티서비스/멀티서버로 확장 쉬움(라벨로 runner 그룹 분리)

단점

  • 러너 자체가 또 하나의 “운영 대상”
  • 권한 설계가 허술하면 러너가 곧 서버 루트권한 통로가 됨
  • 러너 장애/디스크/캐시로 CI가 불안정해질 수 있음

언제 추천?

  • 팀 개발 / 운영 배포 / 멀티 서비스
  • 사내망·폐쇄망·VPN 환경
  • “CI/CD를 프로세스로 관리”하고 싶은 경우

3) Watchtower(Docker) 전용 방식

핵심 구조

서버에서 Watchtower 컨테이너가 돌아감 → 특정 컨테이너의 이미지 태그를 주기적으로 확인 → 새 이미지면 자동 pull + 재기동

사용법(실전 순서)

  1. 전제 조건
  • 앱이 Docker 이미지로 배포되어야 함
  • 레지스트리(GHCR, Docker Hub, ECR 등)에 이미지 push가 되어야 함
  1. 이미지 태그 전략 결정(중요)
  • 운영에서는 latest 남발하면 사고 확률↑
  • 권장: app:2026.03.05-1234 같은 불변 태그 + (선택) prod 같은 이동 태그
  1. 서버에 docker compose로 구성
  • app 서비스 + watchtower 서비스
  • watchtower가 감시할 컨테이너를 label로 지정하거나 이름으로 지정
  • private registry면 pull 권한(docker login) 세팅
  1. 알림/롤백 고려
  • Watchtower는 “업데이트는 쉬운데, 실패시 자동 복구는 제한적”
  • 최소한 Slack/Email 알림 연동은 붙여두는 게 좋음

장점

  • 운영 단순성 최고: 이미지 push만 하면 서버가 알아서 따라옴
  • 배포 도구/스크립트 최소화
  • 작은 서비스/개인 운영에서 효율 좋음

단점(중요)

  • 배포 승인/점검/릴리즈 노트 같은 프로세스 제어가 약함
  • “새 이미지 = 곧바로 적용”이라 장애 전파가 빠를 수 있음
  • 복잡한 마이그레이션(DB 스키마 변경 등)과 궁합이 나쁨
  • 멀티 인스턴스/무중단/카나리 같은 고급 배포는 한계

언제 추천?

  • 개인 서비스 / 내부 도구 / 다운타임 허용
  • “이미지 기반 운영을 매우 단순하게” 가져가고 싶은 경우

4) 3가지 방식 비교표(의사결정용)

항목                               SSH                         PullActions Runner                                    Watchtower
도입 난이도 ⭐ (가장 쉬움) ⭐⭐⭐ ⭐⭐
운영 안정성 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐~⭐⭐⭐(규모 커지면 흔들림)
보안 통제 ⭐⭐ ⭐⭐⭐⭐(잘하면 최상) ⭐⭐
감사/로그/추적 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐
롤백 용이성 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐
멀티서버 확장 ⭐⭐ ⭐⭐⭐⭐ ⭐⭐
권장 규모 1대/소규모 팀/프로덕션 개인/단순 운영

 

5) 결론: 뭐를 선택해야 하나(실무 기준)

  • 서버 1대, 빨리 끝내야 함SSH 방식
  • 운영/팀/폐쇄망/감사로그 필요GitHub Actions Runner
  • Docker 이미지 기반 + 초간단 자동업데이트Watchtower (단, 운영은 태그 전략/알림/점검 최소 장치 필수)
LIST

+ Recent posts