Self-Hosting Mastodon Behind Cloudflare Tunnel
I recently migrated my Mastodon server to my homelab. As I’m on a domestic UK internet connection, my IP address changes periodically - which rules out relying on a static public IP. I also didn’t want to forward ports 80 and 443, so I opted for Cloudflare Tunnels instead.
Here’s how I got Mastodon running behind a Cloudflare Tunnel.
Set Up Mastodon
I covered the initial setup in my first ever blog post, so I won’t repeat it here. For the migration of my existing server I followed the official migration docs which are really really thorough.
Set Up Cloudflare Tunnel
Install
cloudflared. On Ubuntu or another Debian-based distro, I recommend using the Cloudflare package repository:# Add the Cloudflare GPG key sudo mkdir -p --mode=0755 /usr/share/keyrings curl -fsSL https://pkg.cloudflare.com/cloudflare-main.gpg | sudo tee /usr/share/keyrings/cloudflare-main.gpg >/dev/null # Add the repo to your apt sources echo 'deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] https://pkg.cloudflare.com/cloudflared any main' | sudo tee /etc/apt/sources.list.d/cloudflared.list # Install cloudflared sudo apt-get update && sudo apt-get install cloudflaredLog in:
cloudflared tunnel loginCreate a tunnel:
cloudflared tunnel create mastodonmastodonhere is just the internal name for the tunnel - it’s for your reference only. Cloudflare will return a tunnel UUID; keep a note of it for the next step.Configure the tunnel by creating
~/.cloudflared/config.yml:tunnel: {uuid} # replace with your UUID here credentials-file: /home/mastodon/.cloudflared/{uuid}.json # replace with your UUID here ingress: - hostname: mastodon.example.com # replace with your Mastodon domain service: https://127.0.0.1:443 originRequest: httpHostHeader: mastodon.example.com # replace with your Mastodon domain noTLSVerify: true - service: http_status:404Two things to note here:
originRequest.httpHostHeadermust be set, otherwise the underlying nginx can’t identify your virtual host.originRequest.noTLSVerify: trueis required because nginx won’t have a valid certificate for127.0.0.1. Without this, the tunnel will refuse to connect.
Create the DNS record:
cloudflared tunnel route dns mastodon mastodon.example.comReplace
mastodonwith your tunnel name (if you used a different one in step 3), andmastodon.example.comwith your actual domain.Install
cloudflaredas a service:sudo cloudflared --config /home/mastodon/.cloudflared/config.yml service install
That’s it. Visit https://mastodon.example.com in your browser and you should land on your Mastodon instance.