Running a Node Service with PM2
Published: 2024-06-13 12:02:39


Managing a Node.js application in a production environment can be complex. PM2 (Process Manager 2) simplifies this process by ensuring your application runs continuously, providing load balancing, and offering robust monitoring and logging features. This guide will walk you through setting up a Node.js service using TypeScript, compiling it to JavaScript, and managing it with PM2.

## Prerequisites

- Node.js and npm installed on your machine.
- Basic understanding of TypeScript and Node.js.

## Step 1: Create the `dist` Folder for Compiling TypeScript to JavaScript

### 1.1 Set Up Your Project

First, create a new Node.js project and initialize it.

```
mkdir my-node-service
cd my-node-service
npm init -y

```

### 1.2 Install TypeScript and Other Dependencies

Install TypeScript and necessary development dependencies.

```
npm install typescript ts-node @types/node --save-dev

```

### 1.3 Initialize TypeScript Configuration

Create a `tsconfig.json` file to configure TypeScript.

```
npx tsc --init

```

Update the `tsconfig.json` file to specify the output directory for compiled JavaScript files:

```json
{
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "moduleResolution": "node",
    "target": "es6",
    "strict": true,
    "esModuleInterop": true
  },
  "include": ["src/**/*.ts"],
  "exclude": ["node_modules"]
}

```

### 1.4 Create Your TypeScript Source Files

Create a `src` directory and add your TypeScript files. For instance, create a `src/index.ts` file:

```
mkdir src
touch src/index.ts

```

Add a simple Node.js server in `src/index.ts`:

```tsx
import http from 'http';

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

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

```

### 1.5 Compile TypeScript to JavaScript

Compile the TypeScript files to JavaScript:

```
npx tsc

```

This command generates the `dist` folder containing the compiled JavaScript files.

## Step 2: Set Up PM2

### 2.1 Install PM2 Globally

Install PM2 globally on your machine:

```
npm install pm2 -g

```

### 2.2 Start Your Node Service with PM2

Navigate to your project's root directory and start your compiled JavaScript file with PM2:

```
pm2 start dist/index.js --name my-node-service

```

### 2.3 Monitor Your Application

PM2 provides various commands to manage and monitor your application:

- **List all processes**: `pm2 list`
- **View logs**: `pm2 logs my-node-service`
- **View detailed information**: `pm2 info my-node-service`

### 2.4 Ensure Application Runs on System Reboot

To ensure your Node.js service starts automatically after a system reboot, use the following commands:

```
pm2 startup
pm2 save

```

### 2.5 Restart, Stop, and Delete Processes

- **Restart**: `pm2 restart my-node-service`
- **Stop**: `pm2 stop my-node-service`
- **Delete**: `pm2 delete my-node-service`

## Setting Up a Watch Script

To automatically compile TypeScript files and restart the service when changes are made, you can use `tsc`'s `--watch` option along with `nodemon`.

### 3.1 Install Nodemon

Install `nodemon` as a development dependency:

```
npm install nodemon --save-dev

```

### 3.2 Update `package.json` Scripts

Update your `package.json` to include scripts for building, watching, and starting your application with PM2:

```json
{
  "name": "my-node-service",
  "version": "1.0.0",
  "main": "dist/index.js",
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch",
    "start": "pm2 start dist/index.js --name my-node-service",
    "dev": "concurrently \\"npm run watch\\" \\"npm run start:dev\\"",
    "start:dev": "nodemon dist/index.js"
  },
  "devDependencies": {
    "typescript": "^4.5.2",
    "ts-node": "^10.4.0",
    "@types/node": "^16.11.7",
    "nodemon": "^2.0.15",
    "concurrently": "^6.2.1"
  },
  "dependencies": {
    "pm2": "^5.1.1"
  }
}

```

### 3.3 Run the Watch Script

Now, you can run the `dev` script to start the watch process and automatically restart the server when changes are made:

```
npm run dev

```

### Summary of Commands

- **Start watching and running the development server**: `npm run dev`
- **Compile TypeScript files**: `npm run build`
- **Start the application with PM2**: `npm run start`

## Conclusion

By following these steps, you can set up a robust Node.js service using TypeScript and manage it effectively with PM2. This setup ensures your application runs continuously and handles crashes and reboots efficiently. The watch script facilitates a smooth development process by automatically compiling TypeScript files and restarting the service upon changes. With PM2's extensive features for process management, monitoring, and load balancing, you can maintain a stable and reliable production environment for your Node.js applications.