Below is a detailed, step-by-step guide to hosting your Django project on a Raspberry Pi behind Cloudflare Tunnel. The end result will be a secure HTTPS connection to your Raspberry Piâs Django application using your own domain name, without having to open ports on your home router.
Overview of the Process¶
- Obtain a Domain and Add It to Cloudflare
- Prepare the Raspberry Pi (update system, install Python dependencies, set up Django)
- Install and Configure Cloudflare Tunnel (
cloudflared) on the Pi - Configure Your Tunnel to point your domain to the local Django server port
- Test and Verify everything works under
https://yourdomain.com
1. Set Up Your Domain on Cloudflare¶
1.1 Obtain a Domain Name¶
- Purchase a domain from a registrar (e.g., Namecheap, Google Domains, etc.) if you donât already have one.
1.2 Create a Cloudflare Account and Add Your Domain¶
- Go to https://dash.cloudflare.com/ and sign up or log in.
- Click Add a Site.
- Enter your domain name (e.g.,
example.com) and select a free plan (or paid if you prefer). - Cloudflare will scan existing DNS records (you can review or adjust these later).
- Youâll be prompted to change your domainâs nameservers to Cloudflareâs nameservers.
- Log in to your domain registrar, find the DNS or Nameservers settings, and update them to the nameservers shown by Cloudflare.
- Wait for Cloudflare to confirm your domain is active (this can take from a few minutes up to 24 hours, but usually itâs quick).
Once your domain is active in Cloudflare, you will manage its DNS from the Cloudflare dashboard.
2. Prepare Your Raspberry Pi¶
2.1 Update and Install System Packages¶
- SSH into your Raspberry Pi or connect via a monitor/keyboard.
- Update the system:
- (Optional) Install some useful packages:
2.2 Set Up Your Django Project¶
Assuming you already have a Django project, do something like:
- Clone the barodybroject repository onto the Pi:
- Create a virtual environment and install dependencies:
- Run migrations and test the development server locally:
- If you see the Django welcome page on
http://<Pi-IP>:8000, youâre good. Stop the dev server (Ctrl + C).
2.3 (Optional) Use Gunicorn/Uvicorn in Production Mode¶
For a more robust setup, you can run Django via Gunicorn or Uvicorn. For instance:
- This will bind your app to localhost:8000. - You can set this up as a systemd service so it starts automatically, or just run it in a screen/tmux session for testing.3. Install and Configure cloudflared on Raspberry Pi¶
Cloudflare Tunnel works by installing a small daemon (cloudflared) on your Raspberry Pi that creates an outbound-only connection to Cloudflareâs network. Then, Cloudflare routes inbound traffic (from the public internet) over that tunnel to your Pi.
3.1 Install cloudflared¶
Option A: Install Using the Official Cloudflare .deb Package¶
- Download and add the Cloudflare GPG key:
-
Add the Cloudflare apt repository:
(Note: Replaceecho "deb [signed-by=/usr/share/keyrings/cloudflare-main.gpg] http://pkg.cloudflare.com/ jammy main" | sudo tee /etc/apt/sources.list.d/cloudflare.listjammywith your actual OS codename if necessary. Raspberry Pi OS is often based onbullseyeorbuster, so verify which repository is appropriate. More info here: Cloudflare Docs.) -
Update and install:
Option B: Install via Manually Downloading Binary (If APT not supported)¶
- Go to the Cloudflare GitHub Releases page, download the latest ARM .deb or tarball for Raspberry Pi, and install it manually: (Instructions vary, but typically itâs straightforward to install.)
3.2 Authenticate cloudflared¶
- Log in to Cloudflare from the Pi:
- This command will print a URL. Copy it, open it in your browser (where youâre logged in to Cloudflare), and authorize
cloudflared. - Once authorized, return to your Pi terminal.
4. Create and Configure a Named Tunnel¶
4.1 Create the Tunnel¶
- Create a new tunnel (give it a name):
- This stores a credentials JSON file to your system, typically at:
or
/etc/cloudflared/<TUNNEL_ID>.json.
4.2 Configure the Tunnel to Point to Django¶
Create (or edit) a config file for this tunnel. For example:
(Location can vary; just be consistent. Many users keep it in/home/pi/.cloudflared/.)
Put something like this in config.yml:
tunnel: <TUNNEL_ID_FROM_ABOVE>
credentials-file: /etc/cloudflared/<TUNNEL_ID>.json
ingress:
- hostname: yourdomain.com
service: http://localhost:8000
- service: http_status:404
Explanation:
- tunnel: The unique tunnel ID you generated.
- credentials-file: Path to the JSON credentials from step 4.1.
- ingress rules:
- First rule: direct requests for
yourdomain.comtohttp://localhost:8000(where Gunicorn or Django dev server is running). - Second rule: a âcatch-allâ for anything else that returns a 404.
4.3 Route Your Domain to the Tunnel¶
- You can do this either from the Cloudflare web dashboard or from the command line.
- From command line:
This will automatically create a DNS record (CNAME) in Cloudflare linking
yourdomain.comto the tunnel.
4.4 Start the Tunnel¶
or(Optional) Run as a Systemd Service¶
To ensure Cloudflare Tunnel starts at boot, you can enable the service:
Now your Pi will automatically connect to Cloudflare on reboot.
5. Configure Cloudflare SSL/TLS Settings¶
Log in to your Cloudflare dashboard and do the following:
- Go to SSL/TLS â Overview for your domain.
- Choose the encryption mode:
- Flexible: Encrypts traffic between the browser and Cloudflare, but unencrypted between Cloudflare and your Pi. This is easiest if you donât have an SSL certificate installed locally.
- Full (strict recommended if you can manage local certificates): End-to-end encryption. Requires you to have a certificate on the Pi or use an origin cert from Cloudflare.
For quick setups, Flexible is fine. If you want truly secure end-to-end, switch to âFull (strict)â once youâve installed an SSL cert on your Pi (you can use Cloudflare Origin Certificates, for example).
6. Test Your Setup¶
- Ensure your Django application is running locally on
localhost:8000(e.g.,gunicorn your_django_project.wsgi:application --bind 127.0.0.1:8000). - Ensure
cloudflaredtunnel is running: or if running manually, confirm itâs showing âConnected to Cloudflare.â - In a web browser, go to
https://yourdomain.com. - You should see your Django app!
If everything is working, you have a secure, globally accessible site:
- Browsers show HTTPS lock icon (if Cloudflare SSL settings are correct).
- Your Piâs public IP remains hidden (no open ports, no direct exposure).
7. Additional Best Practices¶
- Set Djangoâs
ALLOWED_HOSTS - In the settings file (located at src/barodybroject/settings.py), add your domain (e.g., "yourdomain.com") along with "localhost" and "127.0.0.1":
- Run in Production Mode
- Use Gunicorn (or Uvicorn) + a process manager (systemd) or Docker.
- Secure Your Pi
- Disable password SSH login, use SSH keys.
- Keep software updated (
sudo apt update && sudo apt upgrade). - Logging and Metrics
- Check Cloudflareâs dashboard for requests, error logs, etc.
- Check
cloudflaredlogs on the Pi:journalctl -u cloudflared -f. - Use a Reverse Proxy Locally (Optional)
- Some prefer Nginx or Caddy on the Pi to handle advanced logic (e.g., multiple apps). You can still have your local proxy listen on
localhost:8000orlocalhost:8080, andcloudflaredforwards traffic to that port.
Final Summary¶
Cloudflare Tunnel is one of the easiest and most secure ways to host your Django app on a Raspberry Pi from home without exposing ports or dealing with dynamic IP headaches. In a nutshell:
- Set up your domain on Cloudflare (and make sure DNS is managed by Cloudflare).
- Install and authenticate
cloudflaredon the Pi. - Run your Django application on a local port (e.g.,
127.0.0.1:8000). - Create a named tunnel and configure Cloudflare to forward requests from
yourdomain.comtolocalhost:8000. - Browse to
https://yourdomain.comand enjoy your publicly accessible, SSL-protected Django site with minimal fuss and maximum security.