개발자에게 가장 고통스러운 순간 중 하나는 "로컬에서는 잘 되는데 서버에 올리니 안 돼요"라는 말을 듣는 순간입니다. 수동 배포는 오타, 환경 변수 누락, 빌드 누락 등 휴먼 에러의 온상입니다. eleslog.work 프로젝트가 지속적으로 업데이트될 수 있는 원동력은 바로
GitHub Actions를 통한 자동화된 CI/CD 파이프라인에 있습니다.
1. 왜 GitHub Actions인가?
기존의 Jenkins나 CircleCI와 비교했을 때 GitHub Actions가 갖는 독보적인 강점은 '통합성'입니다.
- 완전 관리형: 별도의 서버(Master) 설치 없이 GitHub 저장소 내에서
.yaml파일 하나로 모든 정의가 끝납니다. - 강력한 생태계: GitHub Marketplace에는 이미 수천 개의 미리 만들어진 Actions가 존재합니다. SSH 접속, Docker 이미지 푸시 등을 직접 구현할 필요가 없습니다.
- 이벤트 중심:
push,pull_request뿐만 아니라issue생성,release태그 등 거의 모든 GitHub 활동을 트리거로 삼을 수 있습니다.
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
매번
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) 전략에 대해 더 깊게 파고들어 보겠습니다.