DEV Community

David Loor
David Loor

Posted on • Originally published at davidloor.com on

How to Share Your Local WordPress or Drupal Site with Cloudflare Tunnel (Free)

When developing locally with DDEV, you might need to share your work with clients, test webhooks from external services, or collaborate with remote team members. Cloudflare Tunnel provides a secure, simple way to expose your local development sites to the internet without opening firewall ports or dealing with complex networking configurations.

What is Cloudflare Tunnel?

Cloudflare Tunnel (formerly Argo Tunnel) is part of Cloudflare's Zero Trust networking solution. It creates a secure, outbound-only connection from your local machine to Cloudflare's edge network, which then routes public traffic to your local services. This means:

  • No open inbound ports - Your firewall stays secure
  • No public IP required - Works behind NAT and corporate firewalls
  • Free for development use - Cloudflare's quick tunnels are free
  • HTTPS by default - Automatic SSL/TLS encryption
  • Simple setup - Just one command to get started

What is DDEV?

DDEV is a Docker-based local development environment that makes it easy to set up PHP projects (Drupal, WordPress, Laravel, etc.) with minimal configuration. It provides:

  • Pre-configured containers for web, database, and other services
  • Support for multiple PHP versions
  • Built-in SSL certificates for local HTTPS
  • Command-line tools for common development tasks

Using DDEV with Cloudflare Tunnel lets you run your site locally and share it publicly whenever needed.

Prerequisites

