DEVOPS / Automation • 2026. 02. 14

GitHub Actions를 이용한 자동 배포 환경 구축: 현대적 CI/CD의 표준

개발자에게 가장 고통스러운 순간 중 하나는 "로컬에서는 잘 되는데 서버에 올리니 안 돼요"라는 말을 듣는 순간입니다. 수동 배포는 오타, 환경 변수 누락, 빌드 누락 등 휴먼 에러의 온상입니다. eleslog.work 프로젝트가 지속적으로 업데이트될 수 있는 원동력은 바로 GitHub Actions를 통한 자동화된 CI/CD 파이프라인에 있습니다.

1. 왜 GitHub Actions인가?

기존의 Jenkins나 CircleCI와 비교했을 때 GitHub Actions가 갖는 독보적인 강점은 '통합성'입니다.

[Image of CI/CD Pipeline flow diagram]

2. CI(지속적 통합): 품질의 게이트키퍼

배포 전 가장 중요한 단계는 코드가 안전한지 검증하는 것입니다. CI 파이프라인은 개발자가 코드를 푸시하는 즉시 실행되어 린트(Lint), 테스트, 빌드 과정을 수행합니다.


name: CI Workflow
on:
  push:
    branches: [ main, develop ]
  pull_request:
    branches: [ main ]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: Setup Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20'
      - name: Install dependencies
        run: npm ci
      - name: Run Tests
        run: npm test
        

여기서 npm ci를 사용하는 이유는 package-lock.json에 명시된 버전을 엄격하게 준수하여 환경 간의 일관성을 보장하기 위함입니다.

3. CD(지속적 배포): 무중단 서비스의 핵심

빌드가 완료된 아티팩트를 실제 서버에 반영하는 과정입니다. eleslog.work에서는 보안을 위해 SSH 기반의 배포 방식을 채택했습니다. 민감한 서버 정보는 GitHub Secrets에 암호화하여 저장합니다.

Secrets 설정의 중요성

서버 IP, 사용자 이름, SSH Private Key 등은 절대로 코드에 노출되어서는 안 됩니다. Settings > Secrets and variables > Actions 메뉴에서 변수를 등록하고 사용해야 합니다.


  deploy:
    needs: test # CI 성공 시에만 실행
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    steps:
      - name: Deploy via SSH
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.SERVER_HOST }}
          username: ${{ secrets.SERVER_USER }}
          key: ${{ secrets.SSH_PRIVATE_KEY }}
          script: |
            cd /var/www/eleslog
            git pull origin main
            npm install
            npm run build
            pm2 restart all
        
실무 팁: SSH 배포 최적화
매번 npm install을 실행하는 것은 배포 속도를 늦춥니다. Docker를 활용해 이미지를 빌드하고 레지스트리에 푸시한 뒤, 서버에서는 docker pull만 실행하도록 구성하면 배포 시간을 획록적으로 단축하고 롤백이 용이해집니다.

4. 파이프라인 고도화: 캐싱과 조건부 실행

배포 속도는 개발 생산성과 직결됩니다. GitHub Actions의 Cache 기능을 사용하면 수백 메가바이트에 달하는 node_modules를 매번 새로 받지 않아도 됩니다.


      - name: Cache Node modules
        uses: actions/cache@v3
        with:
          path: ~/.npm
          key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}
          restore-keys: |
            ${{ runner.os }}-node-
        

위 설정은 package-lock.json 파일이 변경되지 않았다면 이전 빌드에서 사용했던 패키지들을 그대로 재사용하게 해줍니다. 이는 평균 빌드 시간을 2~3분 이상 단축시킵니다.

5. 모니터링 및 알림

자동화가 무조건 정답은 아닙니다. 배포가 실패했을 때 즉시 인지하는 체계가 필요합니다. GitHub Actions는 Slack, Discord 등과 연동하여 빌드 결과 알림을 보낼 수 있는 다양한 라이브러리를 지원합니다.

워크플로우의 진화:
1. 초기: 단순 SSH 스크립트 실행 (수동성 잔존)
2. 중기: GitHub Actions 도입 및 CI 테스트 자동화
3. 현재: Dockerized 환경 + Blue/Green 배포를 통한 가동중단 없는 업데이트

마치며: 자동화는 선택이 아닌 필수

현대적인 웹 개발에서 배포 자동화는 더 이상 '멋진 옵션'이 아닙니다. 비즈니스 요구사항은 시시각각 변하고, 개발자는 코드 작성에만 집중할 수 있는 환경이 조성되어야 합니다. 오늘 소개한 GitHub Actions 파이프라인을 여러분의 프로젝트에 적용해 보세요. 반복되는 수동 작업에서 해방될 때, 비로소 더 가치 있는 로직을 고민할 시간이 생길 것입니다.

다음 포스트에서는 Docker 컨테이너를 활용한 무중단 배포(Zero-downtime Deployment) 전략에 대해 더 깊게 파고들어 보겠습니다.