서비스 중단 0분! Next.js Zero-downtime 배포, Atomic Swap으로 마스터하기
Next.js 배포 시 잦은 서비스 중단을 겪으셨나요? Atomic Swap 기법으로 0분 서비스 중단 배포를 구현하는 방법을 소개합니다.
서비스 중단 0분! Next.js Zero-downtime 배포, Atomic Swap으로 마스터하기
기존 Next.js 배포 방식 때문에 2~5분씩 서비스가 멈추는 일이 잦았습니다. rm -rf .next 하고 next build 하고 pm2 restart 하는 과정에서 500/502 에러가 뜨는 거죠. 이게 너무 불편해서 어떻게든 해결해보고자 했습니다.
시도와 함정
처음에는 빌드 방식을 바꿔봤습니다. .next 디렉토리를 직접 건드리지 않고 .next.new에 새 빌드를 만드는 방식이었죠. next build --distDir .next.new 이걸 사용했습니다.
# 기존 방식 (문제 발생)
rm -rf .next
next build
pm2 restart app_name
# 시도 1: 새 빌드 디렉토리 사용
next build --distDir .next.new
이렇게 새 빌드를 만들고 나서 .next 디렉토리를 어떻게 교체해야 할지 막막했습니다. 단순히 디렉토리 이름을 바꾸는 건 위험해 보였거든요.
원인
문제의 핵심은 빌드와 서버 재시작이 같은 시간대에 일어나면서 발생하는 서비스 공백이었습니다. .next 디렉토리가 완전히 사라진 상태에서 새로운 빌드가 올라오고, 그 후에 서버가 시작되니 당연히 에러가 날 수밖에 없었죠. PM2의 기본 재시작 방식으로는 이 간격을 메울 수 없었습니다.
해결
그래서 Atomic Swap 기법을 도입했습니다. 새로운 빌드가 완료되면 .next 디렉토리를 .next.old로 이름을 바꾸고, .next.new를 .next로 원자적으로 교체하는 방식입니다.
# 1. 새 빌드 생성 next build --distDir .next.new2. 기존 빌드 백업 (이름 변경)
mv .next .next.old
3. 새 빌드를 실제 디렉토리로 교체 (Atomic Swap)
mv .next.new .next
4. PM2 클러스터 모드로 순차 재시작
pm2 reload app_name
PM2 설정도 바꿔줬습니다. ecosystem.config.js에 cluster 모드와 인스턴스 2개를 설정하고, pm2 reload를 사용해서 각 인스턴스를 순차적으로 재시작하도록 했습니다.
// ecosystem.config.js
module.exports = {
apps : [{
name: "app_name",
script: "node_modules/next/dist/bin/next",
instances: 2, // 인스턴스 2개로 설정
exec_mode: "cluster", // 클러스터 모드 사용
watch: false,
env: {
NODE_ENV: "production",
},
kill_timeout: 5000 // 5초 타임아웃
}]
};
빌드 실패 시에는 .next 디렉토리가 변경되지 않으니 자동으로 이전 버전이 유지되는 셈입니다. 성공하면 .next.old 디렉토리를 정리하는 스크립트도 추가했고요.
결과
- 배포 시 500/502 에러 발생 빈도 및 시간 대폭 감소 (거의 0분)
pm2 reload를 통한 점진적 배포로 안정성 확보- 빌드 실패 시 별도 롤백 없이 이전 버전 자동 유지
redeploy.sh스크립트 한 줄로 배포 자동화 완료
정리 — 같은 함정 안 빠지려면
- [ ] 빌드 과정과 서버 재시작 과정을 분리하세요.
- [ ] 디렉토리 교체 시에는 Atomic Swap 기법을 고려해보세요. (
mv명령은 원자적입니다.) - [ ] PM2 클러스터 모드와
pm2 reload명령을 활용하여 인스턴스를 점진적으로 재시작하세요. - [ ] 빌드 실패 시 롤백 전략을 명확히 하세요. (이번 케이스는 이전 버전 유지로 해결)
- [ ] 성공적인 배포 후에는 이전 빌드 디렉토리를 정리하는 스크립트를 추가하세요.
태그
📨 박주니에게 한마디
스팸·악성 메시지 방지를 위해 구글 로그인 후 메시지를 보낼 수 있어요. 비공개로 전달되며, 운영자 외에는 볼 수 없습니다.
Google 로그인 후 메시지 남기기