Develop
Next.js 정적 사이트를 Jenkins로 자동 배포하는 방법 — Jenkinsfile로 빌드부터 배포까지
Next.js 프로젝트를 output: 'export' 설정으로 정적 빌드한 뒤, Jenkins 파이프라인을 구축해 원격 운영 서버로 자동 배포하는 정석 프로세스를 알아봅니다. Credentials를 통한 SSH 안전 연동 팁도 다룹니다.

- ·output: 'export': next.config.ts에 설정 시 빌드 결과가 out/ 폴더에 정적 파일로 생성됨
- ·npm ci: package-lock.json 기준으로 정확히 고정된 버전 설치. npm install보다 재현성이 높음
- ·scp: SSH 프로토콜 기반 파일 전송 명령. 별도 소프트웨어 설치 없이 SSH 접근 권한만으로 사용 가능
- ·withCredentials: Jenkins Credentials에 저장된 SSH 키를 환경변수로 안전하게 전달하는 블록
매번 로컬 컴퓨터에서 `npm run build` 돌려서 생성된 out 폴더를 윈도우 파일 탐색기 열고 파일 서버 경로에 복사해 넣던 수동 마이그레이션 시절이 있었습니다. 도중 실수로 파일 누락이 나서 사이트 레이아웃이 꿀렁이며 깨지는 장애를 겪고 나서 바로 Jenkins 자동 배포 파이프라인을 구축했죠. Checkout, Install, Build, Deploy 순서로 명확하게 쪼개놓고 실행하니 어디서 문제가 났는지 시각적으로 바로 잡혀서 속이 다 시원했습니다. 배포 단계에서 대상 서버와의 SSH 연동을 뚫는 과정에서 인증 키 보안 노출 때문에 꽤 고민을 많이 했었는데, Jenkins Credentials에 Private Key를 고이 박아두고 `withCredentials` 블록으로 안전하게 바인딩해 호출하는 방식으로 정석 우회를 성공했습니다. 적용 후에는 push 한 번이면 로컬 리소스 점유 없이 단 1분 만에 고속 배포가 끝나서 삶의 질이 달라졌습니다.
1. 빌드 자동화와 아키텍처 설계
서버 오버헤드를 낮추는 Next.js 정적 빌드와 Jenkins의 연결점
Next.js 앱을 백엔드 Node 서버 없이 순수 정적 파일 형태로 가볍게 서비스하려면 next.config.ts 파일 내에 output: 'export' 설정을 매핑해 주어야 합니다. 이렇게 빌드를 돌려주면 CSS, JS, HTML 뼈대 파일 및 이미지 정적 리소스 세트가 out/ 폴더 안으로 가볍게 응축되어 생성되죠. 이 out 폴더 전체를 Nginx 웹서버가 리스닝 중인 디렉토리에 덮어쓰기만 하면 번거로운 런타임 설치 없이 초고속 웹 서빙 환경이 마련됩니다. Jenkins는 이러한 깃 소스 획득부터 의존성 패키지 설치, 빌드 컴파일 완료 후 생성된 정적 패키지 폴더를 운영 리눅스 서버로 무사히 복사 전송해 주는 일련의 가동 단계를 일관성 있게 조립해 주는 중앙 사령탑의 역할을 도맡아 돌아갑니다.
파이프라인 단계별 성공 여부를 시각화하는 Jenkins 자동 배포 파라미터
좋은 배포 파이프라인은 복잡한 배포 태스크를 개발자가 단번에 인지할 수 있는 명확한 단계(Stage)로 나누어 설계하는 데서 출발합니다. Next.js 빌드 파이프라인의 경우 크게 코드 동기화를 전담하는 'Checkout', 패키지를 인스톨하는 'Install', out 폴더를 뱉어내는 'Build', 최종 목적지 서버에 파일을 이식하는 'Deploy' 스테이지로 4단 격리를 적용해 주는 것이 국룰이죠. 이렇게 구조화해 두면 배포 실패가 일어났을 때, 의존 모듈 꼬임이 문제인지 아니면 대상 서버의 네트워크 포트 락이 문제인지 Jenkins 파란/빨간 모니터링 대시보드 화면에 한눈에 명세화되므로 실무 디버깅 복구 시간을 경이롭게 줄일 수 있습니다.
2. 패키지 인스톨 및 정적 컴파일 단계 구현
프로젝트 빌드를 구동하는 Jenkinsfile 내 Next.js 설정 기법
본격적인 연동을 위해 프로젝트 루트에 젠킨스파일을 열고 빌드 구조를 매핑합니다. tools에는 격리된 Node 18 환경 등을 엮어두고, stages 아래에 순서대로 작업 명령을 기술하죠. 이때 Next.js 빌드 도중 환경 설정 파일(.env.production 등)이 제대로 물려 들어가도록, 필요한 환경 변수 스키마를 pipeline environment 블록 내에 안전하게 매핑해 두는 세심함이 필요합니다. 빌드 서버에서 미리 셋업된 구성 매개변수들은 Next.js 컴파일 러너 안으로 자연스럽게 주입되어 out 폴더 내부의 HTML 소스코드에 데이터 토큰으로 아름답게 박혀 들어갑니다.
패키지 의존성을 유지하는 npm ci 명령어와 Next.js 빌드 환경
빌드서버에서 의존 패키지를 다운로드할 때는 npm install 대신 반드시 npm ci 명령어를 활용해야 인프라가 꼬이지 않습니다. npm install은 package.json의 버전 틸드/캐럿 범위 규칙을 해석하여 구동 시점의 가장 신규 라이브러리를 동적으로 다운받기 때문에, 로컬에서 잘 돌던 프로그램이 CI 서버의 엉뚱한 의존성 꼬임으로 컴파일 크래시를 유발할 수 있죠. 반면 npm ci는 오직 package-lock.json에 기재된 잠금 버전 트리 정보만 그대로 추종하여 고정 다운로드하므로, 협업 팀원 모두와 빌드 서버 전체가 단 1바이트의 오차도 없이 동일한 모듈 팩을 유지하며 안전하게 Next.js 정적 빌드를 완수하게 지켜줍니다.
3. 보안 연동 및 파일 복사 배포
보안 자격증명을 활용해 Jenkins에서 운영 서버로 파일 전송하기
컴파일이 완성되어 out 폴더가 마련되었다면, 이제 이를 운영 리눅스 장비로 복사 전송해야 합니다. 이때 SSH 원격 터널을 안전하게 타기 위한 개인키(Private Key) 정보를 코드상에 날것으로 기재해 두면 깃 저장소 스캔 도구에 걸려 보안 경고가 터지죠. Jenkins가 지원하는 Credentials 매니저에 SSH 키를 비밀 토큰으로 격리 등록한 뒤, 파이프라인 내부에서는 withCredentials 래퍼 헬퍼를 소환해 메모리상에만 임시로 보안 변수(SSH_KEY)를 활성화해 매핑하는 것이 정석 패턴입니다. 이후 scp 전송 명령에 -i $SSH_KEY 인자를 붙여 실행해 주면 소스 노출 걱정 없는 철저한 무균 배포 라인이 성립됩니다.
pipeline {
agent any
tools {
nodejs 'NodeJS 18'
}
stages {
stage('SCM Checkout') {
steps {
checkout scm
}
}
stage('Install Modules') {
steps {
sh 'npm ci'
}
}
stage('NextJS Export Build') {
steps {
sh 'npm run build'
}
}
stage('Secure Target Deploy') {
steps {
withCredentials([sshUserPrivateKey(
credentialsId: 'web-server-ssh-key',
keyFileVariable: 'SSH_KEY'
)]) {
// StrictHostKeyChecking=no 플래그를 추가해 첫 접속 시 interactive confirm 락이 걸리는 현상 예방
sh 'scp -r -i $SSH_KEY -o StrictHostKeyChecking=no out/* root@123.45.67.89:/var/www/my-next-app/'
}
}
}
}
}웹 서버 루트 설정을 맞춰 Next.js 배포 최종 점검하기
원격 전송이 문제없이 마감되었다면 마지막 점검 대상은 배포 목적지 서버의 Nginx 또는 Apache 웹서버 설정 상태입니다. 전송한 out/ 디렉토리 내의 알맹이 파일들(index.html, _next 등)이 위치한 경로를 Nginx 설정 파일(nginx.conf) 내 root 지시어가 한 치의 오차도 없이 일직선으로 바라보고 있는지 경로를 꼭 대조해 봐야 합니다. 경로 세팅을 잘못 잡아서 404 Not Found 에러가 뜨는 실무 실수가 잦기 때문이죠. 배포 성공 즉시 파이프라인의 post { success } 구문 내부에 curl 테스트 커맨드를 태워 원격 도메인 리턴 코드가 200 OK를 뱉는지 자동 검진까지 묶어 두면 인간의 수동 확인 공수조차 없애주는 신의 배포망이 조립 완료됩니다.
자주 묻는 질문
Next.js 빌드를 돌렸는데 out/ 폴더 대신 .next/ 폴더만 덩그러니 생기고 파일 전송 단계에서 에러가 납니다.+
Next.js는 기본 설정 시 정적 파일 추출 대신 Node 런타임 서버 구동용 빌드를 진행합니다. 정적 배포망을 개설하시려면 프로젝트 내 `next.config.ts` 파일의 설정 객체 하단에 `output: 'export'` 속성을 명시적으로 주입해 빌드 형식을 정적 패키지 타입으로 토글하셔야 out 폴더가 정상 생성됩니다.
Deploy 스테이지 가동 중에 Host key verification failed 경고창이 뜨며 접속이 끊겨요.+
젠킨스 가상 컨테이너가 배포 목적지 원격 서버에 태어나서 처음으로 접속할 때, 상대방의 보안 지문을 등록할지 물어보는 쉘 대기 락이 걸렸기 때문입니다. scp 명령어 옵션에 `-o StrictHostKeyChecking=no` 플래그를 심어주면 첫 통신 시의 신원 확인 프롬프트 승인 과정을 강제 패스하고 논스톱으로 파일을 전송해 줍니다.
관련 글
Jenkins 빌드 스케줄러 완벽 가이드 — Jenkinsfile에 cron 트리거 추가하는 방법
Jenkins UI에서 직접 관리하던 파이프라인을 Jenkinsfile로 전환하고, cron 트리거로 매일 자동 빌드를 구성하는 방법을 정리했습니다. H 표현식을 이용한 부하 분산과 UTC 시간대 대처 팁까지 상세히 다룹니다.
Jenkins Pipeline에서 Node.js 버전 고정하는 방법 — tools 블록과 NodeJS 플러그인 설정
Jenkins 빌드 환경에서 서버 Node.js 버전에 흔들리지 않고 개발 환경과 통일하는 방법을 다룹니다. NodeJS 플러그인 설치 및 Global Tool Configuration 등록, Jenkinsfile tools 블록 적용법을 정리했습니다.