How to Host Your Website on a Raspberry Pi with Cloudflare Tunnels
How to Host Your Website on a Raspberry Pi with Cloudflare Tunnels
In this guide, we’ll walk through setting up a secure and accessible web server using a Raspberry Pi and Cloudflare Tunnels. This setup allows you to host your website from home without exposing your home IP address or opening ports on your router, thanks to Cloudflare’s secure tunneling technology.
Prerequisites:
- A Raspberry Pi (We used a Raspberry Pi 4 with 8GB RAM, but other models should work with adjustments)
- Raspberry Pi OS installed on the Pi
- SSH access to your Raspberry Pi
- A domain name you own
- A Cloudflare account
- A static website ready to be deployed (We used an Astro site for this example, but the steps apply to other types of sites as well)
Step 1: Prepare Your Raspberry Pi
First, ensure your Raspberry Pi is up to date and install Nginx, which will serve as our web server.
-
Update your system:
sudo apt update sudo apt full-upgrade sudo reboot
-
Install Nginx:
sudo apt install nginx
-
Verify Nginx Installation:
Visit your Raspberry Pi’s local IP address in a browser. You should see the default Nginx welcome page.
Step 2: Build and Deploy Your Website
With your Raspberry Pi ready, it’s time to build your website and place it where Nginx can serve it.
-
Navigate to your project directory and build your website:
cd /path/to/your/website/project npm run build
This creates a
dist
folder (or your configured output folder) containing your website’s static files. -
Create a directory for your website:
sudo mkdir -p /var/www/mywebsite
-
Copy your website files:
sudo cp -r /path/to/your/website/project/dist/* /var/www/mywebsite/
Note: It is recommended to delete old files before copying the new ones to prevent any old files from staying in your website’s directory. You can delete them with:
sudo rm -rf /var/www/mywebsite/*
Step 3: Configure Nginx
Configure Nginx to serve your website.
-
Create a new Nginx configuration file:
sudo nano /etc/nginx/sites-available/mywebsite
-
Add the following configuration, adjusting your domain and paths as necessary:
server { listen 80; server_name yourdomain.com [www.yourdomain.com](https://www.yourdomain.com); root /var/www/mywebsite; index index.html; location / { try_files $uri $uri/ =404; } }
-
Enable the site and disable the default site:
sudo ln -s /etc/nginx/sites-available/mywebsite /etc/nginx/sites-enabled/ sudo unlink /etc/nginx/sites-enabled/default
-
Test and reload Nginx configuration:
sudo nginx -t sudo systemctl reload nginx
Step 4: Install and Configure Cloudflared
Install the Cloudflare Tunnel daemon (cloudflared
) and set up a tunnel.
-
Download and install
cloudflared
:wget [https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb](https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64.deb) sudo dpkg -i cloudflared-linux-arm64.deb
-
Authenticate
cloudflared
:cloudflared tunnel login
Follow the prompts in your browser to log in to your Cloudflare account and select your domain.
-
Create a tunnel:
cloudflared tunnel create mytunnel
-
Configure the tunnel:
sudo mkdir /etc/cloudflared sudo nano /etc/cloudflared/config.yml
Add the following configuration, replacing
mytunnel
with your tunnel name,<UUID>
with your tunnel’s UUID, andyourdomain.com
with your domain:tunnel: mytunnel credentials-file: /home/yourusername/.cloudflared/<UUID>.json ingress: - hostname: yourdomain.com service: http://localhost:80 - hostname: [www.yourdomain.com](https://www.yourdomain.com) service: http://localhost:80 - service: http_status:404
-
Run the tunnel:
cloudflared tunnel --config /etc/cloudflared/config.yml run
Step 5: Configure DNS Records in Cloudflare
-
Log in to your Cloudflare dashboard and go to the DNS settings for your domain.
-
Add CNAME records for your root domain and
www
subdomain pointing to your tunnel’s.cfargotunnel.com
address.- Type:
CNAME
- Name:
@
(for the root domain) - Target:
<your-tunnel-id>.cfargotunnel.com
- Proxy status:
Proxied
- TTL:
Auto
Repeat for the
www
subdomain:- Type:
CNAME
- Name:
www
- Target:
<your-tunnel-id>.cfargotunnel.com
- Proxy status:
Proxied
- TTL:
Auto
- Type:
Step 6: Set up cloudflared
as a systemd Service
To ensure cloudflared
runs automatically on startup:
-
Create a systemd service file:
sudo nano /etc/systemd/system/cloudflared.service
-
Add the following content, adjusting paths and usernames as needed:
[Unit] Description=Cloudflared Tunnel After=network.target [Service] TimeoutStartSec=0 Type=notify ExecStart=/usr/local/bin/cloudflared tunnel --config /etc/cloudflared/config.yml run mytunnel User=yourusername Group=yourusername Restart=on-failure RestartSec=10 [Install] WantedBy=multi-user.target
-
Enable and start the service:
sudo systemctl enable cloudflared sudo systemctl start cloudflared
Step 7: Secure Your Server
Enhance your server’s security by setting up a firewall and a brute-force protection tool.
-
Install and configure
ufw
(Uncomplicated Firewall):sudo apt install ufw sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw allow ssh sudo ufw allow http sudo ufw allow https sudo ufw enable
-
Install and configure
fail2ban
:sudo apt install fail2ban sudo systemctl start fail2ban sudo systemctl enable fail2ban sudo nano /etc/fail2ban/jail.local
Add the following configuration to
jail.local
:[DEFAULT] bantime = 3600 banaction = iptables-multiport findtime = 600 maxretry = 3 [sshd] enabled = true [nginx-http-auth] enabled = true port = http,https filter = nginx-http-auth logpath = /var/log/nginx/error.log [nginx-badbots] enabled = true port = http,https filter = nginx-badbots logpath = /var/log/nginx/access.log [nginx-noscript] enabled = true port = http,https filter = nginx-noscript logpath = /var/log/nginx/access.log
Restart
fail2ban
:sudo systemctl restart fail2ban
Conclusion
You’ve now successfully set up a web server on your Raspberry Pi using Cloudflare Tunnels, Nginx, and enhanced its security with ufw
and fail2ban
. This setup provides a secure and efficient way to host your website from home. Remember to keep your system updated and monitor logs regularly to maintain security and performance.
Further Enhancements:
- HTTPS: Cloudflare Tunnel automatically provisions SSL certificates, so your site should be accessible via HTTPS.
- Caching: Configure Cloudflare’s caching options to improve performance.
- Dynamic DNS: If your home IP address changes, consider setting up dynamic DNS to update your Cloudflare DNS records automatically.
- Monitoring: Set up monitoring tools to keep an eye on your server’s performance and uptime.