How To Serve Node.js Applications with Nginx on a Raspberry
Tags: node, nginx, raspberrypi, javascript
Published: 2019-01-30 17:35:03

---
title: How To Serve Node.js Applications with Nginx on a Raspberry
published: true
description: How To Serve Node.js Applications with Nginx acting as a reverse proxy on a Raspberry inside your local network.
tags: node, nginx, raspberry, javascript
cover_image: https://cdn-images-1.medium.com/max/800/1*clDbMcjFESL2xfHoz0zaaw.png
---

This is a tutorial of how I made my own server with *Nginx* to serve *Node.js* applications using a *Raspberry Pi* on my local network. I did it to have my own development server in my local network before committing any changes to the production host. We’ll go through all the steps so you can easily make your own too.

## Prerequisites and specifications

For this tutorial, I suppose you have a *Rasberry Pi* with the *Raspbian OS* installed, root access to the board, another computer connected on the same network, and access to your Wifi app.

- **Board model:** Raspberry Pi 3 B+
- **Board OS:** Raspbian
- **Board CPU:** ARMv7l

## Install and run Nginx

To install *Nginx* and start the service on your *Raspberry*, open the terminal and type the following commands:

```
sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx
```

Now your Nginx server is up and running. To check if the server is working properly, we can open a web browser from another computer and search for our *Raspberry* local IP. If you don’t know whats your *Raspberry* local IP open a new terminal and type:

```
hostname -I
```

In my case, it’s **192.168.0.173**. So the address I have to search for will be **http://192.168.0.173**. Here you can see the default landing page of *Nginx*.

![Nginx default page](https://cdn-images-1.medium.com/max/800/1*73xWgLveCtpOOoZGywlcqg.png)

Congratulations, your *Nginx* server is working. Now we have to serve *Node.js* applications instead of static *HTML* files. How?

## Install Node.js and NPM

Obviously, to work with *Node.js*, we first need to install *Node.js* packages and *NPM* (node package manager). We’ll also update *NPM* to the latest version. To do so, open a new terminal and type:

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

To check if both *Node.js* and *NPM* are installed properly, run the following commands:

```
nodejs -v
npm -v
```

Now that we have *Nginx* running and *Node.js* installed, it’s time to make our first *Node* app. The app will be a simple "Hello World" to check if *Node* and *Nginx* have good communication. Let’s write the app.

## Create a Node.js app

In your home directory create a new folder called `server`. In this folder, we’ll create our *Node.js* app. Let’s write the `index.js` file.

```javascript
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}`);
});
```

Save this file in the `server` directory we created before. To make this app work, we need to install the `express` packages. Open a terminal, go to your `server` folder and use *NPM* to install them:

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

What we did is to initialize *NPM* and install the `express` packages. Now we can run the app with *Node.js*:

```
nodejs index.js
```

If you open a browser in your *Raspberry* and search for http://localhost:3000 you’ll see this *Node* "Hello World".

## Nginx Proxy to the app

Our app is now running in port 3000. But what we want is to redirect all the HTTP requests in port 80 (the *Nginx* server) to the port 3000 (the *Node.js* app). We can do this modifying the default configuration file of *Nginx*.

```
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;
        }
}
```

Copy this configuration, delete all the text in your config file and paste it. To edit your default file type:

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

When you’re finished editing type `crtl+X` to save changes before exit. Don’t forget to restart your *Nginx* service:

```
sudo systemctl restart nginx
```

Now your *Nginx* is redirecting your HTTP requests to your localhost app. If we visit http://192.168.0.173 again (the address where *Nginx* is listening to) we now have to see the *Node* “Hello World”.

![Node app served with nginx](https://cdn-images-1.medium.com/max/800/1*y7oBAnhKV1SDW7vx-c2Nrg.png)

## Configure IP tables

The only problem right now is we can access the app via http://localhost (thanks to *Nginx*) but still with http://localhost:3000 (the *Node.js* direct access). We don’t want this port **3000** open to anyone.

Imagine in the future you want to redirect all port **80** connections to port **443** because you transport personal data and you need an *SSL certificate*. People could still connect to port **3000** an omit this encrypted connection.

To solve this we just need to change two rules in our IP tables. The first one will allow localhost (the *Raspberry*) to connect to port **3000**. The second one will deny access to anyone else. Open the terminal and type this:

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

## DHCP IP reservation

Another thing you may want to do is to reserve an IP for your *Raspberry*. So your device has the same IP address every time it connects to your Wifi.

- Open your Wifi app visiting: http://192.168.0.1 (This is your routers address)
- Log in with the user and password printed on the bottom of the router.
- There is a section called **Advanced Networking**.
- Search for the **DHCP IP reservations**.
- Click **add** device and search for your *Raspberry*.
- Change the last number of the IP address to your will.

## Last words

I hope this tutorial was useful for you. If you had any trouble in any of the steps just leave it in the comments below and I’ll do my best to help you. Thanks!