2

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?

monday
  • 55
  • 1
  • 5

1 Answers1

3

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
Michael Hampton
  • 237,123
  • 42
  • 477
  • 940
  • Thank you! Also, is using one app per user a common practice? – monday Jul 28 '16 at 09:33
  • @monday With this method, users can run as many apps as your system can handle (or whatever you want to allow them). Whether each app should have a separate user account is another question entirely. If a single person is deploying multiple apps, it probably doesn't make sense. But multiple unrelated people shouldn't share an account. On the other hand, separate user accounts for each app can isolate the apps from each other, so you might want to do it anyway. – Michael Hampton Jul 28 '16 at 09:35