Allowing node.js applications to run on port 80

in order to avoid this error, you can resolve the non-symlink executable with which node, as full example:

sudo apt-get install libcap2-bin
sudo setcap cap_net_bind_service=+ep `readlink -f \`which node\``

the "which" command shows the full path of shell commands.


Figured it out. Turns out however I installed node, created a sym-link in /usr/bin/node which pointed to another sym-link in /etc/alternatives/node which pointed to another sym-link in /usr/bin/nodejs.

Running the command against /usr/bin/nodejs worked.


FWIW, another option is to use authbind. Authbind uses a slightly different mechanism to achieve similar ends to CAP_NET_BIND_SERVICE. I.e. allows non-privileged apps to use privileged ports.

Install from apt:

sudo apt-get update && sudo apt-get install authbind

Assuming the desired app.js is running under non-privileged user "user" and you wish to bind to port 80:

sudo touch /etc/authbind/byport/80
sudo chown user:user /etc/authbind/byport/80
sudo chmod 500 /etc/authbind/byport/80

Then run your app like this:

authbind node app.js

If you instead wish to use something like "forever" (essentially daemonizes node apps), then this is the go:

authbind --deep forever app.js

One reason the setcap command sometimes fails is because certain file systems do not support it, if they don't support extended attributes.

The filesystem must support attaching capabilities to an executable file, so that a process gains those capabilities when the file is executed.

http://man7.org/linux/man-pages/man7/capabilities.7.html

This is especially true with Docker. Docker uses the BTRFS or AUFS storage backends, but can also user overlayfs. Overlayfs supports setting caps, but BTRFS and AUFS (see below) do not.

https://github.com/moby/moby/issues/30557

If you need to run images with AUFS, you must be running a kernel with CONFIG_AUFS_XATTR=y.

For this reason authbind is often a better solution.