Running a temporary testing server used to mean juggling cloud instances, ngrok sessions, or relying on physical access to a machine. These workarounds are neither sustainable nor scalable. One developer found a better way by leveraging an unused Windows computer and Cloudflare Tunnel to create a permanent, globally accessible testing infrastructure at no cost.
With this setup, every project gets its own permanent HTTPS URL that survives reboots and remains accessible worldwide, all without cloud hosting fees or port-forwarding hassles. The architecture flips traditional networking on its head: instead of opening ports on the machine, the tunnel client initiates a secure connection to Cloudflare, making the server invisible to ISPs and eliminating the need for firewall adjustments.
How the Architecture Works
The system uses a straightforward yet powerful design. A spare Windows machine hosts both Apache (for PHP projects) and Node.js applications. A Cloudflare Tunnel client runs continuously on this machine, creating an encrypted connection to Cloudflare’s network. Cloudflare DNS then routes incoming requests to specific subdomains, forwarding them through the tunnel to the correct local ports.
Here’s the flow:
- A tester anywhere in the world accesses
project1.yourdomain.com - Cloudflare DNS resolves the domain and forwards the request
- The tunnel carries the request securely to the local machine
- Apache or Node.js serves the project from
localhost:3001or similar - Response travels back the same secure path
This design ensures zero inbound exposure on the local network, no port conflicts, and permanent URLs that persist across reboots and network changes.
Prerequisites for the Setup
To replicate this solution, you’ll need a few key components:
- An always-on Windows machine (even an older PC works)
- XAMPP installed with Apache (MySQL is optional)
- A domain you control
- A free Cloudflare account
- The
cloudflaredCLI tool from GitHub - Node.js and PM2 if you run JavaScript projects
Each tool plays a specific role. XAMPP provides the local web server, Cloudflare handles DNS and secure routing, and cloudflared establishes the persistent tunnel connection. PM2 manages Node.js processes to ensure they restart automatically.
Step 1: Transfer DNS Management to Cloudflare
The first phase involves moving your domain’s DNS records to Cloudflare. This is a one-time process that centralizes control and enables advanced features like tunnels and proxying.
Start by adding your domain to Cloudflare. Log in to cloudflare.com, select "Add a Site," and enter your domain name. Choose the free plan and let Cloudflare scan your existing DNS records. This ensures services like email continue working without interruption.
Next, Cloudflare will provide two nameservers (e.g., ns1.cloudflare.com and ns2.cloudflare.com). Copy these values, then visit your domain registrar (such as GoDaddy or Namecheap) and update the nameserver settings to point to Cloudflare. DNS propagation typically completes within minutes, though it can take up to a few hours in rare cases. Once complete, all DNS changes will be managed through Cloudflare’s dashboard.
Step 2: Configure Apache Virtual Hosts for PHP Projects
By default, Apache serves all projects from the same directory on port 80. This setup complicates routing and requires manual path adjustments in code. Virtual hosts solve this by assigning each project its own port, making the local server behave like separate environments.
Open C:\xampp\apache\conf\httpd.conf and locate the Listen section. Add a new line for each project port:
Listen 80
Listen 3001
Listen 3002
Listen 3003Next, ensure Apache loads virtual host configurations by verifying this line is uncommented:
Include conf/extra/httpd-vhosts.confNow, edit C:\xampp\apache\conf\extra\httpd-vhosts.conf to define a virtual host for each project. For example:
<VirtualHost *:3001>
DocumentRoot "C:/xampp/htdocs/project1"
<Directory "C:/xampp/htdocs/project1">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>
<VirtualHost *:3002>
DocumentRoot "C:/xampp/htdocs/project2"
<Directory "C:/xampp/htdocs/project2">
AllowOverride All
Require all granted
</Directory>
</VirtualHost>Save the file, restart Apache via the XAMPP Control Panel, and test access by visiting If you encounter a 403 error, double-check the Directory block permissions. Common issues include missing AllowOverride All or misconfigured Require` directives.
To ensure Apache starts automatically with Windows, open the XAMPP Control Panel, click the Svc checkbox next to Apache, and confirm. This guarantees your projects remain accessible even after system reboots.
Step 3: Manage Node.js Projects with PM2
For JavaScript applications, PM2 provides process management, automatic restarts, and monitoring. Install PM2 globally using npm:
npm install -g pm2
npm install -g pm2-windows-startupStart your Node.js project and assign it a name for easy reference:
cd C:\projects\myapp
pm2 start server.js --name myappEnsure your application listens on the correct port by modifying the server code:
const PORT = process.env.PORT || 3002;
app.listen(PORT, () => console.log(`Running on ${PORT}`));Save the PM2 configuration and enable auto-start on boot:
pm2 save
pm2-startup installPM2 offers several useful commands for ongoing management:
pm2 list– View all running projectspm2 logs myapp– Monitor real-time logspm2 restart myapp– Restart after code updatespm2 monit– Access a live CPU and memory dashboard
Step 4: Establish the Cloudflare Tunnel Connection
With the local server ready, the final step links everything together via Cloudflare Tunnel. This connection remains active indefinitely, even through reboots, ensuring permanent access to your projects.
Begin by installing cloudflared. Download the Windows 64-bit executable from the GitHub releases page, rename it to cloudflared.exe, and place it in C:\cloudflared\. Add this directory to your system PATH, then verify the installation:
cloudflared --versionNext, authenticate with Cloudflare:
cloudflared tunnel loginThis command opens a browser window where you authorize the tunnel to access your Cloudflare account. A certificate file is saved to C:\Users\YourUser\.cloudflared\cert.pem.
Create a new tunnel using a unique name:
cloudflared tunnel create test-tunnelA tunnel ID and credentials file will be generated. Store these securely, as they’re required for future configurations. The next step involves creating a configuration file that maps subdomains to local services. Create C:\cloudflared\config.yml with content like:
tunnel: <TUNNEL_ID>
credentials-file: C:\Users\YourUser\.cloudflared\<TUNNEL_ID>.json
ingress:
- hostname: project1.yourdomain.com
service:
- hostname: project2.yourdomain.com
service:
- service: Update the hostname entries to match your domain and subdomains. The final service line acts as a catch-all for unmatched requests. Save the file and start the tunnel:
cloudflared tunnel run test-tunnelTest access by visiting your subdomain (e.g., `). The connection should load instantly, with traffic secured by Cloudflare’s network. To ensure the tunnel runs continuously, create a Windows service:
cloudflared service install
cloudflared service startWith this in place, your testing infrastructure is fully operational—permanent, secure, and cost-free.
The Benefits of a Self-Hosted Testing Server
This approach eliminates the recurring costs and complexity of cloud testing environments. Instead of spinning up VMs for every preview or demo, teams can rely on a single, always-on machine. The permanent HTTPS URLs simplify collaboration, enabling stakeholders to access builds from anywhere without VPNs or physical access.
For developers managing multiple projects, virtual hosts and PM2 streamline workflows, reducing manual configuration and downtime. The Cloudflare Tunnel architecture further enhances security by removing the need for open ports, reducing attack surfaces while maintaining global accessibility.
As organizations scale, this model can extend to include load balancers, additional subdomains, or even multiple physical machines. The foundation remains lightweight, cost-effective, and built on open-source tools—proving that sometimes, the best infrastructure isn’t in the cloud, but right under your desk.
AI summary
Learn how to create a permanent, zero-cost testing server using Cloudflare Tunnel on a spare Windows machine. No cloud fees, no port forwarding, just permanent HTTPS URLs.