웹사이트 검색

Rocky Linux 9에서 프로덕션용 Node.js 애플리케이션을 설정하는 방법


소개

Node.js는 서버 측 및 네트워킹 애플리케이션을 구축하기 위한 오픈 소스 JavaScript 런타임 환경입니다. 플랫폼은 Linux, macOS, FreeBSD 및 Windows에서 실행됩니다. 명령줄에서 Node.js 애플리케이션을 실행할 수 있지만 이 자습서에서는 애플리케이션을 서비스로 실행하는 데 중점을 둡니다. 이는 재부팅 또는 실패 시 다시 시작되며 프로덕션 환경에서 사용하기에 안전함을 의미합니다.

이 튜토리얼에서는 단일 Rocky Linux 9 서버에 프로덕션 준비가 된 Node.js 환경을 설정합니다. 이 서버는 Let’s Encrypt에서 관리하는 Node.js 애플리케이션을 실행합니다.

전제 조건

이 가이드에서는 다음이 있다고 가정합니다.

  • Rocky Linux 9의 초기 서버 설정 가이드에 설명된 대로 Rocky Linux 9 서버 설정. sudo 권한이 있는 루트가 아닌 사용자와 활성 방화벽이 있어야 합니다.
  • 전체 example.com.
  • Rocky Linux 9에 Nginx를 설치하는 방법에 설명된 대로 Nginx가 설치되었습니다.
  • Let’s Encrypt 인증서를 사용하여 SSL로 구성된 Nginx. Rocky Linux 9에서 Let’s Encrypt로 Nginx를 보호하는 방법이 프로세스를 안내합니다.
  • 서버에 설치된 Node.js. Rocky Linux 9에 Node.js를 설치하는 방법\n

전제 조건을 완료하면 https://example.com/에서 도메인의 기본 자리 표시자 페이지를 제공하는 서버를 갖게 됩니다.

1단계 — Node.js 애플리케이션 만들기

모든 HTTP 요청에 대해 "Hello World\를 반환하는 Hello World 애플리케이션을 작성해 보겠습니다. 이 샘플 애플리케이션은 Node.js를 시작하고 실행하는 데 도움이 됩니다. 자신의 애플리케이션으로 대체할 수 있습니다. 적절한 IP 주소 및 포트에서 수신 대기하도록 애플리케이션을 수정해야 합니다.

Rocky Linux 9와 함께 제공되는 기본 텍스트 편집기는 vi입니다. vi는 매우 강력한 텍스트 편집기이지만 사용 경험이 부족한 사용자에게는 다소 둔감할 수 있습니다. Rocky Linux 9 서버에서 구성 파일 편집을 용이하게 하기 위해 nano와 같은 보다 사용자 친화적인 편집기를 설치할 수 있습니다.

  1. sudo dnf install nano

이제 nano 또는 좋아하는 텍스트 편집기를 사용하여 hello.js라는 샘플 애플리케이션을 만듭니다.

  1. nano hello.js

파일에 다음 코드를 삽입합니다.

const http = require('http');

const hostname = 'localhost';
const port = 3000;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World!\n');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

파일을 저장하고 편집기를 종료합니다. nano를 사용하는 경우 Ctrl+X를 누른 다음 메시지가 표시되면 Y를 누르고 Enter를 누릅니다.

이 Node.js 애플리케이션은 지정된 주소(localhost)와 포트(3000)에서 수신하고 "Hello World!\를 반환합니다. 200 HTTP 성공 코드 사용 localhost에서 수신 대기 중이므로 원격 클라이언트는 애플리케이션에 연결할 수 없습니다.

애플리케이션을 테스트하려면 다음을 입력합니다.

  1. node hello.js

다음 출력을 받게 됩니다.

Output
Server running at http://localhost:3000/

참고: 이 방식으로 Node.js 애플리케이션을 실행하면 CTRL+C를 눌러 애플리케이션을 종료할 때까지 추가 명령이 차단됩니다.

응용 프로그램을 테스트하려면 서버에서 다른 터미널 세션을 열고 curl을 사용하여 localhost에 연결합니다.

  1. curl http://localhost:3000

다음 출력이 표시되면 애플리케이션이 제대로 작동하고 올바른 주소와 포트에서 수신 대기하는 것입니다.

Output
Hello World!

예상한 결과를 얻지 못한 경우 Node.js 애플리케이션이 실행 중이고 적절한 주소와 포트에서 수신 대기하도록 구성되어 있는지 확인하세요.

