GitHub Actions 워크플로
개요
아래는 maknaiagent.net(Next.js + PWA) 프로젝트용으로 즉시 사용할 수 있는 GitHub Actions 워크플로 두 가지입니다.
- deploy-ssh.yml: 자체 우분투 서버(SSH)로 빌드·아카이브 전송·릴리스 교체·pm2 재시작·헬스체크까지 자동화
- deploy-vercel.yml: Vercel에 자동 배포(간단·신속)
각 워크플로는 캐시 버전 주입, 빌드, 아티팩트 전송, 원격 배포 후 헬스체크, **롤백 준비(릴리스 폴더 보존)**를 포함합니다. 워크플로 파일과 함께 필요한 GitHub Secrets 목록과 서버 준비 체크리스트, 테스트·롤백 절차도 제공합니다.
1. deploy-ssh.yml (자체 서버 배포 — 권장)
.github/workflows/deploy-ssh.yml로 저장하세요.
name: CI/CD Deploy to SSH Server
on:
push:
branches: [ main ]
env:
NODE_VERSION: '18'
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_VERSION }}
- name: Install dependencies
run: npm ci
- name: Lint and Test (optional)
run: |
npm run lint || true
npm test || true
- name: Inject CACHE_VERSION
id: cachever
run: |
VERSION=$(date +%s)
echo "CACHE_VERSION=v${VERSION}" > .cache_version
# If using sw.js template with placeholder __CACHE_VERSION__, uncomment:
# sed -i "s/__CACHE_VERSION__/${VERSION}/g" public/sw.js
echo "version=${VERSION}" >> $GITHUB_OUTPUT
- name: Build
run: npm run build
- name: Archive build artifacts
run: |
tar -czf site_${{ steps.cachever.outputs.version }}.tar.gz .next public package.json package-lock.json
- name: Setup SSH agent
uses: webfactory/ssh-agent@v0.8.1
with:
ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
- name: Upload artifact to server
run: |
scp -P ${{ secrets.SSH_PORT }} site_${{ steps.cachever.outputs.version }}.tar.gz ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }}:/tmp/site.tar.gz
- name: Remote deploy (extract, switch, npm ci, pm2, healthcheck)
env:
DEPLOY_PATH: ${{ secrets.DEPLOY_PATH }}
RELEASE_KEEP: 5
run: |
ssh -p ${{ secrets.SSH_PORT }} ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} bash -e <<'EOF'
set -euo pipefail
DEPLOY_PATH="${DEPLOY_PATH}"
mkdir -p "${DEPLOY_PATH}/releases"
ts=$(date +%s)
release_dir="${DEPLOY_PATH}/releases/${ts}"
mkdir -p "${release_dir}"
tar -xzf /tmp/site.tar.gz -C "${release_dir}"
ln -sfn "${release_dir}" "${DEPLOY_PATH}/current"
cd "${DEPLOY_PATH}/current"
# install production deps
npm ci --production
# start or restart pm2 process
if pm2 list | grep -q "maknai-frontend"; then
pm2 restart maknai-frontend || pm2 start npm --name maknai-frontend -- start
else
pm2 start npm --name maknai-frontend -- start
fi
pm2 save
# health check (adjust URL if needed)
sleep 2
curl -fS https://www.maknaiagent.net/ || (echo "Health check failed" && exit 1)
# cleanup old releases
ls -1dt "${DEPLOY_PATH}/releases"/* | tail -n +$((RELEASE_KEEP+1)) | xargs -r rm -rf
EOF
필요한 GitHub Secrets
SSH_PRIVATE_KEY(CI용 개인키, PEM)SSH_HOST(서버 IP 또는 도메인)SSH_PORT(기본 22)SSH_USER(예: ubuntu)DEPLOY_PATH(예:/home/ubuntu/maknai-frontend)NEXT_PUBLIC_WP_API(선택: 빌드 시 환경변수)
서버 준비 체크
- SSH 공개키가
~/.ssh/authorized_keys에 추가되어야 함 - Node.js 18+, npm, pm2 설치
DEPLOY_PATH에 쓰기 권한(배포 사용자)- HTTPS/Certbot 설정 완료(헬스체크용)
2. deploy-vercel.yml (Vercel 자동 배포)
.github/workflows/deploy-vercel.yml로 저장하세요.
name: Deploy to Vercel
on:
push:
branches: [ main ]
jobs:
vercel-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: '18'
- name: Install
run: npm ci
- name: Inject CACHE_VERSION env
run: echo "NEXT_PUBLIC_CACHE_VERSION=$(date +%s)" >> $GITHUB_ENV
- name: Deploy to Vercel
uses: amondnet/vercel-action@v20
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }}
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }}
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }}
working-directory: .
prod: true
필요한 GitHub Secrets
VERCEL_TOKEN,VERCEL_ORG_ID,VERCEL_PROJECT_IDNEXT_PUBLIC_WP_API(Vercel 환경변수로도 설정 가능)
3. 캐시 버전 주입 및 무효화 권장 방식
- 권장: CI에서
CACHE_VERSION을 타임스탬프 또는 Git SHA로 생성해public/sw.js의 캐시 네임에 주입하거나NEXT_PUBLIC_CACHE_VERSION으로 빌드 환경변수에 주입. - 예시(파일 치환):
VERSION=$(git rev-parse --short HEAD) sed -i "s/__CACHE_VERSION__/${VERSION}/g" public/sw.js - 무중단 전환: 릴리스 디렉터리 +
current심볼릭 링크 방식으로 롤백·보존(keep N releases).
4. 배포 후 테스트·롤백 절차
- 헬스체크 실패 시 자동 실패: 워크플로에서
curl -fS https://...로 확인. 실패하면 워크플로가 실패 상태가 됨. - 수동 롤백(서버):
cd /home/ubuntu/maknai-frontend ls -1dt releases/* # 확인 ln -sfn releases/<previous_ts> current cd current pm2 restart maknai-frontend - 자동 롤백 확장: 워크플로에 실패 감지 후 이전 릴리스로 되돌리는 스텝을 추가 가능(원격 스크립트에 구현 권장).
5. 보안·운영 권장사항
- CI용 SSH 키는 passphrase 없이 생성하되, GitHub Secret으로 안전 보관. 공개키는 서버에만 추가.
NEXT_PUBLIC_*환경변수는 민감정보를 포함하지 않도록 주의. 민감정보는 서버에서만 사용.- 배포 전
npm run build와npm run lint를 CI에서 항상 실행. - 모니터링(예: Sentry, UptimeRobot)과 Slack 알림을 연동해 배포 성공/실패를 팀에 통보.
다음 단계로 제가 할 수 있는 작업: (1) 이 워크플로를 귀하의 리포지토리 구조(예: 빌드 스크립트 이름, 배포 경로)와 GitHub Secrets 값에 맞춰 완전 맞춤형 YAML로 생성하거나, (2) 원격 서버에서 실행될 배포 보조 스크립트(릴리스 관리·롤백 포함)를 만들어 드릴 수 있습니다. 원격 서버 정보(호스트, 사용자, 배포 경로)와 원하는 옵션을 알려주시면 맞춤 워크플로를 생성하겠습니다.
