| |

Serving Node.js Applications on a Raspberry Pi with Ngnix

Look at the this other post https://blog.mpfau.com/nginx-web-server-setup/ to get you machine setup as a traditional web server. You can just follow the first section to install Ngnix and then come back here to install Node.

sudo apt-get install nodejs
sudo apt-get install npm
npm install -g npm
nodejs -v
npm -v

Now we can make a little express application to to test our instance.

cd ~
mkdir server
cd server
touch index.js

nano ~/server/index.js

----------------------------
...paste this inside and save

const express = require("express");
const app = express();

// The HelloWorld
app.get("/", (req, res) => {
  res.send("Hello from Node.js!");
});

const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`App listening on http://localhost:${port}`);
});

we also need to install express and initilize

cd ~/server
npm init -y
npm install express --save

test that everything worked by running the app and then checking in the browser 192.your.ip.address:3000

nodejs index.js

You can use CTRL + C to kill the process when you are done.

Nginx Proxy

For security reasons we don’t want user to be able to access the app directly on port 3000, so we are going to setup a proxy to port 80 to handle all the incoming requests.

I will first create a backup of the default config with PHP enabled and save it a default_copy file in my home directory. Do not save it in the sites-enabled directory otherwise you will get an error about two default servers trying to use port 80, which is true.

cd /etc/nginx/sites-enabled/
sudo cp default ~/default_copy

now lets add this to the default config file.

sudo nano /etc/nginx/sites-enabled/default

...add this 

server {
        listen 80 default_server;
        listen [::]:80 default_server;

        root /var/www/html;

        index index.html index.htm index.nginx-debian.html;

        server_name _;

        location / {
                proxy_pass http://localhost:3000;
                proxy_http_version 1.1;
                proxy_set_header Upgrade $http_upgrade;
                proxy_set_header Connection 'upgrade';
                proxy_set_header Host $host;
                proxy_cache_bypass $http_upgrade;
        }
}

restart server for change to take effect

sudo systemctl restart nginx

systemctl status nginx.service

Now navigate to 192.your.ip.address and you will see that the node app has been forwarded.

If you get a 502 Bad Gateway Error that means you need to start your upstream service (node.js app).

so lets do that again

cd ~/server
nodejs index.js

IP Tables

At the moment anyone can access the app form port 80 AND 3000. This might be a problem if you want to authenticate access over a secure port like 443 but still have 3000 open as a backdoor. Let’s change that.

sudo apt-get install iptables

sudo iptables -A INPUT -p tcp -s localhost --dport 3000 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 3000 -j DROP

UFW to make life easier.

sudo apt install ufw

sudo ufw allow 22

Daemonized

Basically, auto startup and restart with system.

cd ~/server
sudo npm install -g pm2
pm2 start index.js

..for startup

pm2 startup systemd

sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u pi --hp /home/pi

pm2 save

Use these commands to manage the daemon pm2 list, pm2 status or pm2 show

UFW

You can use universal firewall to lock down you server in whatever way you see fit, the following is an example to allow ssh.

sudo apt-get install ufw

sudo ufw allow ssh
sudo ufw enable

and finally, open up to the world!

All that is left is to reserve an IP address on your router and setup Static WAN IP

Lets handle this in another post, until then see jah!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *