DriversRecommendedOutdated drivers can make a good PC feel brokenScan driver issues before chasing fixes manually.Scan NowOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run Scan×
Skip to content
VGSources
Blog

How to Write a Linux Daemon With Node.js on a VPS

Run Node.js reliably after reboot by keeping it in the foreground and letting systemd manage the process. This guide covers the service unit, absolute executable paths, dedicated users, secrets, deployment commands, journal troubleshooting, reverse proxies and systemd-versus-PM2 decisions.
Length10 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The reliable way to run a Node.js daemon on a Linux VPS is to leave the program in the foreground and let systemd own its lifecycle. A service unit supplies the absolute Node path, working directory, non-root user, environment file, restart policy and boot target. After installing the unit, reload systemd, enable and start it, inspect the status and journal, and call the application’s health endpoint. For a public site, bind Node to a private address and put Nginx or another reverse proxy in front of it.

What a Node.js daemon means under systemd

On Linux, “daemon” describes a long-running background service. Under systemd, the Node process should not detach itself, call daemon(), use nohup, or fork into the background. It should run as a normal foreground process; systemd supervises it, starts it at boot, stops and restarts it, records its output in the journal, and reports its state.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The Linux man-pages project describes a service unit this way: “A unit configuration file whose name ends in ".service" encodes information about a process controlled and supervised by systemd.” That supervision is the reason a service unit is preferable to leaving node server.js in an SSH session or hiding it behind shell tricks.

Prepare the application and VPS

Keep the application foreground-safe

Your entry point should stay attached to its standard input, output and error streams and keep the event loop alive. Do not add a second daemon manager inside the application. If the program exits, systemd can apply the restart policy; if it remains running, systemd can track its PID and deliver stop signals correctly.

#1 Best Overall
Sale
Gaoye Blue Light Blocking Glasses
  • BLUE LIGHT BLOCKING GLASSES: Our blue light glasses for women boast UV400 protection, blocking harmful blue rays from computer screens. With these bluelight glasses women, you can enjoy gaming, reading, or watching TV with no worries of eye strain.
  • EYE RELIEF: Our blue light glasses are engineered to reduce blurry vision or strain caused by prolonged screen time. These womens blue light glasses aid in better sleep by preventing blue light from disrupting your natural sleep cycle, helping you fall asleep faster and enjoy a more restful night's sleep, making them the perfect christmas present.
  • COMFORTABLE: Crafted from durable material, our trendy blue light glasses for woman or blue light glasses men ensure long-lasting comfort. The high-transmittance lenses accessories, gamer gifts for men, help keep your eyes relaxed. Perfect stocking stuffers, gifts for gamers men, christmas gifts for men, halloween costumes.
  • LIGHTWEIGHT: These clear blue light glasses feature a lightweight frame, meaning they’ll stay comfy for long-term wear. Perfect as blue blockers glasses for women or mens blue light glasses, these non-prescription fake glasses for men can be worn throughout the day. The blue light blocking glasses women feature polycarbonate HD lenses, which are anti-reflective and restore true color.
  • WORRY-FREE PURCHASE: If you experience any issues, our support team is ready to assist you quickly. These are the perfect costume glasses for cosplay dressing up.

Make configuration external to the JavaScript source. A typical application might read PORT, database credentials and API keys from environment variables. Those values belong in a protected environment file, not in the unit file or a repository.

Create a dedicated service account

Run the daemon as a dedicated account such as myapp, not as root. On distributions that provide the usual tools, an administrator can create a system account with no interactive shell and then give it ownership of the application directory:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
sudo useradd --system --home /opt/myapp --shell /usr/sbin/nologin myapp
sudo install -d -o myapp -g myapp /opt/myapp

Check the account and shell conventions on the provisioned VPS image before using those exact flags. The important properties are a separate identity, no unnecessary login access, and read/write permissions only where the application needs them.

Choose the listener and directory

Use a fixed directory, such as /opt/myapp, so the service does not depend on whichever directory an SSH session happened to use. Decide which local port the application will listen on. If a reverse proxy will be the public entry point, bind Node to loopback or a private interface and expose only the proxy’s public ports.

