Build a Secure Preview Gateway
Expose a loopback app through a temporary HTTPS development gateway.
Introduction
30 Second Summary
A work-in-progress page is hard to share when it only exists on your computer. Screenshots miss the feel of clicking through the real thing.
In this project, you will build a gateway status page that stays on your Windows computer at http://localhost:8000. You will use a Cloudflare Quick Tunnel to publish a temporary HTTPS link while the origin server stays bound to the loopback address.
What You'll Build
You'll watch the same Secure Preview Gateway page load from a public HTTPS link while its server remains reachable only on your computer.
By the end of this project, you'll have:
- A local-only status page you can open in Microsoft Edge at http://localhost:8000 while the server listens on 127.0.0.1:8000.
- A temporary public gateway that lets you load the same page from a generated trycloudflare.com URL over HTTPS.
- A repeatable traffic-path test that shows requests in the local server log. Stopping the tunnel breaks the public path. Restarting it restores access.
- Secret Mission: Route the same temporary gateway to your in-progress app. You will test one real screen or endpoint through its generated HTTPS link.
Are there any prerequisites?
You need a supported Windows computer with permission to install Python 3.14.7 plus cloudflared 2026.8.2. A Cloudflare account or domain is not required.
Before We Start
This first checkpoint commits you to a temporary development gateway before any tools or traffic enter the picture. A clear app and audience give the preview link a real purpose.
Install and Verify the Gateway Tools
Your preview gateway needs one program to serve the local page. Python provides that lightweight origin server.
The cloudflared client creates the tunnel connection. A fresh Windows PowerShell window will confirm that both programs are ready before any traffic is exposed.
In this step, get ready to:
- Install Python 3.14.7 for the local preview server.
- Install cloudflared 2026.8.2 for tunnel traffic.
- Verify both tools in a fresh Windows PowerShell window.
Install Python 3.14.7
Your computer may already have Python installed. Checking its version first shows whether you can use the existing runtime.
- Press the Windows key to open Windows search.
- Type Windows PowerShell into the search field.
- Press Enter to open Windows PowerShell.
- Check the active Python version by running this command:
python --version
What Does This Check Do?
The python --version command asks the active Python executable to report its version. The result shows whether this PowerShell window can find the required runtime.
Choose the tab that matches the output in your PowerShell window.
✔️ I see version 3.14.7
Good. Python 3.14.7 is ready to serve the local preview later in the project.
ⓧ I see an older version
The active Python runtime is older than 3.14.7. Install the pinned release so the project uses the expected toolchain.
- Open the official Python release page for 3.14.7 in Microsoft Edge.
- Find the Windows download section.
- Select Download Windows installer (64-bit).
- Open the downloaded installer.
- Approve the Windows permission request.
- Complete the installer.
- Close every open Windows PowerShell window.
- Repeat the version check above in a fresh Windows PowerShell window.
You should now see Python 3.14.7 in the output.
ⓧ Command not found
Windows cannot find a Python installation from this PowerShell window. Install the pinned runtime from the official release page.
- Open the official Python release page for 3.14.7 in Microsoft Edge.
- Find the Windows download section.
- Select Download Windows installer (64-bit).
- Open the downloaded installer.
- Approve the Windows permission request.
- Complete the installer.
- Close every open Windows PowerShell window.
- Repeat the version check above in a fresh Windows PowerShell window.
You should now see Python 3.14.7 in the output.
Still Seeing the Wrong Python Version?
- Close every Windows PowerShell window before checking again.
- Run the Python 3.14.7 installer again if the older version remains active.
Ask for help with a Python version mismatch on Windows.
Install cloudflared 2026.8.2
The cloudflared client carries requests between the public gateway and your local origin. A version check shows whether the required client is already available.
- Return to the Windows PowerShell window from the Python check.
- Check the active cloudflared version by running this command:
cloudflared --version
What Does This Check Do?
The cloudflared --version command asks the tunnel client to report its installed version. The result confirms whether PowerShell can locate the client.
Choose the tab that matches the output in your PowerShell window.
✔️ I see version 2026.8.2
Great. The cloudflared 2026.8.2 tunnel client is ready for the gateway step.
ⓧ I see an older version
The installed tunnel client is older than 2026.8.2. Install the pinned MSI release before continuing.
- Open Cloudflare's official cloudflared 2026.8.2 release in Microsoft Edge.
- Expand the Assets section if the downloads are hidden.
- Select cloudflared-windows-amd64.msi.
- Open the downloaded MSI installer.
- Approve the Windows permission request.
- Complete the installer.
- Close every open Windows PowerShell window.
The final check below opens a fresh PowerShell window so it can locate the updated client.
ⓧ Command not found
Windows cannot find the tunnel client from this PowerShell window. Install the Windows 64-bit MSI from Cloudflare's official release.
- Open Cloudflare's official cloudflared 2026.8.2 release in Microsoft Edge.
- Expand the Assets section if the downloads are hidden.
- Select cloudflared-windows-amd64.msi.
- Open the downloaded MSI installer.
- Approve the Windows permission request.
- Complete the installer.
- Close every open Windows PowerShell window.
The final check below opens a fresh PowerShell window so it can locate the new client.
Still Seeing cloudflared Not Found?
- Close every Windows PowerShell window after the MSI finishes.
- Open a fresh Windows PowerShell window before retrying the version check.
Ask for help with a cloudflared installation that PowerShell cannot find.
Verify Python and cloudflared
You will use Microsoft Edge to test the preview URLs. You will use Windows Notepad to create the gateway page in the next step.
- Press the Windows key to open Windows search.
- Enter Microsoft Edge in the search field.
- Select Microsoft Edge from the search results.
Microsoft Edge opens successfully. This confirms that your browser is available for the local and gateway checks.
- Close Microsoft Edge.
- Press the Windows key to open Windows search.
- Enter Notepad in the search field.
- Select Notepad from the search results.
Windows Notepad opens with a blank document. Your browser and text editor are both available for the next step.
- Close Windows Notepad.
Missing Edge or Notepad?
A missing standard app can depend on how your Windows computer is managed. Ask whoever manages the computer to restore the app before continuing.
Ask for help with finding a missing Windows app.
The final verification needs a new terminal session so PowerShell can detect changes made by both installers.
- Close every open Windows PowerShell window.
- Press the Windows key to open Windows search.
- Type Windows PowerShell into the search field.
- Press Enter to open a fresh Windows PowerShell window.
Before you run both checks, picture the two version numbers you expect to see.
- Verify the complete gateway toolchain by running both commands:
python --version
cloudflared --version
What Should I See?
The first output includes Python 3.14.7. The second output includes 2026.8.2.
These results prove that the fresh PowerShell session can locate both gateway tools.
One Version Check Still Failing?
- Confirm that you closed every PowerShell window after the installers finished.
- Repeat the installer for the tool whose required version is missing.
- Open another fresh Windows PowerShell window before checking again.
Ask for help with the failing gateway tool version check.
That is the toolchain ready. Python can serve your origin while cloudflared carries gateway traffic.
Your Windows toolchain is ready. Next, you will create a visible preview page that listens only on your computer.
Launch a Local-Only Preview App
Your gateway tools are ready. The next piece is an origin server that gives the gateway real content to carry.
A Python server can use loopback binding to listen only on your computer. This keeps the preview away from every other network interface.
In this step, get ready to:
- Create the C:\ps-test\scripts working directory.
- Build the Secure Preview Gateway page in index.html.
- Serve the page only on 127.0.0.1:8000.
Create the working directory
A fixed working directory keeps the page easy to find. You can create it from the fresh Windows PowerShell window you used earlier.
- Switch back to the fresh Windows PowerShell window from Step 1.
- Create the C:\ps-test\scripts directory by running this command:
New-Item -ItemType "Directory" -Path "C:\ps-test\scripts"
What does this command do?
This command creates a directory named scripts inside C:\ps-test. The terminal output confirms the new directory exists.
You will see a directory entry whose name is scripts.
- Move PowerShell into C:\ps-test\scripts by running this command:
Set-Location -Path "C:\ps-test\scripts"
Why change the location?
PowerShell uses the current directory when Python looks for files to serve. Moving here makes index.html the page at the local origin.
Your PowerShell prompt now ends with C:\ps-test\scripts.
Directory command failed?
Check that the path uses backslashes. Confirm that you are running the command in Windows PowerShell.
If the directory already exists from an earlier attempt, continue with the location command.
Help me troubleshoot the PowerShell directory commands.
Build the gateway status page
An HTML page makes the origin visible when requests reach it. You will assemble the page in Windows Notepad using six short sections.
- Press the Windows key to open search.
- Type Windows Notepad and press Enter to open it.
- Paste the document foundation into the blank Notepad file by copying this section:
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Preview Gateway</title>
<style>
:root {
color-scheme: dark;
font-family: "Segoe UI", sans-serif;
background: #08111f;
color: #e5eefc;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at top left, #14315a 0, transparent 38%),
#08111f;
}
What does this section do?
- The document metadata gives the browser a page title plus mobile-friendly sizing.
- The :root selector establishes the dark colour palette plus the page font.
- The body selector centres the page content against a layered background.
- Place the content panel styles immediately below the first section by copying this code:
main {
width: min(760px, 100%);
padding: 32px;
border: 1px solid #29496f;
border-radius: 20px;
background: rgba(11, 26, 46, 0.92);
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
}
.eyebrow {
margin: 0 0 8px;
color: #77b8ff;
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(2rem, 6vw, 3.5rem);
}
.intro {
max-width: 60ch;
color: #b8c9df;
line-height: 1.7;
}
How is the content framed?
- The main selector creates the rounded central panel.
- The .eyebrow selector styles the small label above the title.
- The heading plus introduction styles create a clear visual hierarchy.
- Save the file as C:\ps-test\scripts\index.html using Notepad's save controls.
You will see index.html in Notepad's title area. This confirms the page now exists in the working directory.
- Add the route card styles at the end of index.html by copying this section:
.route {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
gap: 16px;
margin-top: 28px;
}
.card {
padding: 20px;
border-radius: 14px;
background: #0f223b;
}
.label {
margin: 0 0 8px;
color: #8ca4c1;
font-size: 0.85rem;
}
.value {
margin: 0;
font-weight: 700;
overflow-wrap: anywhere;
}
What do the route styles control?
- The .route selector arranges the gateway stages in a responsive grid.
- The .card selector gives each stage its own panel.
- The label plus value styles separate each stage name from its details.
- Add the response status styles below the route card styles by copying this section:
.status {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 24px;
padding: 9px 12px;
border-radius: 999px;
background: #103b31;
color: #7ce2bc;
font-weight: 700;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #45d69d;
box-shadow: 0 0 16px #45d69d;
}
</style>
</head>
How does the status appear?
- The .status selector creates a green response badge.
- The .dot selector adds a glowing indicator inside the badge.
- The final two lines close the page styles plus the document head.
- Save your latest changes to index.html using Notepad's save controls.
Notepad now shows the saved file without an unsaved-change marker. Your complete visual design is stored in index.html.
- Add the page heading plus gateway route below </head> by copying this section:
<body>
<main>
<p class="eyebrow">Development ingress demo</p>
<h1>Secure Preview Gateway</h1>
<p class="intro">
This page begins as a loopback-only origin. A temporary Cloudflare Quick
Tunnel can place an HTTPS gateway in front without turning this test
server into production hosting.
</p>
<section class="route" aria-label="Gateway route">
<article class="card">
<p class="label">Origin</p>
<p class="value">127.0.0.1:8000</p>
</article>
<article class="card">
<p class="label">Gateway</p>
<p class="value">Temporary HTTPS URL</p>
</article>
<article class="card">
<p class="label">Traffic path</p>
<p class="value">Browser to edge to tunnel to origin</p>
</article>
</section>
What does the route show?
- The heading identifies the page as the Secure Preview Gateway.
- The route cards name the origin plus the temporary gateway.
- The Gateway route accessibility label describes the card group for assistive technology.
- Finish the page below the route section by copying this final section:
<div class="status">
<span class="dot" aria-hidden="true"></span>
Origin page is responding
</div>
</main>
</body>
</html>
How does the page finish?
The status badge gives you a visible success signal when the page renders. The final tags close the central panel plus the HTML document.
- Save the completed index.html file using Notepad's save controls.
Your saved file now contains the heading plus three route cards. It also contains the green origin response badge.
Seeing the wrong file extension?
Use Notepad's save controls again. Confirm the file name ends with .html.
Keep the file inside C:\ps-test\scripts so the Python server can find it.
Help me fix the saved HTML file.
✔️ Awesome, I've got everything!
Great. Confirm that your latest changes are saved in C:\ps-test\scripts\index.html.
ⓧ I'd like to double check the full code
Compare your index.html file with this complete version.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Preview Gateway</title>
<style>
:root {
color-scheme: dark;
font-family: "Segoe UI", sans-serif;
background: #08111f;
color: #e5eefc;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at top left, #14315a 0, transparent 38%),
#08111f;
}
main {
width: min(760px, 100%);
padding: 32px;
border: 1px solid #29496f;
border-radius: 20px;
background: rgba(11, 26, 46, 0.92);
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
}
.eyebrow {
margin: 0 0 8px;
color: #77b8ff;
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(2rem, 6vw, 3.5rem);
}
.intro {
max-width: 60ch;
color: #b8c9df;
line-height: 1.7;
}
.route {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
gap: 16px;
margin-top: 28px;
}
.card {
padding: 20px;
border-radius: 14px;
background: #0f223b;
}
.label {
margin: 0 0 8px;
color: #8ca4c1;
font-size: 0.85rem;
}
.value {
margin: 0;
font-weight: 700;
overflow-wrap: anywhere;
}
.status {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 24px;
padding: 9px 12px;
border-radius: 999px;
background: #103b31;
color: #7ce2bc;
font-weight: 700;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #45d69d;
box-shadow: 0 0 16px #45d69d;
}
</style>
</head>
<body>
<main>
<p class="eyebrow">Development ingress demo</p>
<h1>Secure Preview Gateway</h1>
<p class="intro">
This page begins as a loopback-only origin. A temporary Cloudflare Quick
Tunnel can place an HTTPS gateway in front without turning this test
server into production hosting.
</p>
<section class="route" aria-label="Gateway route">
<article class="card">
<p class="label">Origin</p>
<p class="value">127.0.0.1:8000</p>
</article>
<article class="card">
<p class="label">Gateway</p>
<p class="value">Temporary HTTPS URL</p>
</article>
<article class="card">
<p class="label">Traffic path</p>
<p class="value">Browser to edge to tunnel to origin</p>
</article>
</section>
<div class="status">
<span class="dot" aria-hidden="true"></span>
Origin page is responding
</div>
</main>
</body>
</html>
Serve the page on loopback
The page needs a local HTTP server before a browser can request it. Binding that server to 127.0.0.1 keeps the origin on your computer.
Before you run the server, predict which network address it will listen on.
- Switch back to the Windows PowerShell window in C:\ps-test\scripts.
- Start the loopback-only server by running this command:
python -m http.server --bind 127.0.0.1
What does this command do?
- The http.server module serves files from C:\ps-test\scripts.
- The bind value limits the listener to 127.0.0.1.
- The server uses port 8000 for this preview.
PowerShell stays busy while the server runs. Leave this window open so it can continue serving the page.
- Press the Windows key to open search.
- Type Microsoft Edge and press Enter to open it.
- Select the browser address bar.
- Enter http://localhost:8000.
- Press Enter to load the local origin.
You will see the Secure Preview Gateway page in Microsoft Edge. The page shows three route cards plus a green origin response badge.
You made the origin live. It now responds at http://localhost:8000 while listening only on 127.0.0.1:8000.
Page not loading?
Confirm the PowerShell window is still running the Python server. Check that index.html is saved inside C:\ps-test\scripts.
Use the http://localhost:8000 address exactly. A different protocol tests a capability this local server has not configured.
Help me debug the local preview server.
Your local origin is healthy. Next, you will test the HTTPS capability that this development server currently lacks.
Hit the Missing HTTPS Barrier
Your Secure Preview Gateway page now loads from an origin server bound to the loopback address. That local success gives you a healthy baseline for this test.
A page loading over HTTP does not establish whether the same endpoint can negotiate HTTPS. This step compares both paths in Microsoft Edge without changing your origin.
In this step, get ready to:
- Confirm the local HTTP origin remains healthy.
- Test the same local endpoint through HTTPS.
- Compare the HTTPS failure with the working HTTP page.
Confirm the local HTTP origin
The working HTTP page is your control result. Confirming it first ensures that any difference in the HTTPS test comes from the connection method.
- Switch back to the Microsoft Edge tab from earlier.
- Refresh the page at http://localhost:8000.
Good. You will see the Secure Preview Gateway page render with the status message Origin page is responding.
Test the HTTPS address
HTTPS asks the endpoint to negotiate TLS before the browser requests the page. Testing the same port isolates whether your local server supports that negotiation.
Before you try it, do you expect the same local service to negotiate HTTPS?
- Select the address bar in Microsoft Edge.
- Enter https://localhost:8000.
- Press Enter.
You will see a connection or protocol failure instead of the Secure Preview Gateway page. This failure is the intended result.
- Leave the browser failure in place without bypassing it.
What did this prove?
TLS termination is the point where an endpoint accepts an encrypted HTTPS connection. Your Python development server serves plain HTTP on the loopback address.
Changing the address scheme does not add TLS configuration. The failed page exposes the missing secure entry point that the gateway needs to provide.
Recheck the healthy HTTP origin
The failed HTTPS request should leave the HTTP origin untouched. Rechecking the original address separates origin health from HTTPS capability.
Before you switch back, do you expect the HTTP page to remain available?
- Return to the Microsoft Edge tab showing http://localhost:8000.
- Refresh the HTTP page.
You will see the Secure Preview Gateway page render again. You have now isolated the missing HTTPS boundary.
- Switch back to the PowerShell window from earlier.
- Leave the Python HTTP server running.
The PowerShell window remains occupied by the server process. Your origin is still healthy on 127.0.0.1:8000.
Does the HTTP page no longer load?
- Switch back to the PowerShell window from earlier.
- Confirm that the Python server process is still running.
- Repeat the server launch from Step 2 if the process has stopped.
Ask for help diagnosing the local server if the page remains unavailable.
✔️ Awesome, I've got everything!
Your HTTP origin still works. The HTTPS test failed without changing index.html.
ⓧ I'd like to double check the full code
The protocol test leaves C:\ps-test\scripts\index.html unchanged. The file still matches this reference.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Preview Gateway</title>
<style>
:root {
color-scheme: dark;
font-family: "Segoe UI", sans-serif;
background: #08111f;
color: #e5eefc;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at top left, #14315a 0, transparent 38%),
#08111f;
}
main {
width: min(760px, 100%);
padding: 32px;
border: 1px solid #29496f;
border-radius: 20px;
background: rgba(11, 26, 46, 0.92);
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
}
.eyebrow {
margin: 0 0 8px;
color: #77b8ff;
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(2rem, 6vw, 3.5rem);
}
.intro {
max-width: 60ch;
color: #b8c9df;
line-height: 1.7;
}
.route {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
gap: 16px;
margin-top: 28px;
}
.card {
padding: 20px;
border-radius: 14px;
background: #0f223b;
}
.label {
margin: 0 0 8px;
color: #8ca4c1;
font-size: 0.85rem;
}
.value {
margin: 0;
font-weight: 700;
overflow-wrap: anywhere;
}
.status {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 24px;
padding: 9px 12px;
border-radius: 999px;
background: #103b31;
color: #7ce2bc;
font-weight: 700;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #45d69d;
box-shadow: 0 0 16px #45d69d;
}
</style>
</head>
<body>
<main>
<p class="eyebrow">Development ingress demo</p>
<h1>Secure Preview Gateway</h1>
<p class="intro">
This page begins as a loopback-only origin. A temporary Cloudflare Quick
Tunnel can place an HTTPS gateway in front without turning this test
server into production hosting.
</p>
<section class="route" aria-label="Gateway route">
<article class="card">
<p class="label">Origin</p>
<p class="value">127.0.0.1:8000</p>
</article>
<article class="card">
<p class="label">Gateway</p>
<p class="value">Temporary HTTPS URL</p>
</article>
<article class="card">
<p class="label">Traffic path</p>
<p class="value">Browser to edge to tunnel to origin</p>
</article>
</section>
<div class="status">
<span class="dot" aria-hidden="true"></span>
Origin page is responding
</div>
</main>
</body>
</html>
Why is the file unchanged?
This step tests connection behavior without editing the page. The different browser results come from the address scheme that reaches the origin.
Your local origin remains healthy. Next, you will place a temporary HTTPS gateway in front of it.
Put Cloudflare Quick Tunnels in Front
Your loopback-only origin server made it through the previous check. The failed browser test showed that the Python server has no configured HTTPS endpoint.
Cloudflare Quick Tunnels adds the temporary public HTTPS entry point you need. Its ingress gateway forwards requests to 127.0.0.1:8000 while your origin stays local.
In this step, get ready to:
- Launch cloudflared in a second PowerShell window while the local server stays active.
- Open the generated trycloudflare.com URL in Microsoft Edge.
- Compare the local HTTP route with the temporary HTTPS gateway route.
Start the tunnel in a second PowerShell window
The Python server already holds the first PowerShell window. The cloudflared process needs a separate foreground window so both services can keep running.
- Press the Windows key to open the search bar.
- Type PowerShell into the search bar.
- Press Enter to open a second PowerShell window.
- Leave the first PowerShell window running the Python server.
Before you start the tunnel, what kind of address do you expect cloudflared to generate?
- Connect the tunnel client to the local origin by running this command in the second PowerShell window:
cloudflared tunnel --url http://localhost:8000
How does this command create the gateway?
- The cloudflared command starts the tunnel client on your computer.
- The tunnel argument selects tunnel mode.
- The --url argument points the tunnel at your local origin.
- The running process keeps the temporary public address connected to the Python server.
- Leave the second PowerShell window open so the tunnel stays active.
- Find the generated trycloudflare.com URL in the output.
- Copy the generated URL.
- Paste the copied address here: your temporary HTTPS URL.
You should now have a randomly generated HTTPS address ending in trycloudflare.com. The active command is carrying traffic from that address to your local origin.
No Temporary URL in the Output?
- Confirm the first PowerShell window is still running the Python server.
- Check that the second PowerShell window contains the command exactly as shown.
- Wait until the tunnel startup messages finish printing.
Help me diagnose why the temporary tunnel URL is missing.
Open the HTTPS gateway in Microsoft Edge
The generated address is the gateway's public entry point. Microsoft Edge sends an HTTPS request there before the tunnel relays it to the local HTTP origin.
- Switch back to Microsoft Edge from earlier.
- Select the address bar.
- Paste your temporary HTTPS URL into the address bar.
- Press Enter to load the gateway page.
There it is. Your Secure Preview Gateway page now loads through the temporary HTTPS address.
Gateway Page Not Loading?
- Confirm the first PowerShell window still shows the Python server running.
- Confirm the second PowerShell window remains open with the tunnel running.
- Paste your temporary HTTPS URL into Microsoft Edge again.
Help me troubleshoot the gateway page.
Compare the two traffic paths
The local address and the public address lead to the same page. Each address enters through a different boundary.
Before you compare the tabs, do you expect the page content to differ between the local route and the gateway route?
- Return to the Microsoft Edge tab from earlier that uses http://localhost:8000.
- Confirm the local tab displays the Secure Preview Gateway page.
- Switch to the tab that uses your temporary HTTPS URL.
- Confirm the gateway tab displays the Secure Preview Gateway page.
- Compare the address shown in each tab.
Both tabs display the same Secure Preview Gateway page from index.html. The local route reaches the origin directly.
The temporary route reaches the page through the public HTTPS gateway. Your Python server remains bound to 127.0.0.1:8000.
Your local origin remains on loopback behind a working temporary HTTPS gateway. Next, you'll trace a public request into the Python server logs.
Prove the Gateway Is the Traffic Path
The temporary Cloudflare Quick Tunnel now carries browser requests from its public HTTPS URL to your local page.
A page loading once does not identify which component carried its request. This step traces one request into the origin server.
A stop-and-restart test identifies the tunnel as the traffic path.
In this step, get ready to:
- Trace a public gateway refresh in the Python server output.
- Test the tunnel boundary by stopping its process.
- Restore the gateway through a newly generated URL.
Trace the request into the origin
The public page and the local server log give you two views of the same request. Matching them shows that traffic reaches the origin after passing through the gateway.
- Return to the original generated HTTPS URL in Microsoft Edge.
Before you refresh the page, where do you expect the request to appear?
- Refresh the original generated HTTPS URL in Microsoft Edge.
- Switch back to the first PowerShell window from earlier.
You will see a new request entry in the Python server output. That entry proves the public refresh reached the local origin.
What does the request entry prove?
Microsoft Edge sends the refresh through the generated public URL.
The Python server records the downstream request. The matching activity connects the public page to the local origin.
Remove the tunnel from the path
A controlled boundary test isolates the tunnel process. You can compare the public route with the local origin while the page remains unchanged.
- Switch back to the second PowerShell window from earlier.
- Press Ctrl+C to stop the running cloudflared process.
Before you refresh the public link, do you think it can still reach the origin?
- Refresh the original generated HTTPS URL in Microsoft Edge.
The Secure Preview Gateway page no longer loads through that URL. This failure is intentional.
Now predict whether the local origin still responds without the tunnel.
- Return to the Microsoft Edge tab using http://localhost:8000.
- Refresh the local page.
The Secure Preview Gateway page still renders through local HTTP. The origin remains healthy.
Why This Failure Matters
Stopping cloudflared removes the public route. The old HTTPS URL can no longer deliver requests to your computer.
Local HTTP continues to work because the Python server remains active. This comparison isolates the tunnel as the missing connection.
Restore the gateway with a new URL
Restarting the tunnel rebuilds the public route to the same local origin. The new process generates a different temporary URL.
- Restore the temporary gateway from the second PowerShell window by running this command:
cloudflared tunnel --url http://localhost:8000
What Does This Command Do?
- The cloudflared command starts a new tunnel process.
- The http://localhost:8000 value keeps the tunnel pointed at the loopback-only origin.
- Wait for the second PowerShell window to print a new generated trycloudflare.com URL.
- Record the generated URL here: your new trycloudflare.com URL.
Before you open the new link, do you think the restored gateway can reach the same origin?
- Switch back to Microsoft Edge from earlier.
- Open a new browser tab.
- Paste your new trycloudflare.com URL into the address bar.
- Press Enter.
You will see the unchanged Secure Preview Gateway page through the new HTTPS URL. The public gateway path is restored.
- Switch back to the first PowerShell window from earlier.
- Check the latest server output for the request from the new gateway URL.
You will see another request entry in the Python server output. The restarted tunnel now carries traffic from its new public URL to the same origin.
New HTTPS Link Not Loading?
- Confirm the Python server remains active in the first PowerShell window.
- Confirm the second PowerShell window remains occupied by the running tunnel process.
- Copy the newest generated URL from the second window.
Help me diagnose the restored Quick Tunnel path.
You have the proof now. The public request reaches the Python log while the tunnel connects the browser to the loopback origin.
The traffic test changed the running tunnel process. Your index.html file remains unchanged.
✔️ Awesome, I've got everything!
Your local HTTP page still works. Your restarted tunnel serves the same page through a new temporary HTTPS URL.
ⓧ I'd like to double check the full code
Your unchanged index.html file should match this complete version.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Secure Preview Gateway</title>
<style>
:root {
color-scheme: dark;
font-family: "Segoe UI", sans-serif;
background: #08111f;
color: #e5eefc;
}
* {
box-sizing: border-box;
}
body {
min-height: 100vh;
margin: 0;
display: grid;
place-items: center;
padding: 24px;
background:
radial-gradient(circle at top left, #14315a 0, transparent 38%),
#08111f;
}
main {
width: min(760px, 100%);
padding: 32px;
border: 1px solid #29496f;
border-radius: 20px;
background: rgba(11, 26, 46, 0.92);
box-shadow: 0 24px 70px rgba(0, 0, 0, 0.35);
}
.eyebrow {
margin: 0 0 8px;
color: #77b8ff;
font-size: 0.8rem;
font-weight: 700;
letter-spacing: 0.12em;
text-transform: uppercase;
}
h1 {
margin: 0;
font-size: clamp(2rem, 6vw, 3.5rem);
}
.intro {
max-width: 60ch;
color: #b8c9df;
line-height: 1.7;
}
.route {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
gap: 16px;
margin-top: 28px;
}
.card {
padding: 20px;
border-radius: 14px;
background: #0f223b;
}
.label {
margin: 0 0 8px;
color: #8ca4c1;
font-size: 0.85rem;
}
.value {
margin: 0;
font-weight: 700;
overflow-wrap: anywhere;
}
.status {
display: inline-flex;
align-items: center;
gap: 8px;
margin-top: 24px;
padding: 9px 12px;
border-radius: 999px;
background: #103b31;
color: #7ce2bc;
font-weight: 700;
}
.dot {
width: 10px;
height: 10px;
border-radius: 50%;
background: #45d69d;
box-shadow: 0 0 16px #45d69d;
}
</style>
</head>
<body>
<main>
<p class="eyebrow">Development ingress demo</p>
<h1>Secure Preview Gateway</h1>
<p class="intro">
This page begins as a loopback-only origin. A temporary Cloudflare Quick
Tunnel can place an HTTPS gateway in front without turning this test
server into production hosting.
</p>
<section class="route" aria-label="Gateway route">
<article class="card">
<p class="label">Origin</p>
<p class="value">127.0.0.1:8000</p>
</article>
<article class="card">
<p class="label">Gateway</p>
<p class="value">Temporary HTTPS URL</p>
</article>
<article class="card">
<p class="label">Traffic path</p>
<p class="value">Browser to edge to tunnel to origin</p>
</article>
</section>
<div class="status">
<span class="dot" aria-hidden="true"></span>
Origin page is responding
</div>
</main>
</body>
</html>
Secret mission
Route Your In-Progress App
Your demo proved the gateway path with a static page. Now point that same temporary HTTPS gateway at an app you are actively building, test one real action, then close the public route.
Clean Up Your Resources
Clean Up Your Resources
Your Cloudflare Quick Tunnel is already stopped. Its temporary URL no longer needs cleanup. This project has no ongoing cloud costs.
Your remaining choice is to keep the demo files, pause the development server, or remove the local demo entirely.
Resources you used:
- The local demo folder at C:\ps-test\scripts, including index.html.
- The development-server process for your in-progress app.
Keep everything running
No action is needed. Choose this if you are still developing your app or want to reuse the gateway demo.
- Keep C:\ps-test\scripts\index.html as a reusable gateway test page.
- Leave your in-progress app development server running while you are actively working on it.
- Reuse the installed tools whenever you need another temporary development preview.
Pause - I'll come back to this later
Pausing frees the local port while preserving your demo file. The stopped tunnel stays inactive.
- Switch back to the PowerShell window running your in-progress app.
- Press Ctrl+C in that window to stop the development server.
- Confirm the PowerShell prompt returns.
- Keep C:\ps-test\scripts\index.html for your next gateway test.
Delete - I don't want to use this again
Remove the gateway demo folder after stopping the remaining development server. Your in-progress app files stay untouched.
- Switch back to the PowerShell window running your in-progress app.
- Press Ctrl+C in that window to stop the development server.
- Confirm the PowerShell prompt returns.
- Press the Windows key to open the search bar.
- Type File Explorer into the search bar.
- Press Enter to open File Explorer.
- Enter C:\ps-test in the address bar.
- Select the scripts folder.
Permanent deletion skips the Recycle Bin. Windows may ask you to confirm the removal.
- Press Shift+Delete to remove the selected folder permanently.
- Confirm the permanent deletion if Windows asks.
- Return to C:\ps-test in File Explorer.
- Confirm the scripts folder is no longer listed.
Nice Work!
Nice Work!
You did it! You built a temporary HTTPS gateway for a loopback-only origin server with Cloudflare Quick Tunnels.
You've learned how to:
- Bind a visible local origin to 127.0.0.1:8000 through loopback binding.
- Recognize the missing TLS endpoint through a failed local HTTPS check. Add a temporary public gateway that displays the same page securely.
- Trace the gateway traffic path from the public URL into the Python server log. Prove the tunnel boundary with a stop-and-restart test that produces a new URL.
- Secret Mission: Route your in-progress app through a temporary HTTPS link. Test one real app action before stopping the tunnel.
Ready to quiz yourself?