제대로 작동하는지 확인했으면 CTRL+C를 눌러 응용 프로그램을 종료합니다(아직 종료하지 않은 경우).

2단계 - PM2 설치

다음으로 Node.js 애플리케이션용 프로세스 관리자인 PM2를 설치해 보겠습니다. PM2는 백그라운드에서 서비스로 실행되도록 응용 프로그램을 데몬화할 수 있습니다.

npm을 사용하여 서버에 최신 버전의 PM2를 설치합니다.

  1. sudo npm install pm2@latest -g

-g 옵션은 모듈을 전역적으로 설치하도록 npm에 지시하여 시스템 전체에서 사용할 수 있도록 합니다.

먼저 pm2 start 명령을 사용하여 백그라운드에서 애플리케이션 hello.js를 실행해 보겠습니다.

  1. pm2 start hello.js

이렇게 하면 애플리케이션을 시작할 때마다 출력되는 PM2의 프로세스 목록에 애플리케이션이 추가됩니다.

Output
... [PM2] Spawning PM2 daemon with pm2_home=/home/sammy/.pm2 [PM2] PM2 Successfully daemonized [PM2] Starting /home/sammy/hello.js in fork_mode (1 instance) [PM2] Done. ┌────┬────────────────────┬──────────┬──────┬───────────┬──────────┬──────────┐ │ id │ name │ mode │ ↺ │ status │ cpu │ memory │ ├────┼────────────────────┼──────────┼──────┼───────────┼──────────┼──────────┤ │ 0 │ hello │ fork │ 0 │ online │ 0% │ 25.2mb │ └────┴────────────────────┴──────────┴──────┴───────────┴──────────┴──────────┘

위에 표시된 대로 PM2는 자동으로 앱 이름(.js 확장자가 없는 파일 이름 기반) 및 PM2 id를 할당합니다. PM2는 또한 프로세스의 PID, 현재 상태 및 메모리 사용과 같은 기타 정보를 유지합니다.

PM2에서 실행 중인 응용 프로그램은 응용 프로그램이 충돌하거나 종료되면 자동으로 다시 시작되지만 startup 하위 명령을 사용하여 시스템 시작 시 응용 프로그램이 실행되도록 추가 단계를 수행할 수 있습니다. 이 하위 명령은 서버 부팅 시 PM2 및 해당 관리 프로세스를 시작하는 시작 스크립트를 생성 및 구성합니다.

  1. pm2 startup systemd