Find the real Node executable

Interactive shells often modify PATH through profile files, version managers or per-user configuration. systemd does not automatically inherit those settings. On the VPS, run:

command -v node

Copy the absolute path returned by that command into ExecStart. /usr/bin/node is only an example; a distribution package, a version manager or a custom installation may place Node elsewhere. Confirm the path while logged in as an administrator and ensure the service account can execute it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Windex Gaming Cleaning Wipes, Pre-Moistened Wipes to Instantly Clean all Gaming Gear and Electronics, Resealable Packaging for a Freshness Lock, 25 count (Pack of 1)
  • WINDEX GAMING WIPES: effortlessly clean all your gaming gear and gaming electronics in one easy step with our new Windex Gaming Wipes
  • AMMONIA FREE: our ammonia-free formula is safe to use on all of your favorite gaming equipment like consoles, headsets, controllers, screens, keyboards, and more
  • PRE-MOISTENED WIPES: each wipe instantly removes dust, dirt, and stubborn smudges and fingerprints leaving a streak-free shine
  • ANTI-STATIC: great for cleaning and wiping down your gaming gear and electronics leaving behind no visible residue
  • COMPACT RESEALABLE PACKAGE: store your pack of Windex Gaming Wipes anywhere in your home for whenever a quick and easy wipedown is needed

Write the systemd service unit

Create a local unit file named myapp.service. The following shape covers the essential lifecycle, identity, logging and boot settings:

[Unit]
Description=My Node.js daemon
After=network.target

[Service]
Type=simple
User=myapp
Group=myapp
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/node /opt/myapp/server.js
EnvironmentFile=/etc/myapp/myapp.env
Restart=on-failure
RestartSec=5
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target

Replace the example executable path, account, directory and script with the values on your VPS. Keep the process in the foreground; Type=simple tells systemd that the command itself is the service process.

Directive Purpose Operational note
After=network.target Orders startup after the basic network target. It does not prove that a remote database or every network route is ready; the application should handle connection failures appropriately.
User and Group Drop privileges to the dedicated service identity. Make sure that identity can read the application and write only to directories it genuinely needs.
WorkingDirectory Sets the process’s current directory. Use an absolute, stable path so relative file references behave the same after boot and during manual restarts.
ExecStart Defines the exact command systemd launches. Use an absolute Node path and an absolute script path. Do not rely on shell aliases, profile files or an interactive PATH.
EnvironmentFile Loads runtime variables outside the unit. Store secrets in a separate protected file and do not commit it to source control.
Restart Defines when systemd starts the process again. on-failure restarts abnormal exits; always also restarts a clean exit. Choose according to the application’s intended exit behavior.
RestartSec Delays a restart. A delay prevents an immediate crash from becoming a tight restart loop, but repeated crashes still require investigation.
StandardOutput and StandardError Send application output to journald. Use journalctl rather than expecting a log file to appear in the application directory.
WantedBy=multi-user.target Associates the service with the normal multi-user boot target. Enabling the unit creates the boot-time dependency; starting it immediately is a separate action.

Protect the environment file

Create the directory and file with administrator ownership, then grant only the service account the read access it needs:

sudo install -d -o root -g myapp -m 0750 /etc/myapp
sudo install -o root -g myapp -m 0640 /dev/null /etc/myapp/myapp.env

Add variables in the format expected by the application, for example:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
NODE_ENV=production
PORT=3000

Do not place shell commands in this file and do not assume that a user’s shell expansion will occur. Treat credentials as secrets, restrict file access, and rotate them through your normal secret-management process when necessary.

Install, enable and start the daemon

Copy the unit into systemd’s local unit directory and run the lifecycle commands in this order:

