GitHub Actions, CI/CD 파이프라인 없이도 git push 한 번만으로 서버에 자동 배포되는 환경을 구성할 수 있습니다. Git의 server-side hook 중 하나인 post-receive를 이용하면 됩니다.

Git Hooks란?

Git은 특정 이벤트가 발생할 때 자동으로 실행되는 스크립트인 Hooks를 지원합니다. 클라이언트 훅(pre-commit, pre-push 등)과 서버 훅(pre-receive, post-receive 등)으로 나뉩니다.

  • pre-receive — push 직전에 실행 (거부 가능)
  • post-receive — push 완료 후 실행 ← 배포에 사용

설정 방법

1단계 — 서버에 bare 저장소 만들기

서버에 SSH로 접속 후, bare 저장소를 생성합니다. Bare 저장소는 작업 디렉토리 없이 Git 데이터만 가진 저장소입니다.

# 서버에서 실행
mkdir -p ~/repos/myproject.git
cd ~/repos/myproject.git
git init --bare

2단계 — post-receive 훅 작성

vi ~/repos/myproject.git/hooks/post-receive
#!/bin/bash

# 배포 디렉토리
TARGET="/var/www/myproject"
# bare 저장소 경로
GIT_DIR="/home/deploy/repos/myproject.git"
BRANCH="main"

while read oldrev newrev refname; do
  # main 브랜치에 push 됐을 때만 배포
  if [ "$refname" = "refs/heads/$BRANCH" ]; then
    echo "🚀 배포 시작..."
    git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f "$BRANCH"
    echo "✅ 배포 완료!"
  fi
done
# 실행 권한 부여 (필수!)
chmod +x ~/repos/myproject.git/hooks/post-receive

3단계 — 로컬에서 remote 추가

# 로컬 프로젝트에서 실행
git remote add production deploy@your-server.com:repos/myproject.git

# 이제 push 한 번으로 배포
git push production main

Node.js 프로젝트에 적용하기

Node.js 프로젝트라면 배포 후 패키지 설치와 프로세스 재시작도 훅에서 처리할 수 있습니다.

#!/bin/bash
TARGET="/var/www/myapp"
GIT_DIR="/home/deploy/repos/myapp.git"

while read oldrev newrev refname; do
  if [ "$refname" = "refs/heads/main" ]; then
    echo "📦 코드 동기화..."
    git --work-tree="$TARGET" --git-dir="$GIT_DIR" checkout -f main

    echo "📦 패키지 설치..."
    cd "$TARGET"
    npm install --production

    echo "🔄 서버 재시작..."
    pm2 restart myapp

    echo "✅ 배포 완료! $(date)"
  fi
done

GitHub Pages 방식 (무료)

개인 정적 사이트라면 GitHub Pages를 활용하면 서버 없이도 push만으로 배포됩니다.

# gh-pages 브랜치에 push하면 자동 배포
git subtree push --prefix dist origin gh-pages

# 또는 npm 패키지 활용
npm install -g gh-pages
gh-pages -d dist
보안 주의사항
서버 훅 방식을 사용할 때는 배포 전용 사용자(deploy)를 따로 만들고, SSH 공개 키 인증만 허용하세요. 비밀번호 인증은 반드시 비활성화하세요.

마치며

GitHub Actions가 강력하지만, 소규모 프로젝트나 개인 서버 환경에서는 git hooks만으로도 충분한 자동화가 가능합니다. 한번 설정해두면 이후 git push production main 한 줄로 배포가 끝납니다.