Hello guys! Thank you very much for your interest in my articles. I’m just moving my old blog to this new domain and I’m excited to write my first article here.
I think some of you have a RaspberryPI, don’t you? I also do own one and I didn’t do much with it. Recently I was wondering how could I have a web app deployed on it, maybe with a database as well. Hence I had the idea of building a sample app with NestJS, a bit of UI based on SemanticUI and a nice way to deploy to my Raspberry.
Prerequisites
Basically you’ll need a machine with NodeJS and Powershell Core installed. The trick part is that I’m using Linux as my main machine for development so for the setup and deployment scripts, although they are in Powershell, they call the ssh commands and might not work on Windows. Maybe there is a way to install ssh and scp commands via Mingw or something similar, don’t know exactly how.
Building the NestJS app
First of all, NestJS is a framework based on NodeJS used to build progressive web applications. It uses Typescript as first-class language and internally it’s based on Express framework. This gives NestJS the abstraction layer but also exposes Express APIs directly to the developer to perform fine-tuning. NestJS supports lots of patterns and recipes for databases, REST APIs, server side rendering or Message Queues.
You can very easily start a NestJS project by installing the Nest CLI:
$ npm i -g @nestjs/cli
And then start a new project:
$ nest new project-name
In our case, this NestJS app is called gibilius. It exposes an API, has a sample page rendered with Handlebars and SemanticUI. It also saves a test entity to a RavenDB database. I won’t go through the details of it here, this is the purpose of other articles. Here I will focus more on deploying the app to a RaspberryPI (actually it can be any Linux machine running Debian based distro).
IMPORTANT: before continuing, please clone this repository on your local machine. Make sure you run the commands inside your cloned folder.
Preparing the RaspberryPI machine
At this point I assume you have your Raspberry ready with the RPI OS installed and that you can login from your machine to it.
- Generate or use existing ssh keys for your login. Copy the key to your Raspberry. Place both keys in the ./ssh-keys folder. This folder has a gitignore file which will make sure your id_rsa files will not be committed to Git accidentally
You can follow the steps outlined here - Run the Powershell script: ./setup.ps1 {host}
Replace {host} with your Raspberry address. This script will install NodeJS and setup PM2 on your remote machine in order to orchestrate the app and start the app at reboot - PM2 has been installed but the app has not been configured yet to run. Use this command: ./setup-pm2.ps1 {host}
This command will register the gibilius app with PM2, build the app locally, copy the dist folder to the Raspberry, install npm packages and run the app
That’s quite it about the preparation. The good thing is that you need to do it only once!
Application should be running
This is great! If you browse to http://{host}:3000 you should see a sample page from SemanticUI. This means that the application is up and running. PM2 will take care of orchestrating the app now, even if you reboot the system. It’s a great tool to use in these scenarios.
If you update the app and need to redeploy, the process is simple:
$ yarn build && ./deploy.ps1 {host}
The first thing to do is to make sure you have a production build then run the deploy script by supplying the hostname of your remote Raspberry as parameter. The deploy script will take care of updating the NPM packages, copy the configuration and copy the newly built files to the machine. After that it tells PM2 to reload the application.
Lastly, if you just want to login inside the remote machine for other purposes, you can use the connect script:
$ ./connect.ps1 {host}
Very well done! You have a nice sample app running on your RaspberryPI! Hope it works fine for you!
Thanks for reading, I hope you found this article useful and interesting. If you have any suggestions don’t hesitate to contact me. If you found my content useful please consider a small donation. Any support is greatly appreciated! Cheers 😉