The Raspberry Pi is a little computer that you can get for as low as US $35 and on which you can run many different types of software and build many different projects. In this article, I’m going to guide you through the process of setting it up as a home development server and deploying a full-stack JavaScript application that you can access from outside your network. This is great for setting up your own remote digital workspace, or simply to have control over the hardware you use for development.

Developers connected to a Raspbery Pi server.

What Do You Need?

In February 2015, the second generation Raspberry Pi was released with more memory and CPU power. This tutorial will also work fine on the first generation model (in fact, this is what I am using), but if you don’t have one yet, you will be better off buying the latest Raspberry Pi 2 Model B from one of the distributors.

In addition to the board itself, you will need:

  • A Micro USB charger
  • An Ethernet cable
  • A microSD card (minimum 8GB, and cards up to 32GB seem to work fine)

These will also come in handy during the initial setup:

  • A USB keyboard
  • An HDMI cable and monitor

The Raspberry Pi Operating System: Raspbian

Installing an operating system onto a Raspberry Pi is simple. First, using your computer, install the boot image onto a microSD card. Then simply insert the card into the Raspberry Pi, and boot from there.

Raspbian is a Linux distribution ported from Debian 7.0 (Wheezy), and is the official OS for Raspbery Pi optimized for the device’s artchitecture. While there are other options for running your favorite OS on the Pi, we’ll use Raspbian because of its simplicity.

To install Raspbian, head to the official download page and download the zip file with the latest Raspbian version. Then, insert the microSD card into your computer’s SD card slot or adapter. Depending on your computer’s operating system, follow the instructions provided on Raspberry’s website for Linux, Mac OS, or Windows.

Once the process is finished, eject the SD card from your computer and insert it into the Raspberry Pi. Connect the Raspberry Pi to your router using the Ethernet cable, and plug in the Micro USB charger, which will start the Raspberry Pi booting.

For the initial configuration there are two options:

  • If you have a USB keyboard and an HDMI monitor, you can plug them into the Raspberry Pi for the initial setup.
    • Your Pi should recognize these devices as soon as they are plugged in.
    • The first time the Pi boots, it will automatically run raspi-config. After the first boot, you will need to run sudo raspi-config yourself in order to configure the device.
  • If you don’t have them, you can connect to your Raspberry Pi while it is on using SSH:
    • First, you need to find the IP address of your Raspberry Pi in your local network. This can be done by connecting to your router’s admin page, or by using a network tool like nmap.
    • Once you have the device’s IP address, connect to it using SSH from your terminal (or through Putty if you’re using Windows). The default user is pi, and the default password is raspberry. So, for example, if the IP address is, run ssh pi@ and enter the password when prompted.
    • When you are connected, run sudo raspi-config.

Raspi-config will walk you through the final setup. You can configure all the options but the most important are the first two: to expand the filesystem, ensuring that all the SD card storage is available for the OS, and to change the password for the default Pi user, so that your server will be protected from intruders.


Install the Web Server: Nginx

Next, you’ll install the webserver. I prefer Nginx because it has a small memory footprint, and because it plays well with Node.js (which you’ll be setting up later). Other web servers, such as Apache or lighttpd, would work as well, but you’ll use Nginx for this demonstration.

Before you start installing anything, you need to be sure everything is up to date by running these commands on the Pi:

sudo apt-get update
sudo apt-get upgrade

Then you can install Nginx using apt-get:

sudo apt-get install nginx

Once installation is completed, start the server by running:

sudo service nginx start

If you didn’t have to figure out the local IP of your Raspberry Pi in the previous step, it’s time to find out by running ifconfig. The output for your ethernet adaptor will be under eth0, and with it’s local IP address labeled inet addr.

Once you know the IP address, you can point the your computer’s browser at it, where you should see the default Welcome to Nginx message.

Open to the Web: Port Forwarding

You can skip this step if you are not planning to access your Raspberry Pi from outside your local network. But for those wanting to access their server from other locations, let’s make sure that’s possible.

In a typical home network, devices connected to the router are invisible to the outside world. Only your router can be reached from outside, using your network’s external IP address. Your router is responsible for determining which incoming traffic is allowed into the network, and which device it should be sent to.

