Setting Up a Cloudflare Tunnel on Windows Server to Publish eRapor Securely Using a School Domain
Imagine your school has a domain such as sekolahku.sch.id and you want to serve an internal application like eRapor that normally runs only inside the LAN. Teachers need to access it from home, students need to check their data, and admins want a secure way to publish it without touching the router or exposing port 80 or 443. Cloudflared Tunnel solves this by creating a persistent outbound connection from your Windows Server to Cloudflare. Cloudflare then routes traffic from your domain to your internal service.

This tutorial explains the entire setup in a clear and practical way. It is written for Windows Server users who want a predictable, reproducible, and transparent workflow. It also fits well with your preference for audit friendly infrastructure and deterministic behavior.
Prerequisites
Before you begin, make sure you have the following:
- A Cloudflare account with your school domain added
- Administrator access to your Windows Server
- Your internal service running for example eRapor on port 3000 or 8000
- Basic understanding of DNS so you know what a CNAME is
- A stable internet connection on the server
Step 1. Install cloudflared on Windows Server
Cloudflared is the small connector program that creates the tunnel. Installing it on Windows Server is simple.
- Download the latest cloudflared Windows installer from Cloudflare
- Run the installer as Administrator
- After installation, open PowerShell as Administrator
- Verify installation with:
cloudflared --version
If you see a version number, the installation is correct.
You can absolutely install cloudflared through Winget instead of downloading the installer manually. This is often cleaner for Windows Server environments because it keeps everything scriptable and easy to audit. Below is a polished alternative line you can drop directly into your tutorial.
Alternative installation using Winget
If you prefer a package manager based workflow, you can install cloudflared through Winget. This is ideal for automated deployments, reproducible setups, and environments where you want to avoid manual downloads. Use the following command in an elevated PowerShell session:
winget install Cloudflare.cloudflared
This gives you a fully installed cloudflared binary without touching the browser. It also integrates nicely with your existing provisioning scripts and supports future upgrades through:
winget upgrade Cloudflare.cloudflared
Step 2. Authenticate cloudflared with Cloudflare
Cloudflared needs permission to create tunnels for your domain.
Run this command in PowerShell:
cloudflared login
This will open a browser window asking you to choose the domain you want to authorize. Select your school domain. Once approved, cloudflared stores a certificate file in:
C:\Users\<YourUser>\.cloudflared\
This certificate allows you to create tunnels without entering credentials again.
Step 3. Create the tunnel
Now you can create a named tunnel. Use a descriptive name such as erapor or sekolah.
Example:
cloudflared tunnel create erapor
Cloudflared will generate a tunnel ID and store credentials in the same folder. Keep this safe because it identifies your tunnel.
Step 4. Create the configuration file
Cloudflared uses a YAML file to define what services you want to expose. This file is the heart of your setup and is perfect for your audit friendly workflow because it is plain text and versionable.
Create a file named config.yml in:
C:\Users\<YourUser>\.cloudflared\
Example content:
tunnel: <YOUR_TUNNEL_ID>
credentials-file: C:\Users\<YourUser>\.cloudflared\<YOUR_TUNNEL_ID>.json
ingress:
- hostname: erapor.sekolahku.sch.id
service: http://localhost:3000
- service: http_status:404
Explanation:
- The first ingress rule maps your public hostname to your internal service
- The final rule catches everything else and returns a 404
This file is simple, readable, and deterministic which fits your style perfectly.
Step 5. Create the public hostname in CloudflareNow you need to tell Cloudflare that erapor.sekolahku.sch.id should route through your tunnel.
Run:
cloudflared tunnel route dns erapor erapor.sekolahku.sch.id
This creates a CNAME record pointing to the tunnel. You do not need to create it manually in the Cloudflare dashboard.
Step 6. Run the tunnel for testing
Before installing it as a service, test it manually.
Run:
cloudflared tunnel run erapor
If everything is correct, you will see logs showing that the tunnel is connected. Try opening:
https://erapor.sekolahku.sch.id
If your internal service loads, the tunnel works.
Step 7. Install cloudflared as a Windows service
Create the .cloudflared directory for the SYSTEM account
Since Cloudflared runs as a Windows service under the SYSTEM profile, you must place its configuration and credentials here:
C:\Windows\System32\config\systemprofile\.cloudflared
Copy required files into the folder
Place the following files inside .cloudflared:
cert.pem(downloaded from your Cloudflare account)- Tunnel credentials JSON (e.g.,
<Tunnel-UUID>.json) config.yml(your Cloudflared configuration file)
Create or edit config.yml
Example minimal configuration:
tunnel: <Tunnel-UUID>
credentials-file: C:\Windows\System32\config\systemprofile\.cloudflared\<Tunnel-UUID>.json
ingress:
- hostname: erapor.example.com
service: http://localhost:8080
- service: http_status:404
Install Cloudflared as a service
Run the following command from an elevated PowerShell or Command Prompt:
cloudflared.exe service install
This registers Cloudflared as a Windows service under the SYSTEM account.
Verify the service configuration
- Open Registry Editor and navigate to:
HKLM\SYSTEM\CurrentControlSet\Services\Cloudflared - Confirm the
ImagePathpoints to:"C:\Windows\System32\config\systemprofile\.cloudflared\cloudflared.exe" --config "C:\Windows\System32\config\systemprofile\.cloudflared\config.yml" tunnel run <Tunnel-UUID>
Start the service
net start cloudflared
The tunnel should now run automatically under the SYSTEM account whenever the server boots.
🔐 Notes
- Only edit the
.cloudflaredsubfolder — do not modify other parts ofsystemprofile. - Ensure file permissions restrict access to SYSTEM only.
- Keep backups of
cert.pemand tunnel credentials JSON for reproducibility.
Step 8. Verify everything
Check the following:
- Cloudflared service is running using the Services panel
- Your hostname resolves correctly using nslookup
- Your internal service is reachable through the domain
- Your config.yml is correct and contains no indentation errors
If something fails, cloudflared logs are very helpful. You can view them with:
Get-Content "C:\ProgramData\Cloudflare\cloudflared\cloudflared.log" -Wait
Security considerations
Cloudflare Tunnel is secure by design because:
- No inbound ports are opened
- Traffic is encrypted end to end
- Cloudflare can enforce Zero Trust policies
- You can restrict access to specific emails or groups
If you want to protect eRapor so only teachers can access it, Cloudflare Access is a perfect match.
Operational tips
To keep your setup clean and maintainable:
- Store config.yml in version control
- Document your tunnel ID in your deployment notes
- Use descriptive hostnames for each service
- Restart cloudflared after changes to apply updates
- Monitor logs regularly for connection issues
This approach aligns well with your preference for transparent and reproducible workflows.

You now have a complete Cloudflare Tunnel setup on Windows Server that securely exposes an internal application like eRapor to the internet using your school domain. The entire process avoids router changes, avoids port forwarding, and gives you a clean configuration that you can audit and maintain easily. Cloudflare Tunnel is one of the most elegant ways to publish internal services, especially in environments where security and simplicity matter.
