I have a Node.js app running on a Droplet with PM2 and Nginx. Every time I deploy new code I have to restart PM2 which causes a few seconds of downtime. For my current project this is starting to be a real problem as users are noticing.
I have read a bit about zero-downtime deployments but most guides assume you are using Kubernetes or some cloud-native setup. Is there a simple way to achieve this on a single Droplet with my current stack?
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Hi there,
Good news, PM2 actually handles this natively. You do not need Kubernetes or anything complex for a single Droplet setup.
The simplest fix is using PM2’s reload instead of restart:
pm2 reload app-name
Unlike pm2 restart which kills the process and starts a new one, pm2 reload does a rolling reload. It starts a new instance of your app, waits for it to be ready, then gracefully shuts down the old one. No downtime.
For this to work properly your app needs to handle the SIGINT signal cleanly and stop accepting new connections before exiting:
process.on('SIGINT', () => {
server.close(() => {
process.exit(0);
});
});
If you want to go a step further, PM2 has a built in cluster mode that runs multiple instances of your app and reloads them one by one:
// ecosystem.config.js
module.exports = {
apps: [{
name: 'app-name',
script: 'server.js',
instances: 'max',
exec_mode: 'cluster'
}]
}
Then deploy with:
pm2 reload ecosystem.config.js
Nginx keeps serving requests to the instances that are still up while each one reloads, so users never hit a dead process.
A couple of things to keep in mind:
Make sure your app is stateless or that sessions are stored externally (Redis, database) before enabling cluster mode. In-memory sessions will not work across multiple instances.
If you are doing database migrations as part of your deploy, run those before reloading PM2, not during.
The PM2 docs have a good section on this if you want to go deeper: https://pm2.keymetrics.io/docs/usage/cluster-mode/
Heya, @e15185179e444234a371737aa60817
You can absolutely do zero-downtime deploys on a single Droplet with Node.js + PM2 + Nginx, no Kubernetes needed.
The key idea is: never restart the only running process in place.
Here are the two simple approaches that work well in your setup:
If you’re not already doing this, switch to:
pm2 reload app
Not:
pm2 restart app
reload uses a graceful reload and keeps the old process alive until the new one is ready, so there’s no downtime.
Even better, enable cluster mode:
pm2 start app.js -i max
Then reload works like a rolling update across workers.
If you want something more reliable:
Run app on two ports (e.g. 3000 and 3001)
Deploy new version to the inactive one
Switch Nginx upstream
Reload Nginx
Example Nginx upstream:
upstream node_app {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
Then you just flip which one is active.
Add this to reduce drop issues during deploys:
proxy_http_version 1.1;
proxy_set_header Connection "";
For most setups like yours:
PM2 cluster mode + pm2 reload is enough
If you want near-zero risk → use two ports + Nginx switch (blue/green)
No Kubernetes needed for this level of traffic.
Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.
Full documentation for every DigitalOcean product.
The Wave has everything you need to know about building a business, from raising funding to marketing your product.
Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.
New accounts only. By submitting your email you agree to our Privacy Policy
Scale up as you grow — whether you're running one virtual machine or ten thousand.
From GPU-powered inference and Kubernetes to managed databases and storage, get everything you need to build, scale, and deploy intelligent applications.