Run Node.js as a persistent VPS service
This example uses systemd on Ubuntu or Debian. It assumes a reviewed Node.js application and a supported Node.js installation already exist. Adjust paths and the entry point to your project.
Steps
Create a dedicated service user and private release directory. Deploy the reviewed project there, owned by that user. Run dependency installation and the build as that user, not as root.
bashsudo adduser --system --group --home /srv/apnapp apnapp sudo install -d -o apnapp -g apnapp /srv/apnapp/currentInstall locked dependencies, build the production release and configure the application to listen on 127.0.0.1:3000. Environment settings only work if the app reads them. Keep secrets in a restricted environment file, not the source repository.
bashsudo test -e /etc/apnapp.env || sudo install -o root -g apnapp -m 640 /dev/null /etc/apnapp.env command -v nodeCreate /etc/systemd/system/apnapp.service with the configuration below. Adjust the Node executable path, working directory and entry file. Fill the environment file privately; do not overwrite an existing file containing secrets.
ini[Unit] Description=APNCloud application After=network.target [Service] User=apnapp Group=apnapp WorkingDirectory=/srv/apnapp/current Environment=NODE_ENV=production EnvironmentFile=/etc/apnapp.env ExecStart=/usr/bin/node /srv/apnapp/current/server.js Restart=on-failure RestartSec=5 NoNewPrivileges=true PrivateTmp=true [Install] WantedBy=multi-user.targetValidate the unit, start it and inspect the logs. Fix startup errors before publishing any route.
bashsudo systemd-analyze verify /etc/systemd/system/apnapp.service sudo systemctl daemon-reload sudo systemctl enable --now apnapp sudo journalctl -u apnapp -n 50 --no-pager curl -I http://127.0.0.1:3000/After a release, restart the service and check health. Plan a reboot test and keep the previous release for rollback. A restart can briefly interrupt requests.
If something goes wrong
If it works in a shell but fails as a service, compare the executable path, permissions, working directory and environment. Do not run the service as root to bypass a permission problem. Use application-specific writable directories for uploads and persistent data.
Related articles
Last reviewed
2026-10-28
