{"id":699,"date":"2026-11-13T09:14:00","date_gmt":"2026-11-13T09:14:00","guid":{"rendered":"https:\/\/getserverexplorer.app\/?p=699"},"modified":"2026-11-12T20:59:54","modified_gmt":"2026-11-12T20:59:54","slug":"how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2","status":"publish","type":"post","link":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/","title":{"rendered":"How to Deploy and Manage a Node.js App on a VPS with PM2"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Your Node.js app works on your laptop. Great. But running <code>npm start<\/code> in a terminal isn&#8217;t a reliable production setup: the process can stop when the session closes, and it won&#8217;t automatically return after a reboot.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This guide shows how to <strong>deploy a Node.js app to a VPS<\/strong>, keep it running with PM2, put Nginx in front of it, and inspect it when something goes wrong.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>You&#8217;ll need:<\/strong> an Ubuntu VPS with SSH access, a domain pointing to its public IP, and a Node.js application with a working production start command. Commands below assume a non-root user with <code>sudo<\/code> privileges.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. Prepare your VPS<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Connect over SSH:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>ssh youruser@YOUR_SERVER_IP<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Update package metadata and install Git, Nginx, and curl:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo apt update\nsudo apt install -y git nginx curl<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Install a currently supported Node.js LTS release using a trusted installation method appropriate for your OS, then confirm both commands work:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>node --version\nnpm --version<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note:<\/strong> Avoid relying on an old Node.js version bundled with your distribution. Match the runtime version required by your project, and keep it updated.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Get your application onto the server<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">For an application hosted in Git:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>mkdir -p ~\/apps\ncd ~\/apps\ngit clone https:\/\/github.com\/YOUR_USERNAME\/YOUR_REPO.git my-app\ncd my-app\nnpm ci<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Replace the example repository URL with your own. <code>npm ci<\/code> expects a committed <code>package-lock.json<\/code>; use your project&#8217;s appropriate package manager otherwise.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Create production environment variables securely, following your application&#8217;s configuration. Do not commit <code>.env<\/code> files containing secrets to Git.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If your app needs a build step, run it now:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>npm run build<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Skip this command if your project has no build script.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. Start the app with PM2<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Install PM2 globally:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo npm install -g pm2<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Assuming <code>npm start<\/code> launches your production server:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>cd ~\/apps\/my-app\npm2 start npm --name \"my-app\" -- start\npm2 status<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Your app should listen on a known local port, for example <code>3000<\/code>. Configure it to bind to <code>127.0.0.1<\/code> where supported if Nginx will be the public entry point.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To inspect output or restart it:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pm2 logs my-app\npm2 restart my-app<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important:<\/strong> PM2 runs under the user who started it. Use the same user for subsequent PM2 commands; mixing root and non-root PM2 instances causes confusion.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Keep your app running after a reboot<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pm2 startup<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">PM2 will print a command tailored to your user and init system. <strong>Copy and execute that exact command<\/strong>, then save the current process list:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pm2 save<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">After a future deployment that changes the PM2 process list, run <code>pm2 save<\/code> again.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Put Nginx in front of Node.js<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create an Nginx site configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo nano \/etc\/nginx\/sites-available\/my-app<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Add this configuration, replacing <code>example.com<\/code> with your domain:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>server {\n    listen 80;\n    server_name example.com www.example.com;\n\n    location \/ {\n        proxy_pass http:\/\/127.0.0.1:3000;\n        proxy_http_version 1.1;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n    }\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">Enable the site and validate the configuration:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sudo ln -s \/etc\/nginx\/sites-available\/my-app \/etc\/nginx\/sites-enabled\/my-app\nsudo nginx -t\nsudo systemctl reload nginx<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">If another Nginx site already handles your domain, edit or disable that conflicting configuration instead of creating a duplicate. Ensure your firewall permits HTTP and HTTPS while keeping your app&#8217;s internal port private.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once DNS points to the VPS and HTTP works, enable HTTPS with a trusted certificate tool such as Certbot, following its current Nginx instructions. Do not consider the deployment complete until HTTPS works.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Check the app when something breaks<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Start with these checks:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>pm2 status\npm2 logs my-app --lines 100\ncurl -I http:\/\/127.0.0.1:3000\nsudo systemctl status nginx\nsudo tail -n 100 \/var\/log\/nginx\/error.log<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">When your app keeps restarting, start by checking its logs and environment variables. A successful local <code>curl<\/code> request paired with an inaccessible domain usually points to an issue with Nginx, DNS, firewall rules, or TLS configuration. A <strong>502 Bad Gateway<\/strong> error, meanwhile, often indicates that the backend is down or listening on a different port.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For more troubleshooting, see our guides on <a href=\"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/11\/how-to-check-linux-server-logs\/\">checking Linux server logs<\/a>. <\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Manage PM2 visually with Server Explorer<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can administer a VPS entirely through SSH commands. But when you manage multiple apps, it helps to see processes and server health in one place.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><a href=\"https:\/\/getserverexplorer.app\/\">Server Explorer<\/a> is a desktop SSH client for Windows and macOS. After connecting to your VPS, you can use its PM2 management interface to inspect applications and available actions, alongside server monitoring and an integrated terminal.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img data-dominant-color=\"1e2429\" data-has-transparency=\"true\" style=\"--dominant-color: #1e2429;\" loading=\"lazy\" decoding=\"async\" width=\"2024\" height=\"1624\" src=\"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02.webp\" alt=\"Server Explorer PM2 interface showing Node.js application processes and their running status on a Linux VPS.\" class=\"wp-image-700 has-transparency\" srcset=\"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02.webp 2024w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02-300x241.webp 300w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02-1024x822.webp 1024w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02-768x616.webp 768w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.40.02-1536x1232.webp 1536w\" sizes=\"auto, (max-width: 2024px) 100vw, 2024px\" \/><figcaption class=\"wp-element-caption\"><em>View your PM2 applications and their status in Server Explorer<\/em><\/figcaption><\/figure>\n\n\n<div class=\"section-cta article-cta\" lang=\"en\">\n <svg class=\"cta-network\" viewBox=\"0 0 1000 320\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\" preserveAspectRatio=\"xMidYMid slice\">\n <g class=\"network-routes\" stroke=\"currentColor\" stroke-width=\"1\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n  <path d=\"M1000 280H840L760 200V80L680 0\"\/><path d=\"M930 0V75L850 155H710L630 235H520\"\/>\n  <path d=\"M530 0L610 80H710L790 0\"\/><path d=\"M1000 190H940L865 265V320\"\/>\n <\/g>\n <g class=\"network-signal\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32 720\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n <\/g>\n <g class=\"network-nodes\" stroke=\"currentColor\" stroke-width=\"1.2\">\n  <rect x=\"728\" y=\"108\" width=\"24\" height=\"24\" rx=\"7\"\/><rect x=\"768\" y=\"218\" width=\"24\" height=\"24\" rx=\"7\"\/>\n  <rect x=\"838\" y=\"143\" width=\"24\" height=\"24\" rx=\"7\"\/><circle cx=\"610\" cy=\"80\" r=\"5\"\/><circle cx=\"630\" cy=\"235\" r=\"5\"\/><circle cx=\"865\" cy=\"265\" r=\"5\"\/>\n <\/g>\n <g fill=\"currentColor\"><circle cx=\"740\" cy=\"120\" r=\"3\"\/><circle cx=\"780\" cy=\"230\" r=\"3\"\/><circle cx=\"850\" cy=\"155\" r=\"3\"\/><\/g>\n<\/svg>\n <div class=\"section-cta-copy\">\n  <span class=\"cta-eyebrow\"><span class=\"cta-connection\" aria-hidden=\"true\"><\/span>Server Explorer<\/span>\n  <h3>Bring your servers into focus.<\/h3>\n  <p>A desktop app for macOS and Windows. Connect over SSH.<\/p> <\/div>\n <a class=\"button cta-button\" data-download-auto data-download-mac=\"https:\/\/apps.apple.com\/bj\/app\/server-files-explorer\/id6474502110?l=fr-FR&#038;mt=12\" data-download-windows=\"https:\/\/apps.microsoft.com\/detail\/9nrb68w7pjg8?gl=US&#038;hl=en-US\" href=\"https:\/\/getserverexplorer.app\/#download\">Download<span class=\"cta-arrow\" aria-hidden=\"true\">\u2197<\/span><\/a>\n<\/div>\n\n\n\n\n<p class=\"wp-block-paragraph\">When investigating an issue, use the PM2 view together with the app&#8217;s logs or the integrated terminal. This keeps the deployment workflow transparent: <strong>PM2 runs your app; Nginx routes traffic; Server Explorer helps you manage the server.<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img data-dominant-color=\"1f252a\" data-has-transparency=\"true\" style=\"--dominant-color: #1f252a;\" loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"822\" src=\"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02-1024x822.webp\" alt=\"Server Explorer interface used to inspect a Node.js application's PM2 logs or Linux server resource usage\" class=\"wp-image-701 has-transparency\" srcset=\"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02-1024x822.webp 1024w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02-300x241.webp 300w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02-768x616.webp 768w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02-1536x1232.webp 1536w, https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Capture-decran-2026-11-11-a-23.41.02.webp 2024w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><figcaption class=\"wp-element-caption\"><em>Inspect application output or server resource usage while troubleshooting<\/em><\/figcaption><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Server Explorer is <strong>not<\/strong> presented here as an automatic deployment platform. You still configure your application, PM2, Nginx, DNS, and HTTPS yourself.<\/p>\n\n\n<div class=\"section-cta article-cta\" lang=\"en\">\n <svg class=\"cta-network\" viewBox=\"0 0 1000 320\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\" preserveAspectRatio=\"xMidYMid slice\">\n <g class=\"network-routes\" stroke=\"currentColor\" stroke-width=\"1\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n  <path d=\"M1000 280H840L760 200V80L680 0\"\/><path d=\"M930 0V75L850 155H710L630 235H520\"\/>\n  <path d=\"M530 0L610 80H710L790 0\"\/><path d=\"M1000 190H940L865 265V320\"\/>\n <\/g>\n <g class=\"network-signal\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32 720\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n <\/g>\n <g class=\"network-nodes\" stroke=\"currentColor\" stroke-width=\"1.2\">\n  <rect x=\"728\" y=\"108\" width=\"24\" height=\"24\" rx=\"7\"\/><rect x=\"768\" y=\"218\" width=\"24\" height=\"24\" rx=\"7\"\/>\n  <rect x=\"838\" y=\"143\" width=\"24\" height=\"24\" rx=\"7\"\/><circle cx=\"610\" cy=\"80\" r=\"5\"\/><circle cx=\"630\" cy=\"235\" r=\"5\"\/><circle cx=\"865\" cy=\"265\" r=\"5\"\/>\n <\/g>\n <g fill=\"currentColor\"><circle cx=\"740\" cy=\"120\" r=\"3\"\/><circle cx=\"780\" cy=\"230\" r=\"3\"\/><circle cx=\"850\" cy=\"155\" r=\"3\"\/><\/g>\n<\/svg>\n <div class=\"section-cta-copy\">\n  <span class=\"cta-eyebrow\"><span class=\"cta-connection\" aria-hidden=\"true\"><\/span>Server Explorer<\/span>\n  <h3>Bring your servers into focus.<\/h3>\n  <p>A desktop app for macOS and Windows. Connect over SSH.<\/p> <\/div>\n <a class=\"button cta-button\" data-download-auto data-download-mac=\"https:\/\/apps.apple.com\/bj\/app\/server-files-explorer\/id6474502110?l=fr-FR&#038;mt=12\" data-download-windows=\"https:\/\/apps.microsoft.com\/detail\/9nrb68w7pjg8?gl=US&#038;hl=en-US\" href=\"https:\/\/getserverexplorer.app\/#download\">Download<span class=\"cta-arrow\" aria-hidden=\"true\">\u2197<\/span><\/a>\n<\/div>\n\n\n\n\n<h2 class=\"wp-block-heading\">Final checklist<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Before sharing your app&#8217;s URL, confirm that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Your production start command works.<\/li>\n\n\n\n<li>PM2 reports the app as online.<\/li>\n\n\n\n<li><code>pm2 startup<\/code> and <code>pm2 save<\/code> have been configured.<\/li>\n\n\n\n<li>Nginx forwards requests to the correct local port.<\/li>\n\n\n\n<li>HTTPS works for your domain.<\/li>\n\n\n\n<li>Secrets are not stored in your repository.<\/li>\n\n\n\n<li>You know where to find application and Nginx logs.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Deploying is only the first step. Keeping the app observable and recoverable is what makes it maintainable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Want a visual way to manage your VPS after deployment?<\/strong> Explore <a href=\"https:\/\/getserverexplorer.app\/\">Server Explorer<\/a>.<\/p>\n\n\n<div class=\"section-cta article-cta\" lang=\"en\">\n <svg class=\"cta-network\" viewBox=\"0 0 1000 320\" fill=\"none\" aria-hidden=\"true\" focusable=\"false\" preserveAspectRatio=\"xMidYMid slice\">\n <g class=\"network-routes\" stroke=\"currentColor\" stroke-width=\"1\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n  <path d=\"M1000 280H840L760 200V80L680 0\"\/><path d=\"M930 0V75L850 155H710L630 235H520\"\/>\n  <path d=\"M530 0L610 80H710L790 0\"\/><path d=\"M1000 190H940L865 265V320\"\/>\n <\/g>\n <g class=\"network-signal\" stroke=\"currentColor\" stroke-width=\"2\" stroke-dasharray=\"32 720\">\n  <path d=\"M1000 40H820L740 120H640L570 190H420\"\/><path d=\"M1000 130H880L780 230H630L560 300H390\"\/>\n <\/g>\n <g class=\"network-nodes\" stroke=\"currentColor\" stroke-width=\"1.2\">\n  <rect x=\"728\" y=\"108\" width=\"24\" height=\"24\" rx=\"7\"\/><rect x=\"768\" y=\"218\" width=\"24\" height=\"24\" rx=\"7\"\/>\n  <rect x=\"838\" y=\"143\" width=\"24\" height=\"24\" rx=\"7\"\/><circle cx=\"610\" cy=\"80\" r=\"5\"\/><circle cx=\"630\" cy=\"235\" r=\"5\"\/><circle cx=\"865\" cy=\"265\" r=\"5\"\/>\n <\/g>\n <g fill=\"currentColor\"><circle cx=\"740\" cy=\"120\" r=\"3\"\/><circle cx=\"780\" cy=\"230\" r=\"3\"\/><circle cx=\"850\" cy=\"155\" r=\"3\"\/><\/g>\n<\/svg>\n <div class=\"section-cta-copy\">\n  <span class=\"cta-eyebrow\"><span class=\"cta-connection\" aria-hidden=\"true\"><\/span>Server Explorer<\/span>\n  <h3>Bring your servers into focus.<\/h3>\n  <p>A desktop app for macOS and Windows. Connect over SSH.<\/p> <\/div>\n <a class=\"button cta-button\" data-download-auto data-download-mac=\"https:\/\/apps.apple.com\/bj\/app\/server-files-explorer\/id6474502110?l=fr-FR&#038;mt=12\" data-download-windows=\"https:\/\/apps.microsoft.com\/detail\/9nrb68w7pjg8?gl=US&#038;hl=en-US\" href=\"https:\/\/getserverexplorer.app\/#download\">Download<span class=\"cta-arrow\" aria-hidden=\"true\">\u2197<\/span><\/a>\n<\/div>\n\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>Your Node.js app works on your laptop. Great. But running npm start in a terminal isn&#8217;t a reliable production setup: the process can stop when the session closes, and it won&#8217;t automatically return after a reboot. This guide shows how to deploy a Node.js app to a VPS, keep it running with PM2, put Nginx [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":702,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[210],"tags":[],"class_list":["post-699","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vps-deployment"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v28.7 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer<\/title>\n<meta name=\"description\" content=\"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer\" \/>\n<meta property=\"og:description\" content=\"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/\" \/>\n<meta property=\"og:site_name\" content=\"Server Explorer\" \/>\n<meta property=\"article:published_time\" content=\"2026-11-13T09:14:00+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp\" \/>\n\t<meta property=\"og:image:width\" content=\"1672\" \/>\n\t<meta property=\"og:image:height\" content=\"941\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"darrellkidjo.dev\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@darrell_kidjo\" \/>\n<meta name=\"twitter:site\" content=\"@darrell_kidjo\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"darrellkidjo.dev\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/\"},\"author\":{\"name\":\"darrellkidjo.dev\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#\\\/schema\\\/person\\\/20f67c2affa11693453fec19477c9ec8\"},\"headline\":\"How to Deploy and Manage a Node.js App on a VPS with PM2\",\"datePublished\":\"2026-11-13T09:14:00+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/\"},\"wordCount\":769,\"publisher\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/Deploy-a-Node.js-App-with-PM2.webp\",\"articleSection\":[\"VPS Deployment\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/\",\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/\",\"name\":\"How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/Deploy-a-Node.js-App-with-PM2.webp\",\"datePublished\":\"2026-11-13T09:14:00+00:00\",\"description\":\"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#primaryimage\",\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/Deploy-a-Node.js-App-with-PM2.webp\",\"contentUrl\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2026\\\/11\\\/Deploy-a-Node.js-App-with-PM2.webp\",\"width\":1672,\"height\":941},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/2026\\\/11\\\/13\\\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/getserverexplorer.app\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"How to Deploy and Manage a Node.js App on a VPS with PM2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#website\",\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/\",\"name\":\"Server Explorer\",\"description\":\"Server Explorer SSH client - SFTP Explorer, VPS Security, terminal, Ai Integrated, Cron Management, Docker Manager for Linux servers on Mac and Windows\",\"publisher\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#organization\"},\"alternateName\":\"Server Files Explorer\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/getserverexplorer.app\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#organization\",\"name\":\"Server Explorer\",\"alternateName\":\"Server Files Explorer\",\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/OIG.P8HQiZbb_YxAtGo_Pkmw-removebg-preview.png\",\"contentUrl\":\"https:\\\/\\\/getserverexplorer.app\\\/wp-content\\\/uploads\\\/2024\\\/01\\\/OIG.P8HQiZbb_YxAtGo_Pkmw-removebg-preview.png\",\"width\":500,\"height\":500,\"caption\":\"Server Explorer\"},\"image\":{\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/x.com\\\/darrell_kidjo\",\"https:\\\/\\\/www.linkedin.com\\\/in\\\/darrell-kidjo-ab49381a3\\\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/getserverexplorer.app\\\/#\\\/schema\\\/person\\\/20f67c2affa11693453fec19477c9ec8\",\"name\":\"darrellkidjo.dev\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g\",\"caption\":\"darrellkidjo.dev\"},\"sameAs\":[\"https:\\\/\\\/getserverexplorer.app\"],\"url\":\"https:\\\/\\\/getserverexplorer.app\\\/index.php\\\/author\\\/darrellkidjo-dev\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer","description":"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/","og_locale":"en_US","og_type":"article","og_title":"How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer","og_description":"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.","og_url":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/","og_site_name":"Server Explorer","article_published_time":"2026-11-13T09:14:00+00:00","og_image":[{"width":1672,"height":941,"url":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp","type":"image\/png"}],"author":"darrellkidjo.dev","twitter_card":"summary_large_image","twitter_creator":"@darrell_kidjo","twitter_site":"@darrell_kidjo","twitter_misc":{"Written by":"darrellkidjo.dev","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#article","isPartOf":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/"},"author":{"name":"darrellkidjo.dev","@id":"https:\/\/getserverexplorer.app\/#\/schema\/person\/20f67c2affa11693453fec19477c9ec8"},"headline":"How to Deploy and Manage a Node.js App on a VPS with PM2","datePublished":"2026-11-13T09:14:00+00:00","mainEntityOfPage":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/"},"wordCount":769,"publisher":{"@id":"https:\/\/getserverexplorer.app\/#organization"},"image":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#primaryimage"},"thumbnailUrl":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp","articleSection":["VPS Deployment"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/","url":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/","name":"How to Deploy and Manage a Node.js App on a VPS with PM2 - Server Explorer","isPartOf":{"@id":"https:\/\/getserverexplorer.app\/#website"},"primaryImageOfPage":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#primaryimage"},"image":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#primaryimage"},"thumbnailUrl":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp","datePublished":"2026-11-13T09:14:00+00:00","description":"Learn how to deploy a Node.js app to a Linux VPS using PM2, keep it running after reboot, check logs, and manage your application.","breadcrumb":{"@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#primaryimage","url":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp","contentUrl":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2026\/11\/Deploy-a-Node.js-App-with-PM2.webp","width":1672,"height":941},{"@type":"BreadcrumbList","@id":"https:\/\/getserverexplorer.app\/index.php\/2026\/11\/13\/how-to-deploy-and-manage-a-node-js-app-on-a-vps-with-pm2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/getserverexplorer.app\/"},{"@type":"ListItem","position":2,"name":"How to Deploy and Manage a Node.js App on a VPS with PM2"}]},{"@type":"WebSite","@id":"https:\/\/getserverexplorer.app\/#website","url":"https:\/\/getserverexplorer.app\/","name":"Server Explorer","description":"Server Explorer SSH client - SFTP Explorer, VPS Security, terminal, Ai Integrated, Cron Management, Docker Manager for Linux servers on Mac and Windows","publisher":{"@id":"https:\/\/getserverexplorer.app\/#organization"},"alternateName":"Server Files Explorer","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/getserverexplorer.app\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/getserverexplorer.app\/#organization","name":"Server Explorer","alternateName":"Server Files Explorer","url":"https:\/\/getserverexplorer.app\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/getserverexplorer.app\/#\/schema\/logo\/image\/","url":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2024\/01\/OIG.P8HQiZbb_YxAtGo_Pkmw-removebg-preview.png","contentUrl":"https:\/\/getserverexplorer.app\/wp-content\/uploads\/2024\/01\/OIG.P8HQiZbb_YxAtGo_Pkmw-removebg-preview.png","width":500,"height":500,"caption":"Server Explorer"},"image":{"@id":"https:\/\/getserverexplorer.app\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/x.com\/darrell_kidjo","https:\/\/www.linkedin.com\/in\/darrell-kidjo-ab49381a3\/"]},{"@type":"Person","@id":"https:\/\/getserverexplorer.app\/#\/schema\/person\/20f67c2affa11693453fec19477c9ec8","name":"darrellkidjo.dev","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/475cdf09b61eef7d56e50d2142844c4b668e33b2dd5202b6d97932ea1441fc7a?s=96&d=mm&r=g","caption":"darrellkidjo.dev"},"sameAs":["https:\/\/getserverexplorer.app"],"url":"https:\/\/getserverexplorer.app\/index.php\/author\/darrellkidjo-dev\/"}]}},"_links":{"self":[{"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/posts\/699","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/comments?post=699"}],"version-history":[{"count":1,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/posts\/699\/revisions"}],"predecessor-version":[{"id":703,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/posts\/699\/revisions\/703"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/media\/702"}],"wp:attachment":[{"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/media?parent=699"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/categories?post=699"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/getserverexplorer.app\/index.php\/wp-json\/wp\/v2\/tags?post=699"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}