Table of Contents
- Introduction
- Preparation
- Setting Up the Raspberry Pi
- Installing the Nginx Web Server
- Configuring the Firewall (UFW)
- Setting Up Dynamic DNS (DDNS)
- Configuring Port Forwarding on Your Router
- Deploying Your Static Website
- Installing Certbot and Setting Up HTTPS Certificates
- Testing and Troubleshooting
- Conclusion
1. Introduction
So, you've decided to host your own website from your basement using a Raspberry Pi? Excellent choice! Not only will you save money on hosting fees, but you'll also become the tech wizard among your friends. In this guide, we'll walk you through every step—from setting up your Raspberry Pi to having a shiny, secure website that says "Hello, I'm Ken/Jacky/Allie..." to the world.
Note: While I personally love using the React framework for building websites, we'll keep things simple here with a basic static HTML page. Trust me, your Pi will thank you.
2. Preparation
What You'll Need:
- A Raspberry Pi (preferably a Raspberry Pi 5 for extra oomph)
- A microSD card (at least 16GB)
- Network connection (Ethernet or Wi-Fi)
- A computer (to prepare the SD card and remotely control the Pi)
- A domain name (so people can find your masterpiece)
Software You'll Need:
- Raspberry Pi Imager (the official tool for burning the OS)
- SSH client (most Windows/MacOS/Linux system have pre-installed SSH on Terminal)
3. Setting Up the Raspberry Pi
3.1 Installing the Operating System
Step 1: Download Raspberry Pi Imager
- Visit the official Raspberry Pi website and download Raspberry Pi Imager suitable for your operating system.
Step 2: Install Raspberry Pi Imager
- Run the installer and follow the on-screen instructions.
Step 3: Prepare the microSD Card
- Insert the microSD card into your computer's card reader.
Step 4: Burn the OS to the SD Card
- Open Raspberry Pi Imager.
- Click on "Choose OS" and select "Raspberry Pi OS" or another version you prefered.
- Click on "Choose Storage" and select your microSD card.
Optional but Highly Recommended: Enable SSH and Set Wi-Fi
- Click on the Custom Settings to access advanced settings.
- Set a username and password (make sure to remember them).
- If you're using Wi-Fi, enter your SSID and password.
- Enable SSH by checking the box "Enable SSH".
Step 5: Write the OS
- Click on "Write" and confirm that you want to erase the card.
- Wait patiently as the OS is written to the card.
Step 6: Safely Eject the SD Card
- Once the process is complete, eject the card from your computer.
3.2 Updating and Upgrading the System
Step 1: Power Up Your Pi
- Insert the microSD card into your Raspberry Pi.
- Connect the Pi to your router via Ethernet for a stable connection.
- Plug in the power supply.
Step 2: Find Your Pi's IP Address
- Access your router's admin page (usually at
192.168.x.1
). - Look for connected devices and find
raspberrypi
. Note its IP address (e.g.,192.168.68.130
).
Finding Your Router's IP Address
If you're unsure of your router's IP address, you can find it using the command line:
- Windows:
ipconfig
Look for the "Default Gateway" under your network adapter.
- macOS/Linux:
route -n
or
netstat -nr
Find the default gateway address. (Hmmm ChatGPT wrote the route -n
and netstat -nr
but I didn't test it. But anyways you can always find the IP address on your router's webpage.)
Step 3: Connect via SSH
- Open your PC Terminal and input:
ssh your_username@your_pi_ip_address
Host Name: your_username@your_pi_ip_address
(e.g., ken@192.168.68.130
)
Port: default 22
- Enter your password when prompted (the password won't be visible as you type).
Example using SSH on Windows Terminal:
Step 4: Update the System
- Run the following command to update and upgrade packages:
sudo apt update && sudo apt upgrade -y
- This updates the package lists and upgrades installed packages.
Optional but Recommended: Set Up SSH Keys
Setting up SSH keys allows you to connect to your Pi without entering a password each time.
On your PC terminal:
ssh-keygen -t rsa
- Press
Enter
three times to accept the default settings.
- Locate the
.ssh
folder in your home directory (e.g.,C:\Users\YourUsername\.ssh
) and find theid_rsa.pub
file.
- Open
id_rsa.pub
with a text editor and copy its content. - On your Raspberry Pi terminal, create the
.ssh
directory and theauthorized_keys
file:
mkdir ~/.ssh
nano ~/.ssh/authorized_keys
- Paste the copied public key into the file.
- Press
Ctrl + X
, thenY
, thenEnter
to save and exit.
Now, you can connect to your Raspberry Pi via SSH without entering a password.
4. Installing the Nginx Web Server
Let's install Nginx so your Pi can serve web pages.
Step 1: Install Nginx
sudo apt install nginx -y
Step 2: Start and Enable Nginx
- Start Nginx:
sudo systemctl start nginx
- Enable Nginx to start on boot:
sudo systemctl enable nginx
Step 3: Test Nginx
- Open a web browser on your computer and enter your Pi's IP address.
- You should see the default "Welcome to Nginx!" page.
5. Configuring the Firewall (UFW)
Protect your Raspberry Pi from unauthorized access.
Step 1: Install UFW
sudo apt install ufw -y
Step 2: Allow SSH and Web Traffic
- Allow SSH:
sudo ufw allow ssh
- Allow HTTP and HTTPS traffic:
sudo ufw allow 'Nginx Full'
Step 3: Set Default Rules and Enable the Firewall
- Deny all incoming traffic (except allowed):
sudo ufw default deny incoming
- Enable the firewall:
sudo ufw enable
- Type
y
when prompted.
Step 4: Check the Status
sudo ufw status verbose
- You should see rules for OpenSSH and Nginx.
6. Setting Up Dynamic DNS (DDNS)
Your ISP might change your public IP address periodically. Setting up DDNS ensures your domain always points to your Pi. What is DDNS, Why do we need to do so many things?
⚠️ Attention: This is the most challenging part of the guide. You may encounter various issues—perhaps difficulties using the Cloudflare API, trouble retrieving your public IP, firewall blocks, or even missed steps like configuring the optical modem. Please approach this with patience and persistence. If you run into any problems, try searching online or asking ChatGPT for assistance. Good luck!
Imagine you want to reach your Raspberry Pi at home from anywhere. Here’s how it works:
- Your PC asks the internet, “Where’s chengyongkang.me?”
- Cloudflare (your domain manager) and the DNS Server respond, saying, “Go to IP
123.123.123.1
”—which is your Router’s public IP.- Your Router gets the request, recognizes you want the Raspberry Pi, and forwards it through a “secret gate” to the Pi’s private IP inside your network.
And boom! You’re connected. Cloudflare keeps your domain linked to your router, even if the IP changes. It’s like a guided tour, directing your PC all the way to your Raspberry Pi!
6.1 Registering a Cloudflare Account and Adding Your Domain
Step 1: Sign Up for Cloudflare
- Go to Cloudflare's website and create a free account.
Step 2: Add Your Domain
- In the Account Home, click "Add site".
- Enter your domain name (e.g.,
example.com
).
Step 3: Select a Plan
- Choose the Free plan.
Step 4: Update Your Nameservers
- Cloudflare will provide nameservers (e.g.,
bob.ns.cloudflare.com
andlisa.ns.cloudflare.com
). - Log in to your domain registrar (where you bought the domain).
- Replace the existing nameservers with the ones provided by Cloudflare.
Step 5: Wait for DNS Propagation
- This can take up to 24 hours but usually is faster.
- Use What's My DNS to check the status.
6.2 Obtaining an API Token and Zone ID
An API token allows your Pi to communicate with Cloudflare to update DNS records, and the Zone ID uniquely identifies your domain.
Step 1: Create an API Token
- In Cloudflare, click on your profile icon and select "My Profile".
- Go to the "API Tokens" tab.
- Click "Create Token".
Step 2: Configure the Token
- Choose "Create Custom Token".
-
Token Name:
DDNS Update Token
-
Permissions:
- Zone - DNS - Edit
- Zone - Zone - Read
-
Zone Resources: Include -> Specific Zone -> Your domain (e.g.,
example.com
)
Step 3: Create and Copy the Token
- Click "Continue to summary", then "Create Token".
- Copy the token and store it securely.
Step 4: Obtain the Zone ID
- In your Cloudflare Account Home, click on your domain name (e.g.,
example.com
). - Scroll down; at the bottom right, you'll find your Zone ID.
6.3 Adding a DNS Record
Click "Add Record", and then configure as below:
- Type: A
- Name: @ (for the root domain)
- IPv4 Address, Proxy Status, and TTL: Enter any value for now; our script will update it later.
6.4 Writing a Script to Automatically Update Your IP
Let's automate the IP update process.
Step 1: Create a Directory for Your Script
mkdir ~/Documents/DDNS
cd ~/Documents/DDNS
nano update_dns.py
Step 2: Write the Python Script
#!/usr/bin/env python3
import requests
import json
import os
# Cloudflare API credentials
auth_key = "your_api_token_here" # Replace with your actual API token
record_name = "your_domain.com" # Replace with your domain
zone_id = "your_zone_id_here" # Replace with your Zone ID
ip_file = "ip.txt"
headers = {
"Authorization": f"Bearer {auth_key}",
"Content-Type": "application/json"
}
def get_record_id():
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records?name={record_name}"
response = requests.get(url, headers=headers)
response_data = response.json()
if response_data.get("success"):
return response_data["result"][0]["id"]
else:
print("Failed to fetch record ID")
return None
def get_current_ip():
response = requests.get("http://ipv4.icanhazip.com")
return response.text.strip()
def update_dns_record(record_id, ip):
url = f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{record_id}"
data = {
"type": "A",
"name": record_name,
"content": ip,
"ttl": 120,
"proxied": False
}
response = requests.put(url, headers=headers, json=data)
return response.json()
def main():
current_ip = get_current_ip()
if os.path.exists(ip_file):
with open(ip_file, "r") as file:
last_ip = file.read().strip()
else:
last_ip = None
if last_ip == current_ip:
print("IP has not changed")
else:
print("IP has changed, updating DNS record...")
record_id = get_record_id()
if not record_id:
print("Error: Could not retrieve the DNS record ID.")
return
result = update_dns_record(record_id, current_ip)
if result.get("success"):
print(f"DNS record updated successfully to IP: {current_ip}")
with open(ip_file, "w") as file:
file.write(current_ip)
else:
print("Failed to update DNS record")
print(result)
if __name__ == "__main__":
main()
- Replace:
-
auth_key
with your API token. -
record_name
with your domain. -
zone_id
with your Zone ID.
-
Step 3: Save and Exit
- Press
Ctrl + O
, thenEnter
to save. - Press
Ctrl + X
to exit.
Step 4: Make the Script Executable
chmod +x update_dns.py
Step 5: Test the Script
./update_dns.py
- Check if the DNS record is updated on Cloudflare.
Step 6: Schedule the Script
If you're in a hurry, you can skip this step for now. This helps you set up a timer which runs your program periodically.
- Open crontab:
crontab -e
- If prompted, select
nano
as the editor. - Add the following line at the end:
*/5 * * * * /home/pi/Documents/DDNS/update_dns.py >/dev/null 2>&1
- Make sure the file path is correct.
- This schedules the script to run every 5 minutes.
Step 7: Save and Exit
- Press
Ctrl + O
, thenEnter
to save. - Press
Ctrl + X
to exit.
7. Configuring Port Forwarding on Your Router
Set up port forwarding to allow external access to your Raspberry Pi.
Step 1: Access Your Router's Settings
- Open a web browser and enter your router's IP address (e.g.,
192.168.1.1
). - Log in with your router's username and password.
Finding Your Router's IP Address
If you're unsure of your router's IP address, you can find it using the command line:
- Windows:
ipconfig
Look for the "Default Gateway" under your network adapter.
- macOS/Linux:
route -n
or
netstat -nr
Find the default gateway address.
Step 2: Reserve an IP Address for Your Raspberry Pi
- Navigate to the "DHCP" or "LAN" settings.
- Look for "Address Reservation" or "Static IP Assignment".
- Assign a fixed IP address to your Raspberry Pi.
Step 3: Locate Port Forwarding Settings
- Go to the "Port Forwarding", "NAT", or "Virtual Servers" section.
Step 4: Set Up Port Forwarding Rules
- Forward the necessary ports to your Raspberry Pi's IP address.
- HTTP (Port 80)
- HTTPS (Port 443)
- Configure:
- External Port: 80 and 443
- Internal Port: 80 and 443
- Internal IP: Your Raspberry Pi's fixed IP
- Protocol: TCP
Step 5: Save and Reboot if Necessary
- Save the changes.
- Reboot the router if required.
Step 6: Verify Connectivity
- Ping Your Raspberry Pi's Internal IP:
ping 192.168.X.X
-
Find Your Public IP Address:
- Visit
https://ipv4.icanhazip.com/
.
- Visit
- Ping Your Public IP:
ping your_public_ip_address
- Ping Your Domain:
ping your_domain.com
-
Access Your Domain in a Browser:
- Navigate to
http://your_domain.com
. - You should see the Nginx default page.
- Navigate to
If everything works, congratulations! You've passed the hardest part.
8. Deploying Your Static Website
Let's replace the default Nginx page with your own content.
8.1 Creating a Simple HTML Page
Create a simple webpage that says "Hello, I'm Ken".
Step 1: Create an HTML File
- Create a new directory:
sudo mkdir /var/www/ken
- Create the
index.html
file:
sudo nano /var/www/ken/index.html
- Paste the following content:
<!DOCTYPE html>
<html>
<head>
<title>Hello, I'm Ken</title>
</head>
<body>
<h1>Hello, I'm Ken</h1>
<p>Welcome to my awesome Raspberry Pi hosted website!</p>
</body>
</html>
Step 2: Save and Exit
- Press
Ctrl + O
, thenEnter
to save. - Press
Ctrl + X
to exit.
8.2 Configuring Nginx to Serve Your Website
Step 1: Create a New Nginx Server Block
- Create a new configuration file:
sudo nano /etc/nginx/sites-available/ken
- Paste the following content (replace
www.example.com
with your domain):
server {
listen 80;
server_name www.example.com;
root /var/www/ken;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Step 2: Enable the Server Block
- Create a symbolic link to
sites-enabled
:
sudo ln -s /etc/nginx/sites-available/ken /etc/nginx/sites-enabled/
Step 3: Test Nginx Configuration
- Run:
sudo nginx -t
- Ensure there are no errors.
Step 4: Reload Nginx
- Run:
sudo systemctl reload nginx
Step 5: Test Your Website
- Navigate to
http://www.example.com
in your browser. - You should see your "Hello, I'm Ken" page.
If you are still seeing the Nginx page but not your own page, maybe you forgot to modify the www.example.com
to be your own domain in Step 1.
9. Installing Certbot and Setting Up HTTPS Certificates
Secure your website with HTTPS.
Step 1: Install Certbot
sudo apt install certbot python3-certbot-nginx -y
Step 2: Obtain and Install the SSL Certificate
sudo certbot --nginx -d www.example.com
- Follow the prompts:
- Enter your email address.
- Agree to the terms of service.
- Decide whether to share your email.
- Certbot will obtain and install the certificate automatically.
Step 3: Test HTTPS Access
- Navigate to
https://www.example.com
. - You should see a secure lock icon in your browser.
Step 4: Auto-Renewal
- Certbot installs a cron job for automatic renewal.
- Test the renewal process:
sudo certbot renew --dry-run
10. Testing and Troubleshooting
Common Issues:
-
Can't Access the Website:
- Ensure your domain points to your IP address.
- Verify port forwarding settings.
- Check that UFW allows HTTP and HTTPS traffic.
-
SSL Certificate Issues:
- Make sure your domain is accessible over HTTP before running Certbot.
- Double-check Nginx configurations for errors.
-
DDNS Not Updating:
- Confirm that the API token has the correct permissions.
- Manually run the update script to check for errors.
Useful Commands:
- Monitor Nginx errors:
sudo tail -f /var/log/nginx/error.log
- Check firewall rules:
sudo ufw status verbose
11. Conclusion
Congratulations! You've successfully transformed your Raspberry Pi into a web server hosting your very own website. Not only did you avoid hosting fees, but you've also earned some serious geek cred.
Next Steps:
- Enhance Your Website: Add more content or explore frameworks like React.
- Continue Learning: Dive deeper into Linux, Nginx, and web development.
- Share Your Success: Tell your friends about your new website.
Disclaimer: No Raspberry Pis were harmed in the making of this guide. Remember to keep your Pi cool and well-ventilated.
If you have any questions or run into any issues, feel free to ask. Happy Pi hosting!
Top comments (0)