set up a self-booting node.js server on a raspberry pi 3 using pm2, nginx, dataplicity, and your mac
Here in the summer of 2017:
Among many ways to accomplish this set up, here’s one of them.
Prerequisite skills:
- basic BASH shell (cd / mkdir / touch / sudo nano / exit)
- running a local server with node.js, such as this one
Required materials:
- a Raspberry Pi 3 Model B
- an 8GB micro SD card
- an SD card reader, or an SD card with NOOBS pre-installed
- USB Mouse and keyboard (for about ten minutes)
- HDMI cable and screen (perhaps your tv)
Get SSH terminal access to your Raspberry Pi
- Follow this guide to get Raspian onto your Pi. I would recommend “Download and image Raspian directly”. Briefly:
- Use the SD Formatter 4.0 to format the SD drive (overwrite format).
- Download the Raspian image
- Copy the image to the SD card using etcher.io.
- Put the micro SD chip into the Pi. Plug a mouse, keyboard, HDMI cable, and power into the Pi.
2. When the Pi’s GUI appears on your television screen or monitor, connect to your wireless network. Open the terminal by clicking the terminal icon at the top of the screen. Type hostname -I
and remember your Pi’s local IP address. Type sudo raspi-config
and use the menu system to enable SSH access.
3. On your mac, type ssh pi@xxx.xxx.x.xxx
replacing the x’s with your Pi’s local IP address. The password will be raspberry
and you’ll be prompted to change the password.
Assuming you are able to connect to your Pi via SSH on your mac, you’ll no longer need the mouse or keyboard. You may need to install nano at this stage: sudo apt-get install nano
.
Install Node.js and your server on the Pi
- Connect to your Pi via SSH and type
sudo apt update
, and thensudo apt full-upgrade
. - Install Node Version Manager by copying the curl line from https://github.com/creationix/nvm into the Pi terminal.
- Install Node.js by typing
nvm install 8.0.0
. - You can copy files to your pi using terminal commands, or use CyberDuck for drag and drop. To use CyberDuck, download it, and:
Open Cyberduck and click on File — Open Connection.
Choose SFTP from the dropdown box, then fill out the fields as follows:
Server: your Pi's local IP
Port: 22
Username: the username of your Pi, typically Pi
Password: the password of your Pi
Uncheck the box for Anonymous Login.
Hit Connect
5. Copy your node project file onto your Pi. I played around with a few locations and ultimately put my app folder in an app
directory at the root level.
6. Navigate to your app directory and start up your server. If you’re mac is connected to the same wireless network, you should now be able to access your server in your browser at http://xxx.xxx.x.xx:8080
using your Pi’s local IP address and the port specified in your node app.
Make your server load when the Pi reboots
I struggled with services and the rc.local file for quite awhile before finding a quick solution using an npm module called pm2:
- When connected to your Pi via SSH, type
npm install -g pm2
to do a global install of the pm2 module. - To run a server using pm2, go to your app directory and type
pm2 start filename.js
. If you need to see if it’s running, typepm2 ls
. If you need to stop it, typepm2 delete 0
or whichever thread number you want to delete. - To discover and implement the appropriate boot strategy for pm2, type
pm2 startup
. In this case, pm2 will create a the file /etc/systemd/system/pm2-pi.service which will include the following line:ExecStart=/home/pi/.nvm/versions/node/v8.0.0/lib/node_modules/pm2/bin/pm2 resurrect
. In other words, when the Pi boots, it will execute pm2 resurrect, which will load whatever pm2 threads you have saved. - In order to save the state of pm2 that you want to resurrect, run your server using
pm2 start filename.js
and then typepm2 save
.
For more details and commands for pm2, visit http://pm2.keymetrics.io/docs/usage/startup/
Connect your server to the outside world
Again, there are many methods, some involving port-forwarding, to allow the world to connect to your raspberry pi. Since I don’t currently care about appearances, I used a service called Dataplicity.
- Set up a currently free account at Dataplicity. Follow the directions to link your Pi to the site by copying a line of code to your Pi.
- Click Activate Wormhole to receive an https link to your Pi’s port 80.
- To set up port 80 on your Pi, install nginx by typing
sudo apt-get install nginx
. - Edit the config file by typing
sudo nano /etc/nginx/sites-available/default
. - Delete everything in the file and, using your Pi’s local IP address and node’s port, replace it with:
server {
listen 80;server_name whatever;location / {
proxy_pass http://xxx.xxx.x.xxx:8080;
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;
}
}
6. To confirm that nginx is working, type sudo netstat -an | grep LISTEN |grep :80
.
7. If you mess up and need to restart nginx, type sudo service nginx restart
.
Now, assuming pm2, nginx, and your Dataplicity account were all set up properly, you should be able to connect to the node.js server on your Pi via the url provided by Dataplicity.