Output
… [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy

제공된 명령을 복사하고 실행합니다(Node.js 도구를 sudo로 실행할 때 발생하는 권한 문제를 방지하기 위한 것임).

  1. sudo env PATH=$PATH:/usr/bin /usr/local/lib/node_modules/pm2/bin/pm2 startup systemd -u sammy --hp /home/sammy
Output
… [ 'systemctl enable pm2-sammy' ] [PM2] Writing init configuration in /etc/systemd/system/pm2-sammy.service [PM2] Making script booting at startup... [PM2] [-] Executing: systemctl enable pm2-sammy... Created symlink /etc/systemd/system/multi-user.target.wants/pm2-sammy.service → /etc/systemd/system/pm2-sammy.service. [PM2] [v] Command successfully executed. +---------------------------------------+ [PM2] Freeze a process list on reboot via: $ pm2 save [PM2] Remove init script via: $ pm2 unstartup systemd

이제 Rocky Linux의 SELinux 보안 시스템과 호환되도록 방금 생성된 시스템 서비스를 편집해야 합니다. nano 또는 선호하는 텍스트 편집기를 사용하여 /etc/systemd/system/pm2-sammy.service를 엽니다.

  1. sudo nano /etc/systemd/system/pm2-sammy.service

구성 파일의 [Service] 블록에서 PIDFile 설정의 내용을 아래 강조 표시된 대로 /run/pm2.pid로 바꿉니다. 강조 표시된 다른 Environment 줄을 추가합니다.

[Unit]
Description=PM2 process manager
Documentation=https://pm2.keymetrics.io/
After=network.target

[Service]
Type=forking
User=sammy
LimitNOFILE=infinity
LimitNPROC=infinity
LimitCORE=infinity
Environment=PATH=/home/sammy/.local/bin:/home/sammy/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/bin:/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
Environment=PM2_HOME=/home/sammy/.pm2
PIDFile=/run/pm2.pid
Restart=on-failure
Environment=PM2_PID_FILE_PATH=/run/pm2.pid

ExecStart=/usr/local/lib/node_modules/pm2/bin/pm2 resurrect
ExecReload=/usr/local/lib/node_modules/pm2/bin/pm2 reload all
ExecStop=/usr/local/lib/node_modules/pm2/bin/pm2 kill

[Install]

파일을 저장하고 닫습니다. 이제 부팅 시 사용자를 위해 pm2를 실행하는 systemd unit을 만들었습니다. 이 pm2 인스턴스는 hello.js를 실행합니다.

systemctl로 서비스를 시작합니다.

  1. sudo systemctl start pm2-sammy

시스템 장치의 상태를 확인하십시오.

  1. systemctl status pm2-sammy

systemd에 대한 자세한 개요는 Systemd Essentials: Working with Services, Units, and the Journal을 검토하십시오.

우리가 다룬 것 외에도 PM2는 애플리케이션에 대한 정보를 관리하거나 조회할 수 있는 많은 하위 명령을 제공합니다.

다음 명령으로 애플리케이션을 중지합니다(PM2 앱 이름 또는 id 지정).

  1. pm2 stop app_name_or_id

애플리케이션을 다시 시작합니다.

  1. pm2 restart app_name_or_id

현재 PM2에서 관리하는 애플리케이션을 나열합니다.

  1. pm2 list

앱 이름을 사용하여 특정 애플리케이션에 대한 정보를 가져옵니다.

  1. pm2 info app_name

PM2 프로세스 모니터는 monit 하위 명령으로 가져올 수 있습니다. 애플리케이션 상태, CPU 및 메모리 사용량이 표시됩니다.

  1. pm2 monit

인수 없이 pm2를 실행하면 사용 예가 있는 도움말 페이지도 표시됩니다.

이제 Node.js 애플리케이션이 PM2에서 실행되고 관리되므로 리버스 프록시를 설정해 보겠습니다.

3단계 - Nginx를 리버스 프록시 서버로 설정

애플리케이션이 실행 중이고 localhost에서 수신 중이지만 사용자가 액세스할 수 있는 방법을 설정해야 합니다. 이를 위해 Nginx 웹 서버를 리버스 프록시로 설정합니다.

전제 조건 자습서에서는 /etc/nginx/conf.d/your_domain.conf 파일에서 Nginx 구성을 설정합니다. 편집을 위해 이 파일을 엽니다.

  1. sudo nano /etc/nginx/conf.d/your_domain.conf

server 블록 내에 기존 location / 블록이 있어야 합니다. 해당 블록의 내용을 다음 구성으로 바꿉니다. 애플리케이션이 다른 포트에서 수신 대기하도록 설정된 경우 강조 표시된 부분을 올바른 포트 번호로 업데이트합니다.

server {
...
    location / {
        proxy_pass http://localhost:3000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

이는 루트에서 요청에 응답하도록 서버를 구성합니다. your_domain에서 서버를 사용할 수 있다고 가정하면 웹 브라우저를 통해 https://your_domain/에 액세스하면 hello.js에 요청하여 localhost의 포트 3000에서 수신 대기합니다.

동일한 서버 블록에 추가 위치 블록을 추가하여 동일한 서버의 다른 애플리케이션에 대한 액세스를 제공할 수 있습니다. 예를 들어 포트 3001에서 다른 Node.js 애플리케이션을 실행 중인 경우 https://your_domain/앱2:

server {
...
    location /app2 {
        proxy_pass http://localhost:3001;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
...
}

애플리케이션에 대한 위치 블록 추가를 완료했으면 파일을 저장하고 편집기를 종료합니다.

다음을 입력하여 구문 오류가 발생하지 않았는지 확인하십시오.

  1. sudo nginx -t

Nginx를 다시 시작합니다.

  1. sudo systemctl restart nginx

Node.js 애플리케이션이 실행 중이고 애플리케이션과 Nginx 구성이 정확하다고 가정하면 이제 Nginx 리버스 프록시를 통해 애플리케이션에 액세스할 수 있습니다. 서버의 URL(공개 IP 주소 또는 도메인 이름)에 액세스하여 사용해 보십시오.

결론

축하해요! 이제 Rocky Linux 9 서버의 Nginx 리버스 프록시 뒤에서 실행 중인 Node.js 애플리케이션이 있습니다. 이 리버스 프록시 설정은 사용자가 공유하려는 다른 애플리케이션 또는 정적 웹 콘텐츠에 대한 액세스를 제공할 수 있을 만큼 충분히 유연합니다.

다음으로 Docker로 Node.js 애플리케이션을 빌드하는 방법을 살펴볼 수 있습니다.