Next.js Ubuntu 배포 가이드

Apache2 리버스 프록시 + Certbot SSL + PM2 프로세스 관리

Ubuntu 24.04 Apache 2.4.58 Node.js 22.17 Next.js 16.1 PM2
클라이언트 → HTTPS :443 → Apache2 (리버스 프록시) → localhost:5010 → Next.js (PM2)
1

Apache2 리버스 프록시 설정

여기서 포트 5010 은 임의로 지정한 포트입니다.
서버에서 지원하는 포트로 바꾸시면 됩니다.

Next.js는 자체 서버(포트 5010)로 실행되므로, Apache를 리버스 프록시로 설정하여 도메인과 연결합니다.

필요 모듈 활성화

bash
sudo a2enmod proxy proxy_http proxy_wstunnel rewrite headers
sudo systemctl restart apache2

사이트 설정 파일 생성

bash
sudo nano /etc/apache2/sites-available/your-domain.com.conf
apache
<VirtualHost *:80>
    ServerName your-domain.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5010/
    ProxyPassReverse / http://127.0.0.1:5010/

    # WebSocket 지원
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule /(.*) ws://127.0.0.1:5010/$1 [P,L]

    ErrorLog  ${APACHE_LOG_DIR}/your_domain_error.log
    CustomLog ${APACHE_LOG_DIR}/your_domain_access.log combined
</VirtualHost>

사이트 활성화

bash
sudo a2ensite your-domain.com.conf
sudo systemctl reload apache2
참고
ProxyPreserveHost On — 원래 호스트 헤더를 Next.js에 전달합니다.
WebSocket 설정은 개발 시 HMR 또는 실시간 기능에 필요합니다.
2

Certbot SSL 인증서 발급

Certbot 설치

bash
sudo apt install certbot python3-certbot-apache -y

인증서 발급 (Apache 자동 설정)

bash
sudo certbot --apache -d your-domain.com

실행하면 다음이 자동으로 처리됩니다:

자동 생성되는 SSL 설정

apache
<IfModule mod_ssl.c>
<VirtualHost *:443>
    ServerName your-domain.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:5010/
    ProxyPassReverse / http://127.0.0.1:5010/

    # WebSocket 지원
    RewriteEngine On
    RewriteCond %{HTTP:Upgrade} websocket [NC]
    RewriteCond %{HTTP:Connection} upgrade [NC]
    RewriteRule /(.*) ws://127.0.0.1:5010/$1 [P,L]

    ErrorLog  ${APACHE_LOG_DIR}/your_domain_error.log
    CustomLog ${APACHE_LOG_DIR}/your_domain_access.log combined

    SSLCertificateFile    /etc/letsencrypt/live/your-domain.com/fullchain.pem
    SSLCertificateKeyFile /etc/letsencrypt/live/your-domain.com/privkey.pem
    Include /etc/letsencrypt/options-ssl-apache.conf
</VirtualHost>
</IfModule>

자동 갱신 확인

bash
sudo certbot renew --dry-run
주의
Let's Encrypt 인증서는 90일마다 만료됩니다. Certbot이 자동 갱신 타이머를 등록하지만,
systemctl list-timers | grep certbot으로 정상 등록 여부를 확인하세요.
3

PM2 Ecosystem 설정

PM2 전역 설치

bash
npm install -g pm2

ecosystem.config.js 생성

javascript
module.exports = {
  apps: [
    {
      name: "project_name",
      script: "node_modules/.bin/next",
      args: "start -p 5010",
      cwd: "/home/user/project_folder",
      interpreter: "/home/user/.local/share/fnm/node-versions/v22.17.0/installation/bin/node",
      env: {
        NODE_ENV: "production",
      },
      exec_mode: "fork",
      instances: 1,
      autorestart: true,
      watch: false,
      max_memory_restart: "512M",
    },
  ],
};

옵션 설명

옵션 설명
script next CLI 경로 (npx 대신 직접 지정하여 안정적 실행)
args next start -p 5010 — 포트 번호 지정
cwd 프로젝트 루트 경로
interpreter fnm/nvm 사용 시 Node.js 전체 경로 지정 필수
max_memory_restart 메모리 512MB 초과 시 자동 재시작
autorestart 크래시 발생 시 자동 재시작
fnm / nvm 사용자 필독
fnm이나 nvm으로 Node.js를 설치한 경우, interpreter에 전체 경로를 반드시 명시해야 합니다.
which node 명령으로 경로를 확인하세요. 생략하면 PM2가 시스템 기본 Node를 사용하여 버전 불일치가 발생할 수 있습니다.
4

빌드 및 PM2 실행

프로덕션 빌드

bash
cd ~/project_folder
npm run build

최초 실행

bash
pm2 start ecosystem.config.js

재배포 (업데이트 시)

bash
cd ~/project_folder
git pull
npm install
npm run build
pm2 restart project_name

PM2 주요 명령어

명령어 설명
pm2 list 실행 중인 프로세스 목록
pm2 logs project_name 실시간 로그 확인
pm2 show project_name 프로세스 상세 정보
pm2 restart project_name 재시작
pm2 stop project_name 중지
pm2 delete project_name 프로세스 삭제

서버 재부팅 시 자동 시작

bash
pm2 startup
pm2 save
참고
pm2 startup 실행 후 출력되는 sudo env PATH=... 명령어를 복사해서 실행하면,
서버 재부팅 시 PM2와 등록된 앱이 자동으로 시작됩니다.