When a device on the local network initiates a connection (for example, when you open a website on your browser), the router recognizes the incoming response traffic as being part of this connection, and allows it through. However, if the router receives incoming traffic that is not part of an open connection (for example, when an outside device attempts to initiate a connection with an inside device), it will block the incoming traffic from crossing into the network. This is an important security feature to protect the network!

So how can you connect to your Pi from outside? The answer is port forwarding. The router must be configured to allow incoming connections on specific ports to pass through, and be sent to the correct device. By the default, the HTTP protocol uses port 80, and SSH uses port 22, so these are the two ports that you need to open on your router in order to access your web application, and allow secure connections for managing your server.

Port forwarding.

The steps to configure your router to open and forward the ports may vary depending on your internet provider and the brand of your router, but in any case, you should be able to accomplish it through the advanced configuration options of your router’s admin page. Just look for an option with a name like “Forwarding,” “Port Forwarding,” or “Network Address Translation.”

You need to open a port for HTTP connections, and another one for SSH. The basic idea consists of forwarding data addressed to these two external ports to your Raspberry Pi, with web traffic going to port 80 where Nginx is listening, and SSH traffic going to port 22, where the SSH server accepts connections from external computers. Here’s an example of how this might look in your router’s configuration page:

Port forwarding configuration table.

Port forwarding configuration if your Raspberry Pi’s internal IP address is All incoming traffic bound for ports 80 or 22 are forwarded to this internal address.

You can determine your router’s external IP address by simply typing “what’s my ip address” into Google. If you then move outside your router’s network, you can test that port forwarding is working by opening an SSH connection with ssh pi@{external IP address}. Likewise, HTTP port forwarding can be tested by entering the external IP address into your browser’s address bar. Just keep in mind that port forwarding allows anyone from outside to access the device on these ports if they know your router’s external IP.

Install the Framework: Full-stack JavaScript

You can run most web frameworks on top of Nginx, but let’s see how to go full stack with JavaScript. To do this, you need to install Node.js and MongoDB.

Node.js is easily installed onto the Raspberry Pi’s ARM architecture thanks to the node-arm project:

sudo dpkg -i node_latest_armhf.deb

Once it finishes installing, you can check if it’s working by running node -v.

Unfortunately, off-the-shelf MongoDB doesn’t currently run on ARM machines, and although the MongoDB team is working on the issue, there is no official support yet.

So for now, you can’t have the latest MongoDB. But, as always, the community provides other solutions, and the easiest I’ve found (without the need of compiling the code by yourself) is this repository, which will set up version 2.1.1 of MongoDB:

git clone
cd mongo4pi

To start the MongoDB shell, you need to modify your path to access the binaries:

export PATH

Just be aware that if you ever need to turn off the Raspberry Pi, you need to shut down the service first in order to avoid database corruption:

sudo service mongod stop

Deploy Your App

You can develop on your local machine, and then push your changes to a Git repository on Bitbucket. Since Raspbian comes with Git preinstalled, you can then pull your latest application code onto the device and run it.

Scaffold the Project

First let’s set up some application code and push it to a Git repository. There are many ways of starting an application, but one of my favorites is generator-angular-fullstack, which scaffolds both server and client code.

Install the generator-angular-fullstack in your computer:

npm install -g generator-angular-fullstack

Create a new directory for your application:

mkdir my-app
cd my-app

And scaffold the application:

yo angular-fullstack my-app

Create the Repository and Push the Code

Now create a repository in Bitbucket, as described here. Then set up your local directory:

git init
git remote add origin

So you can commit and push the code:

git add .
git commit -m 'Initial commit'
git push -u origin master

The generator comes with the grunt-build-control plugin, which allows you to commit the build code to a specific branch in your repository. Just add the configuration for Bitbucket to Gruntfile.js in your application’s root directory:

