Binding a Node.js App to Port 80 with Nginx
Sep 26, 2015
You've finished building your first Node.js web app, and boy, is it awesome. Everything works great on your development machine, but when you try to deploy to production, your app just won't bind to the desired port. This is because Linux restricts apps from binding to the first 1024 ports unless they are given root permissions, to prevent malicious processes from binding to sensitive ports such as 80, 443, 22, 21, etc.
Here are a few ways to deal with this security constraint:
IPTABLES
One way is to set up an iptables
forwarding rule. iptables
will then bind to the desired port (80 or 443) and forward all incoming traffic to your application's port, such as 1337.
However, this solution requires that you persist the iptables
rule so that it gets executed on system startup, because your machine will crash or reboot eventually.
Redirecting traffic from one port to another
Let's issue the following command to redirect incoming traffic on port 80 to our Node.js app that is listening on port 1337:
sudo iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 1337
Automatically re-apply the rule on system reboot
Next, go ahead and install iptables-persistent
to save the rule permanently and have it reapplied automatically when your system reboots:
sudo apt-get install iptables-persistent
sudo /etc/init.d/iptables-persistent save
That's it. Now your Node.js app is accessible on port 80 and you should be good to go.
NGINX
A more popular approach is to set up Nginx as a reverse proxy by having it bind to the desired port, forwarding all incoming traffic to your Node.js app.
Nginx is a high performance, open source web server (similar to Apache) that is widely-used as a reverse proxy for Node.js apps.
The main benefit of Nginx is the fact that it takes care of transport optimization. It sends cache headers for static resources and compresses them so that your Node.js app doesn't have to deal with that stuff. Focus on building your product, and let Nginx take care of optimizations.
Installing Nginx
Easy as pie.
sudo apt-get install nginx
Configuring Nginx
Next, we'll need to configure Nginx so that it forwards traffic to our app. Let's start off by removing the default configuration file:
sudo rm /etc/nginx/sites-enabled/default
Next, create a new file in /etc/nginx/sites-available/
called node
and open it with nano
:
sudo nano /etc/nginx/sites-available/node
Paste the following code in the file and make sure to change example.com
to your domain (or IP), and 1337
to your Node.js application port:
server {
listen 80;
server_name example.com;
location / {
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_pass "http://127.0.0.1:1337";
}
}
The proxy_pass
declaration configures Nginx to act as a reverse proxy by forwarding all incoming requests on port 80 to your Node.js app on port 1337, on behalf of the client.
Next, we need to symlink our configuration to sites-enabled
for it to be used by Nginx, since it's currently in sites-available
:
sudo ln -s /etc/nginx/sites-available/node /etc/nginx/sites-enabled/node
Applying the Configuration
Let's restart Nginx so that it loads our configuration:
sudo service nginx restart
All set! Nginx will now forward all incoming requests to your app and even survive a server crash, since it automatically starts up with your machine.