Industrial standard for multiple node apps on a single VPS?

monday asked:

I have a VPS that runs several node apps behind a reverse proxy. Each app is run via pm2 by a different user (i.e. each user runs pm2 on it’s own), app-specific environment variables are set within that user’s .bashrc. Code updates are controlled via git, all post-update logic is moved to the post-receive hook.

This configuration works fine, for now. I do, however, have a nagging feeling that there is a widely known and accepted solution that I somehow missed – most online guides either assume that one user uses pm2 to run multiple apps, or suggest docker.

Is there an accepted way of running multiple node apps on a single server – i.e. code location and version control, user roles, management software?

My answer:


Docker is the usual solution these days, but it’s not well suited – on its own – to a multi-user environment.

You can scale up – way up – with something like Kubernetes or OpenShift, but for a little VPS that’s probably way too much complexity.

Nasty hackery like pm2, supervisord, forever, etc., are usable but systemd largely makes them obsolete.

Consider moving to systemd user services, which each user can control at will. I’ve run services in NodeJS, Go and Ruby on Rails with this method. It’s suitable for practically anything you can think of.

A trivial example (which probably will require expansion):

$ cat $HOME/.config/systemd/user/nodejs-against-humanity.service
[Unit]
Description=NodeJS Against Humanity

[Service]
ExecStart=/home/error/nodejs-against-humanity/server.js
ExecReload=/bin/kill -HUP $MAINPID
WorkingDirectory=/home/error/nodejs-against-humanity

[Install]
WantedBy=default.target

A user can place a user unit in $HOME/.config/systemd/user, and the admin can place user units that are usable by all users (which is uncommon, but sometimes helpful) in /etc/systemd/user.

The user then can manage the service with the usual systemd commands with the --user flag added, e.g.

$ systemctl --user enable nodejs-against-humanity
Created symlink from /home/error/.config/systemd/user/default.target.wants/nodejs-against-humanity.service to /home/error/.config/systemd/user/nodejs-against-humanity.service.
$ systemctl --user start nodejs-against-humanity

Note that in order for user services to be started at boot, root must enable linger for that user.

$ sudo loginctl enable-linger username

View the full question and answer on Server Fault.

Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.