buildcontrol: {
   options: {
      dir: 'dist',
      commit: true,
      push: true,
      connectCommits: false,
      message: 'Built %sourceName% from commit %sourceCommit% on branch %sourceBranch%'
   bitbucket: {
      options: {
         remote: '',
         branch: 'build'

Now run:

grunt build

To create the distribution folder, followed by:

grunt buildcontrol:bitbucket

To commit and push the code to the build branch in your repository.

Generate the SSH Key

You now have your code hosted. Before you can deploy it to your Raspberry Pi, you need to generate an SSH key for the Raspberry Pi and add it to your Bitbucket account. We’ll run through this step quickly, but if you have any trouble, please follow the Bitbucket guide. So, log back into your Raspberry Pi terminal, and generate the public/private key pair:


Then, start the agent:

ssh-agent /bin/bash

And add the key to the agent:

ssh-add /home/pi/.ssh/id_rsa

Now you just need to output the content of the public key:

cat /home/pi/.ssh/

So you can copy and paste it into Bitbucket.

In Bitbucket, click on your profile picture and go to Manage account. Under SECURITY, find SSH keys, and click the button Add key.

Clone the Repository

There isn’t a convention for where to place the code of your apps, but you can create a /var/www directory and put all your projects there.

cd /var
sudo mkdir www

To avoid the use of sudo when you want to place files in the webroot, you can change the owner to your Pi user, and the group to www-data, which is used by Nginx:

sudo chown -R pi:www-data www
cd www

Now, you can clone the build branch of your repository and install the dependencies:

git clone --branch build --single-branch
npm install --production

Once it’s finished you can start your app, setting the environment to production:

export NODE_ENV=production; node server/app.js &

And point your computer browser to the device IP address to check if it works.

Wish you had a dev server you could call your own? You can, with a #RaspberryPi.

Configure Nginx Reverse Proxy

There is one more step remaining to make your application accessible from the outside. Although Nginx is listening on port 80, where it will receive HTTP requests for your Pi, the Node application itself is listening on a different port (for example, port 8080). Therefore, you need to configure Nginx to act as a reverse proxy, recognizing requests intended for your application, and passing them to Node.

Nginx keeps the configuration file for each application it serves in the sites-available folder:

cd /etc/nginx/sites-available/

Here, you can copy the default configuration file and edit at your convenience:

sudo cp default my-app
sudo nano my-app

The final configuration file should look like this, with Nginx acting as a proxy to the Node.js server:

server {
   listen 80;
   root /var/www/my-app/;                  # identifies the location of the application you are configuring
   server_name;                 # identifies the hostname used by this application's traffic
   location / {
      proxy_pass http://localhost:8080/;   # configures the back-end destination for this traffic

In order to enable this configuration, you need to create a symlink in the sites-enabled folder, where Nginx looks for active configurations during runtime:

sudo ln -s /etc/nginx/sites-available/my-app /etc/nginx/sites-enabled/my-app

And reload the service to activate these changes:

sudo service nginx reload

At this point, your application is ready to receive HTTP traffic intended for the domain (thanks to the server_name directive you configured above). The final issue you need to solve is how to make traffic you send from outside match this domain name. Although you could buy a domain name and point it to your IP, the hosts file comes to the rescue and makes that unnecessary.

On the workstation from which you will access the site, simply add your router’s external IP address, and match it with the host name Any HTTP traffic you generate for will then be sent directly to your router, with the correct host name in the Host HTTP header.

On Windows, with administrator privileges, you can edit the file located in c:\windows\system32\drivers\etc\hosts with the notepad. On Linux and Mac you can use the terminal with sudo nano /etc/hosts and sudo nano /private/etc/hosts respectively.

# Host Database
# localhost is used to configure the loopback interface
# when the system is booting. Do not change this entry.
##       localhost broadcasthost
::1             localhost    # add your host name to the list

What’s Next?

Now that everything is set up, you can deploy as many applications as you want, and install forever or pm2 to keep your node servers alive.

And just remember that if something goes wrong, you can just wipe the SD card and start again from scratch!

Raspberry Pi development server in action.

About the author

Pablo Villoslada Puigcerber, Netherlands
member since October 15, 2014
Pablo is a skilled software engineer with over six years of experience developing websites. He has spent the last four years as a front-end engineer creating a variety of JavaScript applications. He is a team player who cares deeply about code quality and standards. [click to continue...]
Hiring? Meet the Top 10 Freelance Raspberry Pi Developers for Hire in October 2016


The last paragraph of the article sums up the problem of over-enthusiasm over RPi. Something being inexpensive is usually more trouble than it's worth. There's few options however that are so cost effective, but the geek factor is over-hyped. If you want to play with it, sure - as the author puts forward nicely, it's a good thing for learning system administration, from nginx onwards. Since you can get cheap vps servers for about $20-30 it's questionable why to use a RPi for your playground.
Pablo Villoslada Puigcerber
Hi! It was actually cheaper for me than a VPS server because I bought one Raspberry Pi to set it as a media center but they sent me two by mistake, so I got the chance to set up the second one as a server. But you are right this is just a playground, although an interesting one because as a frontend developer I don't get to play much with network configuration and server administration so it was a great chance to learn and see the things that can be done with such a little device. I hope you enjoyed though! Cheers.
Kevin Audleman
Nice post. I'm in the process of setting up a RPi for fun home automation projects. There's a next step that I find exciting: using Saltstack to configure your machine. All of the manual steps you listed can be put in a state file and executed automatically. That way if you ever need to wipe your SD card, or your little box breaks, you can swap it out with no effort.
Pablo Villoslada Puigcerber
Wow, that's a nice suggestion. I'll definitely look into it. Thanks Kevin!
I'd like to play with virtualization more, but alas, a mini-itx board with an 8 core intel processor comes up to about $200 at this point. RPi is a far from usable platform in this regard. And my time is much more valuable if invested in friends and family - I tend to learn and practice new things at work, and not at home :)
Alberto Morez
Thanks for a great article Pablo. I don't know why some people miss the point in the comments ... If you want a cheap VS then go get it, no one is stopping you; if you wanna be social instead of nerdy, go right ahead. The info in your article is very useful, but is not about the other 2 or million things that you can do with your own time.
Pablo Villoslada Puigcerber
Thanks Alberto! This was a fun little project to put together after reading some other articles and trying many things, so I'm glad is useful for most of the readers. ;)
Eric Berry
Good tutorial, and great way to learn how how to automate your build cycle. One suggestion, change it to be "npm install --production" once you clone the repo on the pi. Save some time when initializing the project there without all the grunt modules.
Pablo Villoslada Puigcerber
Thanks Eric! That's a great tip.
If you use Arch Linux (, installing nginx and mongodb is much easier: pacman -S nginx mongodo. Updating them to the latest versions: pacman -Syyu.
Jeremy Anderson
Looks like a good introduction project for a web-oriented developer who is new to embedded/small form factors, such as myself. I just got my RPi2B and I am excited to get started playing with it. Full stack Javascript makes sense to me, but I am thinking I may add a helping of Erlang or Erlang-Embedded to my project. Very cool article, thank you.
Pablo Villoslada Puigcerber
Thank you Jeremy! I hope you are enjoying your new Raspberry Pi. ;)
Pablo Villoslada Puigcerber
Thank you Thai! I have to check that out.
Thanks Pablo, but I have a question related to live apps using Java/C# and Pi's FTP/TFTP Server. Would it work in this direction?
Brett Hoffstadt
Thanks for the detailed article! RPi has a tremendous amount of power and possibilities for projects. I mentioned this article to my readers over at How To Be a Rocket Scientist who were reading about the use of Raspberry Pi on the international space station (ISS): Keep up the great work! Brett Hoffstadt, PMP
Pablo Villoslada Puigcerber
Hi Lioxa! I don't have experience in that sense but I'm sure it could work. Cheers.
Pablo Villoslada Puigcerber
Wow, thanks for the mention Brett!
Does it worth it in terms of security? I was thinking on create a node hosting for my apps but I don't know if I'm going to have too many attacks from outside.
comments powered by Disqus
The #1 Blog for Engineers
Get the latest content first.
No spam. Just great engineering and design posts.
The #1 Blog for Engineers
Get the latest content first.
Thank you for subscribing!
You can edit your subscription preferences here.
Trending articles
Relevant technologies
About the author
Pablo Villoslada Puigcerber
JavaScript Developer
Pablo is a skilled software engineer with over six years of experience developing websites. He has spent the last four years as a front-end engineer creating a variety of JavaScript applications. He is a team player who cares deeply about code quality and standards.