- About
- Hardware Recommendations
- Prepare SD Card
- First Login
- Create a custom User
- Allow using
sudo
without Password - Copy SSH Key
- Set Locales, Timezone and Keyboard
- Update Packages and install Basics
- Change Hostname
- Customize MOTD
- Customize bash Profile
- Create a convenient Update Script
- Install node.js via nvm
- Install yarn without node.js
- Setup nginx
- Setup MongoDB
- Setup PM2
- Setup Firewall
- Cleanup
This document will guide you to create a raspberry pi as server for node.js apps in your local network.
To achieve this, the following software will be set up on the device:
- nvm to be able to provide different node versions for different apps
- mongodb to provide a database
- pm2 to manage processes of node apps
- nginx to serve as reverse proxy for node apps
Download the Raspberry Pi Imager,
start it and follow the instructions to create an image using the
Ubuntu Server 20.10 64-bit
image.
- user:
ubuntu
- password:
ubuntu
SSH is already set up, so you can skip connecting a physical keyboard and directly ssh ubuntu@<IP>
.
You will be asked to change your password on the first login.
# create user
sudo adduser <USER>
# grant sudo and common privileges
sudo usermod -aG sudo,adm,dialout,cdrom,floppy,audio,dip,video,plugdev,netdev,lxd <USER>
# after logging in as with your new user, remove the ubuntu user and its homedir
sudo pkill -u ubuntu
sudo deluser -remove-home ubuntu
Run sudo visudo
and edit the line for the sudoers group to this:
%sudo ALL=(ALL:ALL) NOPASSWD:ALL
Copy your ssh id from your local machine to the pi:
ssh-copy-id -i ~/.ssh/id_rsa.pub <USER>@<IP>
# config locales
sudo dpkg-reconfigure locales
# config timezone
sudo dpkg-reconfigure tzdata
# check date/time and timesync settings
timedatectl status
# config keyboard
sudo dpkg-reconfigure keyboard-configuration
sudo apt-get update
sudo apt-get --with-new-pkgs upgrade -y
echo "pi-srv" > sudo tee /etc/hostname
sudo apt-get install -y toilet
sudo rm /etc/update-motd.d/10-help-text
sudo touch /etc/update-motd.d/00-at-first
sudo chmod +x /etc/update-motd.d/00-at-first
sudo nano /etc/update-motd.d/00-at-first
#!/bin/sh
toilet --termwidth --filter border --gay --font future -k "$(cat /etc/hostname)"
printf "$(cat /proc/device-tree/model)\n\n"
Some things to add to ~/.bashrc
:
HISTSIZE=5000
HISTFILESIZE=10000
PS1='\[\e[0;93;100m\]▌\u\[\e[0;30;100m\]@\[\e[0;93;100m\]\h▐\[\e[m\] \[\e[0;94m\]\w\[\e[m\] \[\e[0;90m\]\t\[\e[m\]\n\[\e[0;1;95m\]❯\[\e[m\] \[\e0'
alias ls='ls --color=auto --group-directories-first --human-readable'
alias ll='ls -AlCF'
alias la='ll -A'
mkdir -p ~/bin
touch ~/bin/$(whoami)-update-packages
chmod +x ~/bin/$(whoami)-update-packages
nano ~/bin/$(whoami)-update-packages
#!/bin/sh
sudo apt-get update
sudo apt-get upgrade -y
sudo apt-get autoremove -y
sudo apt-get autoclean -y
sudo apt-get clean -y
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.37.2/install.sh | bash
source ~/.bashrc
nvm install 14
nvm alias default 14
curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add -
echo "deb https://dl.yarnpkg.com/debian/ stable main" | sudo tee /etc/apt/sources.list.d/yarn.list
sudo apt-get update
sudo apt-get install --no-install-recommends yarn
Add this to your ~/.profile
to add ~/.yarn/bin
to your PATH:
PATH="$HOME/.yarn/bin:$PATH"
# install
sudo apt-get install nginx
# edit nginx config (see below)
sudo nano /etc/nginx/nginx.conf
# edit site config (see below)
sudo nano /etc/nginx/sites-available/default
# test config
sudo nginx -t
# reload config
sudo nginx -s reload
# download pi favicon
sudo curl -L https://www.raspberrypi.org/favicon.ico -o /var/www/html/favicon.png
# remove nginx default page
sudo rm /var/www/html/index.nginx-debian.html
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
}
http {
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
include /etc/nginx/mime.types;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
#upstream app_upstream {
# server localhost:3000;
# keepalive 64;
#}
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.php index.html index.htm;
server_name pi-srv;
autoindex on;
autoindex_localtime on;
autoindex_exact_size on;
location / {
try_files $uri $uri/ =404;
}
location = /favicon.ico {
rewrite . /favicon.png;
}
#location = /app {
# return 302 /app/;
#}
#location /app/ {
# proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# proxy_set_header X-Real-IP $remote_addr;
# proxy_set_header Host $http_host;
# proxy_http_version 1.1;
# proxy_set_header Upgrade $http_upgrade;
# proxy_set_header Connection 'upgrade';
# proxy_pass http://app_upstream/;
# proxy_redirect off;
# proxy_read_timeout 240s;
#}
}
# install
wget -qO - https://www.mongodb.org/static/pgp/server-4.4.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu focal/mongodb-org/4.4 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-4.4.list
sudo apt-get update
sudo apt-get install -y mongodb-org
# pin packages to current version
echo "mongodb-org hold" | sudo dpkg --set-selections
echo "mongodb-org-server hold" | sudo dpkg --set-selections
echo "mongodb-org-shell hold" | sudo dpkg --set-selections
echo "mongodb-org-mongos hold" | sudo dpkg --set-selections
echo "mongodb-org-tools hold" | sudo dpkg --set-selections
# edit config (see below)
sudo nano /etc/mongodb.conf
Using this config and below firewall setup, mongodb is accessible from your local network without authentication. See MongoDB Docs for more security.
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
systemLog:
destination: file
logAppend: true
path: /var/log/mongodb/mongod.log
net:
port: 27017
bindIp: 0.0.0.0
processManagement:
timeZoneInfo: /usr/share/zoneinfo
pidFilePath: /run/mongod/mongod.pid
Fix PID-File in mongod service config by changing the respective line in /lib/systemd/system/mongod.service
to:
PIDFile=/run/mongod/mongod.pid
Then...
# create folder for pidfile and set ownership to mongodb user
mkdir /run/mongod
chown mongodb:mongodb /run/mongod
# reload daemon config
sudo systemctl daemon-reload
# restart mongo daemon
sudo systemctl restart mongod
# check status
sudo systemctl status mongod
# autostart daemon after boot
sudo systemctl enable mongod
Create a logrotate config for mongod using this command:
sudo nano /etc/logrotate.d/mongod
Insert this config:
/var/log/mongodb/mongod.log {
rotate 52
weekly
missingok
compress
delaycompress
notifempty
create 640 mongodb mongodb
sharedscripts
postrotate
systemctl restart mongod
endscript
}
You can test this config using sudo logrotate -f /etc/logrotate.d/mongod
.
# install pm2
yarn global add pm2
# display instructions to start pm2 as service
pm2 startup systemd -u $(whoami) --hp /home/$(whoami)
Create a logrotate config for pm2 using this command:
sudo nano /etc/logrotate.d/pm2-$(whoami)
Insert this config and replace <USER>
with your username:
/home/<USER>/.pm2/pm2.log /home/<USER>/.pm2/logs/*.log {
rotate 52
weekly
missingok
notifempty
compress
delaycompress
copytruncate
create 0640 <USER> <USER>
}
You can test this config using sudo logrotate -f /etc/logrotate.d/pm2-$(whoami)
.
sudo apt-get install ufw
# deny all incoming traffic
sudo ufw default deny incoming
# allow ssh from local network
sudo ufw allow from 192.168.<SUBNET>.0/24 to any app OpenSSH
# limit ssh connections
sudo ufw limit ssh/tcp
# allow http(s) from local network
sudo ufw allow from 192.168.<SUBNET>.0/24 to any app "NGINX HTTP"
sudo ufw allow from 192.168.<SUBNET>.0/24 to any app "NGINX HTTPS"
# allow mongodb access from local network
sudo ufw allow from 192.168.<SUBNET>.0/24 to any port 27017
# enable firewall (WARNING: misconfiguration may lock you out!)
sudo ufw enable
sudo ufw status verbose
sudo apt-get autoremove -y
sudo apt-get autoclean -y
sudo apt-get clean -y