Skip to content

Instantly share code, notes, and snippets.

@flackend
Last active March 18, 2022 15:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save flackend/65ff28f5edaddf7411b601d14d62bc1b to your computer and use it in GitHub Desktop.
Save flackend/65ff28f5edaddf7411b601d14d62bc1b to your computer and use it in GitHub Desktop.
Home Raspberry Pi web server DNS

TL;DR: Using an old Raspberry Pi hosted at home in conjunction with CloudFlare and DuckDNS as $1/yr web hosting.

After cPanel hiked its prices, the hosting company I've been using went out of business. I looked for some shared hosting options. They ranged from $30 to $60 a year. That's much more than I want to pay (especially coming from a much better deal with my previous host). My solution is to host them at home on a Raspberry Pi.

I chose a Pi as my hardware versus a spare laptop, since a laptop would cost me at least $30 in electricity in a year. The Pi on the other hand will cost about $1 in electricity. The problem with hosting at home is my IP address will change from time to time. So I had to get a little creative.

I setup DuckDNS to track my IP address. http://example.duckdns.org points to my home IP address and there's a cron job on my Pi that updates my DuckDNS account every 5 minutes. So when my IP address changes, http://example.duckdns.org gets updated automatically.

I pointed my name servers (in my domain registrar's settings) to CloudFlare so it can handle my DNS. Plus, there are a bunch of other benefits (handles SSL, CDN, blocks know malicious IPs). Especially useful is the "Always Online" feature which serves up my site from their cache when my home internet goes down. And lastly, since CloudFlare is proxying my site, I'm able to setup my Pi's firewall (I'm using UFW) to block all incoming connections except those on port 80 coming from CloudFlare (they provides a list of their IPs that I whitelisted).

In CloudFlare, I have two DNS settings. A CNAME for www(.example.com) that points to http://example.duckdns.org. So when someone visits my site, www.example.com, the traffic is sent to my Pi (proxied through CloudFlare). The issue is that I can't setup a CNAME for my root domain, example.com. To get around that, I added a DNS A record that points to a random IP (I chose 8.8.8.8). Then I added a CloudFlare Page Rule that redirects any traffic for example.com/* to https://www.example.com.

The setup took me about a day. So there's some time cost there since it would have taken me about an hour to get the sites setup on shared hosting. But I enjoyed the process and love that I'm saving money with some workarounds.

@flackend
Copy link
Author

@x0rsw1tch pointed out to me that some registrars have DDNS capabilities. That would simplify my setup. I wouldn't need DuckDNS. Though I'd need to setup a new DDNS script to update my registrar instead. I also wouldn't need the CloudFlare Page Rule to redirect non-www to www. And, if I wanted, I could easily make my root domain my default and redirect www traffic to the root domain instead.

@flackend
Copy link
Author

The big problem with this is that if you visit http://site.com/some/page.html, you get redirected to https://www.site.com (losing the URL path). So using the registrar's DDNS option is the way to go. I've decided to write a small NodeJS script to talk to CloudFlare's API.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment