Why PM2 is Essential for Applications in Production?
When deploying a Node.js application in a production environment, ensuring stability, efficiency, and reliability is crucial. This is where PM2, a powerful process manager for Node.js applications, becomes an invaluable tool. PM2 simplifies process management, enhances performance, and provides robust monitoring capabilities. In this post, we’ll explore why PM2 is essential for running Node.js applications in production.
To ensure a Node.js app keeps running smoothly in production on Linux/Ubuntu, there are many ways to achieve this, but here are some of the essential steps that will help you elevate your application’s performance to the ‘next level’:
- Regularly monitor system resource usage to prevent bottlenecks
- Implement error handling and logging to quickly diagnose and fix issues as they arise
- Utilize process managers like PM2 or Forever to automatically restart your application in case of failures
- Ensure that your dependencies are always updated and secure to avoid vulnerabilities
- A bonus step: consider employing load balancing and clustering techniques to enhance the app’s scalability and availability. Nginx is great here even if you have one instance.
1. Use a Process Manager (PM2)
PM2 is a popular process manager for Node.js applications that provides automatic restarts, logging, and monitoring.
Install PM2 globally:
npm install -g pm2
Start your application with PM2:
pm2 start app.js --name myNodeJSAppButInProd
Managing different configurations for development, testing, and production environments can be cumbersome. PM2 allows you to define environment-specific variables using an ecosystem file:
module.exports = {
apps: [{
name: "my-app",
script: "app.js",
env: {
NODE_ENV: "development",
},
env_production: {
NODE_ENV: "production",
}
}]
};
This ensures that your application loads the appropriate settings based on the environment, reducing configuration errors.
Ensure PM2 restarts on reboot:
pm2 startup
pm2 save
2. Set Up a Reverse Proxy (Nginx)
To improve performance and security, use Nginx as a reverse proxy in front of your Node.js app.
Install Nginx:
sudo apt update
sudo apt install nginx
Configure Nginx:
Edit the config file:
sudo nano /etc/nginx/sites-available/myApp
Add the following configuration:
server {
listen 80;
server_name yourdomain.com;
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;
}
}
Enable the configuration:
sudo ln -s /etc/nginx/sites-available/myApp /etc/nginx/sites-enabled/
sudo systemctl restart nginx
3. Enable Firewall & Security Measures
Ensure only necessary ports are open.
sudo ufw allow OpenSSH
sudo ufw allow 'Nginx Full'
sudo ufw enable
4. Use a Process Monitor
Use PM2 monitoring:
pm2 monit
Enable log rotation
Applications generate logs over time, which can quickly consume disk space. PM2 includes a log rotation module to automatically manage log files:
pm2 install pm2-logrotate
5. Enable Automatic OS & Dependency Updates (this is ‘gold’ on any ubuntu in production)
Enable unattended security updates:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Keep Node.js and dependencies updated:
npm update -g
npm audit fix
6. Monitor System Health
Use htop for monitoring:
sudo apt install htop
htop
Enable log monitoring:
journalctl -u nginx -f
pm2 logs
7. Handle Application Crashes Gracefully
- Use proper error handling in your code:
process.on('uncaughtException', (err) => {
console.error('Unhandled Exception:', err);
});
process.on('unhandledRejection', (reason, promise) => {
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
});
8. Load Balancing and Scalability
Node.js is known for its non-blocking, event-driven architecture, but a single-threaded process can only handle a limited number of requests efficiently. PM2 allows you to run your application in cluster mode, which automatically distributes incoming traffic across multiple instances of your app.
With a simple command, you can start multiple instances of your application:
pm2 start app.js -i max
This enables horizontal scaling by utilizing all available CPU cores, ensuring better performance and responsiveness.
9. Monitoring and Logging
Production applications need proper monitoring to track performance, errors, and resource usage. PM2 provides built-in monitoring tools that help developers keep an eye on their applications.
pm2 listprovides a summary of all running processes.pm2 monitoffers real-time insights into CPU and memory usage.pm2 logsallows developers to view logs for debugging and troubleshooting.
Additionally, PM2 can be integrated with external logging services to store logs persistently for long-term analysis.
Conclusion
PM2 is an indispensable tool for managing Node applications in production. With features like automatic restarts, load balancing, monitoring, and log management, PM2 ensures that your application remains stable, scalable, and resilient. By integrating PM2 into your production workflow, you can significantly reduce downtime, improve performance, and simplify application management.
Ahh! I’m not related to PM2 by any way…
Discover more from Ido Green
Subscribe to get the latest posts sent to your email.