Self Hosting!
(cough cough, this might take a while... it did for me)
If your looking for the end all be all self hosting guide this is not it, but it will at least give you a good idea of how to do it for your own situation you got going on. Through this guide you'll probably have a better understanding of how hosting works.
Also, I used a Raspberry PI 4 model B for this project.
Here is the short version.
TLDR:
Install Linux
Enabling Wifi
Install Nginx and Node.js
Configure UFW
Configure the router
Configuring Nginx config files to listen in on specified ports and folders
Register your site through google domains
Point google domains at your device
Installing Certbot for SSL
Serve to the WEB!
NOTE:
Most of this tutorial is done from the Linux terminal and is under the assumption of using VS Code with SSH enabled or have access to an SSH client. So if your not already familiar with the terminal or SSH this will be a good place to start.
1. Installing Linux
Install Linux Server /Ubuntu 20.04 UTS using Raspberry Pi Imager.
You will have to download the Ubuntu 20.04 UTS image separately.
For this I recommend using at least a 32 GB SD card.
Once you successfully boot into Linux, its time to get your PI connected to the internet.
2. Enabling wifi
How to Connect to WiFi from the Terminal in Ubuntu Linux
Identify your wireless network interface name:
There are several ways to identify your network interface name. You can use the ip command, the deprecated ipconfig command or check this file:
ls /sys/class/net
This should give you all the available networking interface (Ethernet, wifi and loopback). The wireless network interface name starts with ‘w’ and it is usually named similar to wlan0.
:~$ ls /sys/class/net
eth0 lo wlan0
Then Edit the Netplan configuration file with the wifi interface details
sudo nano /etc/netplan/50-cloud-init.yaml
YAML files are very sensitive about spaces, indention and alignment. DONT USE TAB KEY FOR SPACING, use 4 (or 2, whichever is already used in the YAML file) spaces instead where you see an indention.
network:
ethernets:
eth0:
dhcp4: true
optional: true
version: 2
wifis:
wlan0:
dhcp4: true
optional: true
access-points:
"SSID_name":
password: "WiFi_password"
Generate the configuration using this command:
sudo netplan generate
And now to apply it with:
sudo netplan apply
You should have network connected.
If not, restarting Linux should do the trick.
3. Installing Nginx and node
just run the commands below one after the other
sudo apt-get update
sudo apt-get install nginx
sudo apt-get install nodejs
4. Configuring UFW
This enables UFW to run and allows the ports that we need to communicate
Once you have port 22 enable you'll be able to SSH into your PI remotely from any application of your choosing, I recommend VS code and setting up SSH keys as well.
sudo ufw enable
sudo ufw allow 443
sudo ufw allow ssh
sudo ufw allow from 0.0.0.0/24 to any port 22
5. Configuring the router
Log into your router and enable the IP address to communicate only on port 443 for https access and SSL certs later on.
Typically you will look for the IP of your PI and assign the port to 443, this will only allow https traffic from outside the network while still allowing you to use port 22 from within the network.
Here is a link for that if you need help as there are many types of routers.
https://www.netspotapp.com/how-to-log-into-router.html
6. Configuring Nginx config files to listen in on specified ports and folders
Useful commands for managing Nginx and apply updates
To restart and apply changes made
sudo systemctl restart nginx
Tests if the current Nginx configuration is viable
nginx -T
Make sure to apply changes as you go.
Now go to file location: /etc/nginx/sites-available/default
and change the contents to the following:
server {
root /usr/share/nginx/html;
listen [::]:443 ssl ipv6only=on;
listen 443 ssl;
location / {
proxy_pass http://Your IP Address:port number;
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;
}
}
server {
if ($host = Yoursite.com) {
return 301 https://$host$request_uri;
}
listen 80 ;
listen [::]:80 ;
server_name Yoursite.com;
return 404;
location / {
satisfy any;
allow 127.0.0.1;
deny all;
auth_basic "closed site";
auth_basic_user_file conf/htpasswd;
}
}
Next go to file location /etc/nginx/nginx.conf
and change that file as well to look like below.
user www-data;
worker_processes auto;
pid /run/nginx.pid;
include /etc/nginx/modules-enabled/*.conf;
events {
worker_connections 768;
# multi_accept on;
}
http {
server {
listen 80;
}
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
# server_tokens off;
include /etc/nginx/mime.types;
default_type application/octet-stream;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3; # Dropping SSLv3, ref: POODLE
ssl_prefer_server_ciphers on;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
gzip off;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
7. Registering your site through google domains
Log into/ register domains.google.com and select Get a new domain, and continue through the process of obtaining your domain name.
Once you have obtained your domain name:
Go to google domains and log in → select your domain of choice → select DNS on the left side bar→ select Dynamic DNS under Synthetic records → select add → gather your Username and Password that google domains generates for your Dynamic DNS synthetic record
8. Point google domains at your device
a. Have google domains point to and update the reported IP every 30 min. for those of you with dynamic IP addresses
run this script from any directory of your choosing, it will run properly no matter where its stored
nano ~/dns_update_script.sh
wget https://username:password@domains.google.com/nic/update?hostname=yourdomain.com -qO dns_update_results.txt
wget https://username:password@domains.google.com/nic/update?hostname=www.yourdomain.com -qO- >> dns_update_results.txt
echo " Last run: `date`" >> dns_update_results.txt
chmod +x ~/dns_update_script.sh
The script downloads the web pages to the text file (the first wget creates the text file, the second wget appends to the text file) and then I also append the current date and time to the text file.
Remember to replace username:password with YOUR username and password that google domains provide when generating your DNS.
Also do not forget to change yourdomain.com & www.yourdomain.com to the domain name of your site.
b. Setup a cron job to run the script at the start of every hour:
crontab -e
0 * * * * ~/dns_update_script.sh
9. Installing Certbot for SSL
Follow the instructions that Certbot provides on there site
https://certbot.eff.org/instructions
10. Serving to the WEB!
serving your web app to the web with node.js and express or just a static site
The default location to store your site should be:
/usr/share/nginx/html
From that directory you will add your static site or applications that run from your self hosted site
CONGRATULATIONS!!!
At this point you should be able to go to your browser an type in "yourdomain.com"
and see your new website with HTTPS enabled and verified.
Top comments (5)
Nice post about selfhosting, you can add #raspberrypi tag on your post if you want!
Thanks for letting me know!
You're not wrong.
this is actually really useful. thanks!