Before we begin, make sure you have:

  • A Mac, Linux, or Windows machine with Docker installed
  • DDEV installed and configured (official installation guide or check out my guide on setting up DDEV for WordPress and Drupal)
  • A working DDEV project (we'll use example sites like myproject.ddev.site and client-site.ddev.site)
  • Basic command-line familiarity
  • No Cloudflare account required for quick tunnels (the method covered in this guide)

Note: If you want persistent URLs with custom domains (covered later), you'll need a free Cloudflare account.

Step 1: Install Cloudflared

The cloudflared daemon is the client that creates the tunnel connection. Installation varies by platform:

macOS (Homebrew)

brew install cloudflared
Enter fullscreen mode Exit fullscreen mode

Linux (Debian/Ubuntu)

wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.debsudo dpkg -i cloudflared-linux-amd64.deb
Enter fullscreen mode Exit fullscreen mode

Linux (RHEL/CentOS)

wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-x86_64.rpmsudo rpm -i cloudflared-linux-x86_64.rpm
Enter fullscreen mode Exit fullscreen mode

Windows

Download the installer from the Cloudflare downloads page or use Chocolatey:

choco install cloudflared
Enter fullscreen mode Exit fullscreen mode

Verify the installation:

cloudflared --version
Enter fullscreen mode Exit fullscreen mode

Step 2: Start Your DDEV Site

Make sure your DDEV project is running. Navigate to your project directory and start DDEV:

cd /path/to/your/projectddev start
Enter fullscreen mode Exit fullscreen mode

Your site will be available locally at something like https://yourproject.ddev.site. Verify it works by opening it in your browser.

Step 3: Create a Cloudflare Tunnel to Your DDEV Site

Here's where it gets interesting. Run one command and cloudflared creates a tunnel with a public URL automatically. No account setup, no authentication, no configuration needed. The basic syntax is:

cloudflared tunnel --url <local-url> --http-host-header <hostname>
Enter fullscreen mode Exit fullscreen mode

Example 1: My Project Site

cloudflared tunnel --url https://myproject.ddev.site/ --http-host-header myproject.ddev.site
Enter fullscreen mode Exit fullscreen mode

Example 2: Client Site

cloudflared tunnel --url https://client-site.ddev.site/ --http-host-header client-site.ddev.site
Enter fullscreen mode Exit fullscreen mode

After running this command, you'll see output like:

2025-10-14T10:30:15Z INF Thank you for trying Cloudflare Tunnel. Doing so, without a Cloudflare account, is a quick way to experiment and try it out. However, be aware that these account-less Tunnels have no uptime guarantee. If you intend to use Tunnels in production you should use a pre-created named tunnel by following: https://developers.cloudflare.com/cloudflare-one/connections/connect-apps2025-10-14T10:30:15Z INF Requesting new quick Tunnel on trycloudflare.com...2025-10-14T10:30:16Z INF +--------------------------------------------------------------------------------------------+2025-10-14T10:30:16Z INF | Your quick Tunnel has been created! Visit it at (it may take some time to be reachable): |2025-10-14T10:30:16Z INF | https://randomly-generated-subdomain.trycloudflare.com |2025-10-14T10:30:16Z INF +--------------------------------------------------------------------------------------------+
Enter fullscreen mode Exit fullscreen mode

Copy the generated URL (e.g., https://randomly-generated-subdomain.trycloudflare.com) and share it with anyone who needs access to your local site!

Understanding the Command Parameters

Let's break down what each parameter does:

  • --url : The local URL where your DDEV site is running. Use HTTPS if your DDEV site uses SSL (which it does by default).
  • --http-host-header : This is crucial for DDEV. It tells cloudflared to forward the correct hostname in the HTTP Host header. DDEV routes requests based on this header, so without it, you'll get a "404 Not Found" or see the wrong site.

Why is --http-host-header Necessary?

DDEV's router uses virtual hosting, meaning multiple sites can run on the same IP address and port. The router determines which site to serve based on the Host header in the HTTP request.

When traffic comes through Cloudflare Tunnel, the Host header would normally be the Cloudflare-generated domain (like randomly-generated-subdomain.trycloudflare.com). By specifying --http-host-header myproject.ddev.site, we override this and ensure DDEV sees the correct hostname.

Using Named Tunnels for Persistent URLs

The quick tunnel method above is perfect for ad-hoc sharing, but the URL changes each time you run the command and there's no uptime guarantee. If you need a persistent URL with your own custom domain (like myproject.example.com), you can create a named tunnel. This requires a free Cloudflare account.

1. Authenticate with Cloudflare

cloudflared tunnel login
Enter fullscreen mode Exit fullscreen mode

This opens a browser to authenticate with your Cloudflare account.

2. Create a Named Tunnel

cloudflared tunnel create my-ddev-tunnel
Enter fullscreen mode Exit fullscreen mode

This generates a tunnel ID and credentials file.

3. Create a Configuration File

Create ~/.cloudflared/config.yml:

tunnel: <TUNNEL-ID>credentials-file: /Users/yourusername/.cloudflared/<TUNNEL-ID>.jsoningress: - hostname: mysite.example.com service: https://myproject.ddev.site originRequest: httpHostHeader: myproject.ddev.site noTLSVerify: true - service: http_status:404
Enter fullscreen mode Exit fullscreen mode

Note: noTLSVerify: true is needed because DDEV uses self-signed certificates.

4. Route Your Domain

cloudflared tunnel route dns my-ddev-tunnel mysite.example.com
Enter fullscreen mode Exit fullscreen mode

5. Run the Tunnel

cloudflared tunnel run my-ddev-tunnel
Enter fullscreen mode Exit fullscreen mode

Your site is now accessible at https://mysite.example.com with a persistent URL!

Common Use Cases

1. Client Demos

Share work-in-progress sites with clients without deploying to staging servers:

cloudflared tunnel --url https://client-demo.ddev.site/ --http-host-header client-demo.ddev.site
Enter fullscreen mode Exit fullscreen mode

Send the generated URL to your client for instant feedback.

2. Webhook Testing

Test webhooks from services like Stripe, GitHub, or Twilio that require a public URL:

cloudflared tunnel --url https://webhooks.ddev.site/ --http-host-header webhooks.ddev.site
Enter fullscreen mode Exit fullscreen mode

Configure the webhook in the external service to point to your Cloudflare URL.

3. Mobile Device Testing

Test your responsive designs on real mobile devices without being on the same network:

cloudflared tunnel --url https://mobile-test.ddev.site/ --http-host-header mobile-test.ddev.site
Enter fullscreen mode Exit fullscreen mode

Open the Cloudflare URL on your phone to test on real devices.

4. Remote Collaboration

Share your development environment with remote teammates:

cloudflared tunnel --url https://team-collab.ddev.site/ --http-host-header team-collab.ddev.site
Enter fullscreen mode Exit fullscreen mode

Your team can access the site as if they were running it locally.

Troubleshooting

Getting a 404 or Wrong Site

Make sure you're using the --http-host-header parameter with the correct DDEV hostname:

cloudflared tunnel --url https://mysite.ddev.site/ --http-host-header mysite.ddev.site
Enter fullscreen mode Exit fullscreen mode

SSL Certificate Errors

If you're using a named tunnel with a config file, add noTLSVerify: true to the origin request section since DDEV uses self-signed certificates.

Tunnel Not Starting

Check if cloudflared is already running:

ps aux | grep cloudflared
Enter fullscreen mode Exit fullscreen mode

Kill any existing processes if needed:

pkill cloudflared
Enter fullscreen mode Exit fullscreen mode

DDEV Site Not Accessible Locally

Verify your DDEV site is running:

ddev describe
Enter fullscreen mode Exit fullscreen mode

Make sure the URL you're using matches the output.

Security Considerations

While Cloudflare Tunnel is secure by design, keep these points in mind:

  • Don't expose production databases - Only tunnel development sites with non-sensitive data
  • Quick tunnels are temporary - URLs expire and shouldn't be relied upon for production
  • Use authentication - For sensitive projects, add Cloudflare Access authentication to your named tunnels
  • Monitor tunnel access - Check Cloudflare Analytics to see who's accessing your tunnels
  • Shut down tunnels when done - Use Ctrl+C to stop the tunnel when you're finished

Alternative: DDEV's Built-in Share Command

DDEV also has a built-in ddev share command that uses ngrok. However, Cloudflare Tunnel offers several advantages:

  • Free without rate limits (ngrok free tier has limits)
  • Better performance through Cloudflare's global network
  • Integration with Cloudflare Zero Trust for advanced features
  • Persistent named tunnels with custom domains

That said, ddev share is even simpler if you just need something quick and don't want to install additional tools.

Additional Resources

Top comments (0)