Rank #3
Sale
LISEN Cell Phone Stand Phone Holder for Desk, Office Decor Gadgets for Men
  • Ergonomic & Adjustable Design: Fight "text neck" and improve your posture. Designed for comfort, it offers an adjustable height (7.1in-8.5in) (1.4in adjustable range) and angle (5°-85°) Please note: cell phone stand is only 9 inches tall—the length of a standard pencil
  • Without blocking subtitles Perfect for office desk Tiktok Face Time Zoom video—this is the ultimate kitchen desk essential for phones! Perfect viewing experience while reducing neck back strain, A must-have for gamers streamers desk, and anyone who values both style and support!
  • Sleek & Stable Design fits Otterbox Case: Say goodbye to bent cables, tangles, and tip-overs! LISEN’s stylish adjustable desk phone holder features a built-in charging hole and smart cable management, keeping your phone secure and your workspace clutter-free cool gadgets for men
  • ANTI-SLIP DESIGN free hands: The under 10.00 items easy gadgets back and the bottom of this kitchen essentials for women are fully covered by anti-skid silicone, which LISEN stand up desk decor can provide maximum protection device from any scratches and slides
  • Your Perfect Viewing Companion:If your product arrives damaged or breaks within 365 days, reach out to LISEN for a quick and hassle-free solution. Struggling with assembly, like tightening the screw? We’ve got your back! Your experience matters to us. (Product including: phone Holder stand*1, screw*1, hexagon screwdriver*1, specification*1)
  1. Install the application files. Ensure /opt/myapp/server.js and its dependencies are owned and readable by myapp. Keep deployment artifacts separate from the environment file.
  2. Install the unit.
    sudo install -m 0644 myapp.service /etc/systemd/system/myapp.service
  3. Reload unit definitions.
    sudo systemctl daemon-reload

    This is required after creating or editing a unit; otherwise systemd may still use its previous definition.

  4. Enable and start in one operation.
    sudo systemctl enable --now myapp.service

    Enabling arranges for boot startup, while --now starts the service immediately.

  5. Inspect the service state.
    sudo systemctl status myapp.service

    Look for an active process, the command systemd actually launched, the latest exit status and recent log lines.

  6. Follow the journal while reproducing a request.
    sudo journalctl -u myapp.service -f

    Leave this running while you make a local health request or restart the unit.

After a successful start, verify that the process is listening on the intended interface and port, call its local health endpoint, and, if a reverse proxy is configured, test the public route through that proxy. These checks distinguish a running process from an application that is actually reachable and healthy.

Choose restart behavior deliberately

Restart=on-failure

This is a sensible default for a server that should remain available but should not be relaunched after an intentional clean exit. Crashes, signal termination and other failures trigger a restart after the configured delay.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Restart=always

Use this only when every exit, including a zero exit status, means the service should come back. It can be appropriate for a worker whose normal completion is itself unexpected, but it can also hide a program that repeatedly exits by design.

Diagnose loops instead of masking them

If status shows repeated restarts, stop treating the restart counter as the fix. Read the journal, run the command manually as the service account when safe, and check the executable path, working directory, permissions, missing environment variables and application startup errors. A restart delay limits the speed of the loop; it does not repair the underlying failure.

Make a VPS application public safely

For HTTP or HTTPS traffic, keep Node on an internal listener and put Nginx or another reverse proxy at the edge. The proxy handles the public address and forwards requests to the local Node port. This arrangement lets you keep the backend off the public interface, centralize TLS and routing, and expose only the firewall ports required by the proxy.

Bind the Node listener to loopback or a private network interface when the proxy is on the same host or private network. Confirm that the proxy’s upstream address and port match the value in the environment file. Test both layers: first the local health endpoint, then the public URL. A successful systemd status alone does not establish that the proxy route, TLS configuration or firewall permits traffic.

Rank #4
Ledagic IC+RGBW USB Powered Led Light Bar with App & Remote Control, 2 Pack
  • Easy Installation: Our gaming lights have been designed to enhance your entertainment experience. Simply position the led light bar next to your TV or game console to create a game room environment with ease. They come with USB power and a 60 inch cord for direct mounting and mobility
  • Audio Syncing & Extensive Mode: The built-in high-sensitivity music sensor allows you to sync the TV led lights to your favorite music. Lights react and move to the beat of music, film and game audio, creating an incredible immersive sound and light experience – and all without the need for an additional hub. You can choose from 64+ patterns, including strobe, illusion, jump, energy, gradient, running, chasing, fluttering mode etc. Each mode can be applied to different scenes
  • 64+ Chasing IC+RGB & W Effect: The independent control design of IC+RGB and white all-in-one multifunctional rgbw led bar lights monitor backlight allows you to easily switch the led lights for desk between IC+RGB and white to enjoy a variety of lighting effects, you can choose white lighting mode with high brightness for better illumination when working, etc. Choose IC+RGB lighting mode when you need to create an entertaining atmosphere for the light show, 16 million colours of Color changing rgb light bar let you dance to the beat and create a dynamic party atmosphere
  • Dynamic and Dimmable Lights: 1%-full brightness free brightness adjustment gives you the flexibility to adjust dimmable led light bar for room decorations or a variety of occasions
  • USB Powered: USB light bars for room can be powered by powernank, usb charger, TV, Monitor, laptop PC mainframe, making behind TV led lighting bar easy to install in any location.TV led lights are powered by the TV usb interface / PC mainframe, can be turned on/off synchronously with TV / PC

Security and maintenance checklist

  • Use a dedicated non-root account, preferably without an interactive shell.
  • Keep WorkingDirectory, script paths and configuration paths absolute.
  • Restrict ownership and mode bits on /etc/myapp/myapp.env; never publish credentials in the unit or repository.
  • Bind backend listeners privately when a reverse proxy or load balancer is the public entry point.
  • Open only the firewall ports that the application and edge proxy require.
  • Patch the operating system and Node.js runtime on a planned schedule, then restart the service deliberately.
  • Watch journal output and restart frequency so a failing deployment is visible rather than silently cycling.
  • Keep one process supervisor responsible for restarts. Stacking systemd and another supervisor without a clear ownership boundary makes status and failure diagnosis harder.

Updating the application without losing service control

Deploy new code into the fixed application directory, preserve the service account’s permissions, and check that the entry-point path and environment variable names have not changed. If the unit file changes, run daemon-reload before restarting. If only application files change, a controlled restart is normally sufficient:

sudo systemctl restart myapp.service
sudo systemctl status myapp.service
sudo journalctl -u myapp.service -n 100 --no-pager

Review the recent journal immediately after the restart and call the health endpoint. Keep the previous application version available until the new process has passed those checks so that you can restore files and restart the same unit if a deployment fails.

When the daemon launches child processes

Node’s child_process.spawn() starts a subprocess and exposes its process identifier. The child object emits an error event when spawning fails, so attach an error handler rather than assuming that a returned object means the command started successfully.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

A successful subprocess.kill() call means that a signal was sent; it does not mean that the child has finished terminating. Use the child’s exit or close events to perform completion handling, release resources and decide whether the parent service should continue. This distinction matters during systemd stops and restarts: the parent should not report a clean shutdown while its workers are still running.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

systemd versus PM2

Both can keep a Node application running, but they solve different operational needs. Select one component as the owner of restarts rather than having both independently relaunch the same process.

Concern systemd PM2
Linux boot and service integration Native service manager, with unit dependencies, enablement and standard administrative commands. Uses its own Node-oriented process manager and requires its startup integration to be configured.
Node-specific runtime dependency No additional Node process manager is required. Adds a Node-specific runtime dependency and CLI.
Restart semantics Configured declaratively with directives such as Restart=on-failure and RestartSec. Configured through PM2’s process model and commands.
Logs Integrates directly with journald and journalctl. Uses PM2’s logging and monitoring workflow.
Clustering Does not provide Node-specific cluster management by itself. Can be attractive when Node-specific clustering is a requirement.
Operational complexity One native supervisor for a conventional single service; teams already administering Linux may know the workflow. Useful when the team prefers its Node-focused CLI and process features, but it adds another layer to operate.

Choose systemd when native Linux lifecycle management, journald and a minimal dependency set are the priority. Consider PM2 when its Node-specific clustering or CLI workflow is a firm requirement. Whichever you choose, avoid overlapping restart policies that can obscure which component owns the process.

Best Value
Sale
HUANUO FlowLift™ Dual Monitor Stand, Fully Adjustable Gaming Monitor Desk Mount for 13–32″ Computer Screens, Full Motion VESA 75x75/100x100 with C-Clamp & Grommet Base, Each Arm Holds 4.4 to 19.8 lbs
  • Compatible with Wide Screens - To ensure compatibility with the dual monitor mount, your each monitor must meet three conditions at the same time: First, computer screens size range: 13 to 32 inches. Second, screen weight range: 4.4 to 19.8 lbs. Third, the back of the monitor screen must have VESA mounting holes with a pitch of 75x75mm or 100x100mm.
  • Regarding the compatibility with desks - Your desk must meet three conditions at the same time: First, desk material: Only wooden desks are recommended, plastic or glass desks cannot be used. Second, desk thickness range: 0.59" - 3.54". Third, the bottom of the desk should not have any cross beams or panels, as this will interfere with installation. We recommend carefully checking that your desk and monitors meets all above conditions before purchasing.
  • Dual C-Clamp Hold - Worried your dual monitors might wobble or slip? Our upgraded base uses a larger platform plus a dual C-clamp structure to lock the dual monitor arm firmly to your desk. Each arm safely keeps your screens steady while you type, click and game—no shaking, no sliding, just a clean and secure setup you can trust every day. It also provides Grommet Mounting installation choice, both options ensure stable and secure fixation for your 0.59" - 3.54" desk.
  • Full-Motion Adjustment For Comfortable View - Pull the screen closer when you’re deep in a spreadsheet, push it back to watch videos, or rotate to portrait for coding — moving everything smoothly with just one hand. The monitor stand offers +85°/-50° tilt, ±90° swivel and 360° rotation. Raise your monitor up to 15.75″ to support a healthy sitting posture. Whether you’re working from home, gaming through the night, or switching between video calls and documents, getting the screens to your natural line of sight helps relieve neck, shoulder and back strain so you can stay focused longer with less fatigue.
  • Keep Your Desk Organized: By lifting both screens off the desktop, this dual monitor stand opens up valuable space for your keyboard, notebook, docking station or a simple, clutter-free work area. Built-in cable management guides wires along the arms, keeping cords out of sight and out of the way. Enjoy a tidy, modern workstation that looks as good as it feels to use.

Troubleshoot by symptom

“Unit not found” after creating the file

Check that the file is under /etc/systemd/system/, that its name ends in .service, and run sudo systemctl daemon-reload. Then use the exact unit name in subsequent commands.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The service exits immediately

Read sudo journalctl -u myapp.service -n 100 --no-pager. An incorrect absolute Node path, a missing script, an unreadable working directory, a syntax error or an absent required environment variable will normally appear there. Reproduce the command as the myapp account only after checking that doing so will not expose secrets.

The service is active but requests fail

Confirm the listener’s interface and port, call the local health endpoint, and inspect the reverse proxy’s upstream target. If local access works but the public route does not, check proxy routing, TLS and firewall rules rather than changing the Node restart policy.

Secrets are missing after reboot

Inspect EnvironmentFile for the correct absolute path and file permissions. Values set only in an interactive shell or a user’s profile are not automatically available to a system service.

Stopping the unit leaves workers behind

Review child-process shutdown handling. A signal sent with subprocess.kill() is not proof of termination; wait for exit or close before declaring the application stopped.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Final operating checklist

  1. The Node program runs in the foreground and does not self-daemonize.
  2. ExecStart uses the absolute path returned by command -v node.
  3. The unit specifies a dedicated user, group, fixed working directory and protected environment file.
  4. The restart policy matches the application’s intended exit behavior.
  5. You ran systemctl daemon-reload after unit edits.
  6. You enabled and started the service, inspected systemctl status, and followed its journal.
  7. The process listens on the intended interface and port, and its health endpoint responds locally.
  8. The reverse-proxy route works publicly without exposing the backend unnecessarily.
  9. Firewall, runtime patches, permissions and restart frequency are part of ongoing operations.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
Crashes, No Sound, or Screen Glitches?Free driver scan
PC Slower Than It Used to Be?Free scan - under a minute

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.