Upgrade Your Local Development Environment with Cloudflare
Use Cloudflare Zero Trust and Tunnels to improve your local development workflows across devices with HTTPS, easy testing of webhooks and APIs, and real-time feedback from team members and clients.
This guide shows you how to deploy your local development infrastructure in a Zero Trust environment that you can securely access from anywhere. You'll learn how to use Cloudflare Tunnels to access your local development server URL (https://localhost:1234) from a secure, public URL (https://app.example.com) provided by Cloudflare. You'll learn how to use Cloudflare Access to make all requests to your local development infrastructure pass through robust security filters so that only you or those you authorize can access your local resources.
When Localhost Over HTTP Is Not Enough
When you access localhost in your web browser, you connect directly to your local development server using the HTTP protocol by default. This design choice prioritizes ease of use since setting up HTTPS on localhost involves additional steps like obtaining and configuring a certificate. localhost over HTTP is generally considered safe because the traffic between your browser and the server running on localhost doesn't pass through external networks where it could be compromised. This risk assessment assumes that your local environment is secure from threats like eavesdropping and malware.
Consequently, when you're developing a web application on localhost (also known as 127.0.0.1), the development server can only accept connections from your machine. However, you may need to test your web application on different devices (like a smartphone or tablet) or allow others to access your development server to preview your web application.
You can configure the development server to listen on 0.0.0.0 to accept connections on all network interfaces of the host machine. Devices connected to your network can then access the development server using the server machine's local IP address, usually something like 192.168.x.x or 10.x.x.x. If your server's local IP address is 192.168.1.5, then you can access your server from another device on the same network by entering http://192.168.1.5:<PORT> in the web browser, where PORT is the port number your server is running on.
Configuring your development server to listen on all interfaces (0.0.0.0) can lead to a lack of access control. Any device on your local network can access your development server, which may be less than ideal, especially when developing sensitive or work-in-progress features. Additionally, this configuration does not grant access to the web application to devices beyond your local network, which may be necessary for testing or previewing purposes.
HTTPS is not a strict requirement for local web development because browsers treat localhost as a secure context, enabling permissions usually reserved for HTTPS. These permissions allow developers to test web features that require a secure environment, such as Service Workers or Geolocation API, on localhost without setting up HTTPS. However, treating localhost as a secure context does not apply when you expose your local server beyond your machine (such as using 0.0.0.0). You need to take additional measures to access your local web server securely across different devices. One effective solution is to use secure tunnels.
Why Use Tunnels With Your Local Environment
In computer networking, a "tunnel" refers to securely transporting data between two networks by encapsulating the data packets, which means the original data is wrapped or encased within another packet with a new header. These tunnels can encrypt traffic between devices, ensuring that the integrity and confidentiality of your data are maintained, similar to how HTTPS protects data on the public Internet.
You can use a tunnel as a secure communication path that forwards traffic from your local development environment to the public Internet. The tunnels allow you to share your local development work with others for testing, collaboration, or demonstration purposes without deploying it to a public server.
When you create a tunnel to your localhost:
-
You have a local web server running on your local machine, commonly bound to
localhostor127.0.0.1, which is not accessible from the Internet. -
You use a tunneling service that connects your local web server to a public endpoint. Common tunneling services for this purpose include Ngrok, LocalTunnel, Cloudflare Tunnel, and others.
-
The tunneling service creates a secure connection from your local web server to one of its servers on the Internet.
-
The tunneling service assigns a public URL to your tunnel. Any requests to this URL are securely forwarded through the tunnel to your local web server.
-
When someone accesses the public URL, the request goes to the tunneling service's server, which then securely forwards the request through the tunnel to your
localhostserver. -
Your local web server handles the request as it would any other and sends the response back through the tunnel to the original requester.
Tunneling services offer a significant advantage for local development by enabling developers to expose local servers to the Internet quickly and securely and have immediate access to an HTTPS environment for local development. As such, tunneling allows for easy testing of secure-context APIs and webhooks across devices, integrating with third-party APIs or services that require a secure connection, catching configuration issues and bugs that might only arise under HTTPS, and fostering real-time feedback from clients or team members without the need for a staging environment.
Tunnels bridge the gap between development and production, allowing for seamless integration and debugging of services as they operate in a live setting.
Risks Associated With Tunnels
While tunneling services offer several advantages, assessing the risk associated with their usage is essential.
Security Risks: Exposing your local development environment to the Internet can open security vulnerabilities. If the local environment is not properly secured, it could be exploited by malicious actors.
Dependence on Third-Party Services: Using a tunneling service means relying on an external provider. Any downtime or issues with the provider could directly affect your access and tunnel functionality.
Limited Control: With tunneling services, you have less network infrastructure control than a self-hosted solution. For instance, you may be limited in customization and configuration options.
Performance Considerations: The additional layer of the tunneling service can introduce latency, which may be an issue for performance-sensitive applications.
Data Privacy: Passing your data through a third-party service raises privacy concerns, primarily if sensitive data is transmitted and the service's data handling policies are unclear or fully compliant with your requirements.
Cost: While some tunneling services offer free tiers, more advanced features, and higher usage limits typically require paid subscriptions, which can be a consideration for budget-conscious projects or organizations.
Temporary URLs: Some services provide non-static URLs that change every time the tunnel is restarted, which is not ideal for some use cases where a persistent URL is necessary.
Given these factors, the decision to use tunnel services should be weighed against your project and organization's specific requirements and constraints, particularly considering security and operational consistency.
Cloudflare: Tunnels with Zero Trust Security
Cloudflare Zero Trust, a part of Cloudflare's suite of services, is designed to address many of the risks associated with traditional tunneling services:
Security Risks: Cloudflare Zero Trust, as part of its security model, minimizes risks by requiring users to authenticate, regardless of location, before accessing applications, such as local environments exposed through a tunnel. User authentication prevents unauthorized access and reduces the attack surface.
Dependence on Third-Party Services: While using Cloudflare Zero Trust still means relying on a third-party service, Cloudflare is known for its robust infrastructure and high uptime, which can significantly mitigate concerns around reliability.
Limited Control: Cloudflare Zero Trust provides a wide range of configuration options, allowing control over how the service handles traffic.
Performance Considerations: Cloudflare's global network is optimized for performance, with data centers in many locations worldwide. Its tunneling solution, Cloudflare Tunnel, benefits from this by reducing latency and improving application performance.
Data Privacy: Cloudflare has policies to protect user data, and its service complies with various regulatory frameworks. However, developers must still exercise due diligence and ensure that their organizations find it acceptable for application data to go through Cloudflare's systems.
Cost: Cloudflare Zero Trust offers different pricing tiers, including a free tier with essential features that are more than suitable for small teams or individual projects.
Temporary URLs: Cloudflare Tunnel allows for creating stable, persistent URLs that do not change between connections, overcoming the challenge of temporary URLs. Nonetheless, Cloudflare still offers the option to create a quick tunnel with a temporary URL if there's a need for it.
In summary, Cloudflare Zero Trust provides solutions addressing many common concerns with tunneling, particularly security, performance, and reliability.
Cloudflare Tunnels in Practice
Let's consider the following use case where you are actively building or maintaining multiple applications:
- Application A
- A web app that represents an internal employee dashboard.
- Runs on
http://localhost:3000.
- Application B
- A static site represents a marketing landing page.
- Runs on
http://localhost:8000
Using a tunneling service like Cloudflare Tunnel, you could choose a dedicated apex domain for general local development and map specific applications to its subdomains:
http://localhost:3000=>https://dashboard.example.comhttp://localhost:8000=>https://marketing.example.com
You can then create a single Cloudflare Tunnel to define and manage these connections. Since tunnel URLs are public, you can use Cloudflare Zero Trust to restrict access to those domains to just yourself or your team.
It would be a good idea to register a domain with Cloudflare just for local development purposes. However, you can use whatever domain you have around from other registrars by adding the domain to Cloudflare as a site.
Let's get started!
Set Up a Cloudflare Tunnel
If you are new to Cloudflare, create a free account . Otherwise, log in to your Cloudflare account to access the Cloudflare Dashboard.
Cloudflare Tunnels is a feature from Cloudflare Zero Trust. Set up that feature by clicking the "Zero Trust" tab on the sidebar.
The first step to set up Cloudflare Zero Trust is to create a team for your Cloudflare account. Your team name creates a unique domain for your Cloudflare Zero Trust account using the following pattern:
<TEAM_NAME>.cloudflareaccess.com
Enter the name that you'd like to have and click the "Next" button.
The "Choose a plan" page will open, showing different bundles that you can choose for the Cloudflare Zero Trust service. The Free bundle provides security tools to protect your applications online for up to 50 users. The free bundle is a solid choice for small steams and to test proof-of-concept (POC) or minimum viable product (MVP) applications.
Click the "Select plan" button under the Free bundle option. You'll see a page summarizing your service selection with a cost of 0/month in your local currency. Click on the "Proceed to payment " button. Select the billing account you have set up for your Cloudflare account and click the "Next" button. Confirm your billing information and click the "Purchase" button to complete the transaction.
You'll see a toast message that says "Successfully updated plan" and a welcome page with suggestions to help you get started with Cloudflare Zero Trust.
What is a Cloudflare Tunnel?
Tunnels establish a secure connection between Cloudflare's edge and your infrastructure, including the web server you use for local development on your machine. Your local web server can run as a host within your Cloudflare Zero Trust infrastructure. Tunnels allow you to securely connect to private resources, such as your local web server, without opening ports or exposing them to the Internet.
Setting up a Cloudflare tunnel consists of two essential steps:
- Install Cloudflared, a Cloudflare Tunnel client (formerly known as Argo Tunnel).
- Connect an application to your tunnel.
Create a Cloudflare tunnel
Within the "Zero Trust overview" section of the Cloudflare Dashboard, click the "Access" or "Networks" tab in the sidebar.
Under the "Access" options, click the "Tunnels" tab.
The "Tunnels" page loads. Click the "Add a tunnel" button. If you have already created a tunnel before, you'll see a "Create a tunnel" button instead.
The "Create a tunnel" page loads and asks you to name your tunnel. Enter the following values in the form that shows up:
local-development
Click the "Save tunnel" button.
Configure a Cloudflare tunnel
The "Configure <tunnel-name>" page opens with instructions on how to create a connector to connect the local environment in your operating system with your remote Cloudflare tunnel.
Locate the "Choose your environment" section and select your operating system of choice.
Open a terminal window in your machine and use the commands the page provides to connect your tunnel to Cloudflare by installing and running a connector.
One of the commands will help you install cloudflared. The other command will help you run the cloudflared service.
Note that you only need to run the command to install the service with sudo or root/admin permission if you want cloudflared client to run at boot. Otherwise, the cloudflared client will only run when the operating system user has logged in, which is a good choice for using Cloudflare Tunnels for local development.
Once you run the command, you should see a message that your system is installing the cloudflared client as a user launch agent and, eventually, that your system installed a service for cloudflared successfully.
Head back to the "Configure <tunnel-name>" page in the Cloudflare Dashboard and locate the "Connectors" section. You should see a "Connector ID" with the" Connected " status".
Click the "Next" button.
Route traffic to a Cloudflare tunnel
The "Route Traffic <tunnel-name>" page opens up. You can route traffic to a Cloudflare tunnel by adding a public hostname or a private network to the tunnel.
For local development, you'd want to connect an application that is running locally on http://localhost:<PORT> with your tunnel. You can set up a public hostname to have granular control over mapping a local web server address to a public web address from Cloudflare.
Let's revisit the use case from this guide's introduction of mapping a specific application to a subdomain:
http://localhost:3000=>https://dashboard.example.comhttp://localhost:8000=>https://marketing.example.com
Now, let's create the route traffic pattern for the "dashboard" application.
Click the "Public Hostnames" tab to load the "Add public hostname for <tunnel-name>" section.
Under the "Public hostname " subsection, select or enter the following information using its fields:
dashboard
Select an available custom domain.
Then, under the "Service" subsection, select or enter the following information using its fields:
HTTP
localhost:3000
Click the "Save tunnel" button.
The "Tunnels" page opens up. Under the "Your tunnels" section, you can see an entry representing the tunnel you created.
Use a Cloudflare Tunnel
As a quick example, Let's create a Next.js application for the dashboard. However, you can use any of your existing applications on any stack as long as you configure it to run on the local port you used to configure the route traffic of your tunnel service.
By default, Next.js applications run locally on port 3000, which matches the service URL of the local-development tunnel you created earlier: https://localhost:3000.
Create a fresh new application:
npx create-next-app@latest
Enter the following as the project name:
dashboard
Choose the default value for the rest of the options to expedite the creation process.
Make dashboard your current directory:
cd dashboard
Then, run the application by executing the following command:
npm run dev
You should see a similar output to this in the terminal:
> next dev
▲ Next.js 14.0.4
- Local: http://localhost:3000
✓ Ready in 1211ms
Visit http://localhost:3000.
You'll see the user interface and content of the default Next.js app. Now, let's see that same content on your Cloudflare Tunnel. Visit the URL you created as your tunnel's public hostname: dashboard.<your-domain>. For example: dashboard.example.com.
The content that the browser renders in your Tunnel's public hostname should match the content that the browser renders in http://localhost:3000.
Now, let's test that your tunnel's public hostname reflects any changes you make to your project's codebase.
Open the dashboard Next.js project in your text editor or IDE. Then, locate the src/app/page.tsx file and replace its content with the following code:
import styles from './page.module.css'
export default function Home() {
return (
<main className={styles.main}>
<h1>Dashboard Web App</h1>
</main>
)
}
Save your changes and notice that the content on your tunnel's public hostname reflects that change quickly. Test the tunnel connection further by making other changes in the codebase. If you place two browser windows side by side, one with http://localhost:3000 and one with your tunnel's public hostname, you'll notice that both windows update simultaneously.
There's no performance or productivity compromise by using Cloudflare Tunnels for local development. You can use a public URL to set up a development environment with any services your applications integrate, such as Auth0, Twilio, or Stripe.
Speaking of access, as it is, anyone with an internet connection can visit your Tunnel's public hostname. That's less than ideal, as you may be actively developing ideas that must stay private. Cloudflare helps you elegantly solve that problem using Cloudflare Access, which you'll learn how to set up and configure in the next section.
Use the tunnel with multiple applications
Let's revisit the multi-application use case of mapping a specific application to a subdomain:
http://localhost:3000=>https://dashboard.example.com(Done)http://localhost:8000=>https://marketing.example.com
You created the dashboard application in the previous section and connected its local web server with Cloudflare using your tunnel. In this section, let's create and set up the application for the marketing site.
Navigate to the parent of the dashboard directory or make another directory your current directory. Then, let's quickly create another Next.js app for the marketing site by running the following command:
npx create-next-app@latest
Enter the following as the project name:
marketing
Choose the default value for the rest of the options. Once the scaffolding process is complete, make marketing your current directory:
cd marketing
Open the marketing Next.js project in your text editor or IDE. Then, locate the src/app/page.tsx file and replace its content with the following code:
import styles from './page.module.css'
export default function Home() {
return (
<main className={styles.main}>
<h1>Marketing Site</h1>
</main>
)
}
Then, run the application by executing the following command:
npm run dev -- --port 8000
Visit http://localhost:8000 to open the application.
Let's update your local-development tunnel by adding another public hostname that maps to http://localhost:8000 as its service URL.
Head back to the "Tunnels" page in the Cloudflare Dashboard and click the local-development tunnel you created. On the side panel that slides out, click the "Configure" button.
Now, click the "Public Hostname" tab and then click the "Add a public hostname" button. The process is identical to what you did to create the first public hostname. Select or enter the following information using the fields:
marketing
The same domain you selected for the dashboard public hostname
HTTP
localhost:8000
Click the "Save hostname" button to complete the process.
You have now registered two public hostnames with your local-development tunnel. Visit the marketing.<YOUR_DOMAIN> URL, and you should see the same content that you have in http://localhost:8000/.
Restrict Access to Cloudflare Tunnels
Finally, integrate with Cloudflare Tunnel with Cloudflare Access to restrict who can access your local development environment through the public URL. The free plan gives you up to 50 users and access to Zero Trust Network Access.
Within the "Zero Trust overview" section of the Cloudflare Dashboard, click the "Access" in the sidebar.
Under the "Access" options, click the "Applications" tab.
The "Applications" page loads. Click the "Add an application" button.
The "Add an application" page loads where you can configure the policies, authentication, and settings of your applications.
Locate the "Self-hosted" block and click the "Select" button to choose it as the application type. A self-hosted application is an application you host in your infrastructure, such as the operating system of your local machine, that uses Cloudflare's authoritative DNS.
You need to define the route traffic pattern that this Cloudflare Access application must protect. You'll use a single Zero Trust application to protect all your local development public hostnames. Since you are mapping each local web server address to a subdomain of your chosen domain, you can define the route traffic pattern easily:
*.<YOUR_DOMAIN>
Under the "Application Configuration" section, select or enter the following information using the fields:
local-development
*
The same domain you selected for your tunnel
Ignore the warning about "No DNS record found for this domain. The policy may not execute as expected." Cloudflare created the DNS record for each subdomain you defined in your tunnel's public hostnames. You receive this warning because Cloudflare proactively checks if the value in the "Subdomain" field has already been defined for the selected domain. Cloudflare shows the warning since the subdomain has no * DNS record.
Scroll down to locate the "Identity providers " section. Notice that the "Accept all available identity providers" option is enabled. The default authentication mechanism for your Zero Trust users is the one-time PIN, where Cloudflare sends them a one-time PIN (or code) by email that they then use to log in. The process feels familiar to using your email address as a factor in multi-factor authentication.
Click the "Next" button.
Now, you can create policies that explicitly define who can access the applications you protect with this Zero Trust application based on route traffic.
The first section defines the policy name, the action to take if there's a match, and the session duration. Select or enter the following information using the fields:
local-development-access
Allow
The "Configure rules " section allows you to define conditions or rules for who can or cannot reach your application.
The "Include" subsection allows you to define a key-value pair that represents a rule. You can add as many rules as you'd like. For this use case, you'll create an allow-list of email addresses that can access your application.
Select "Emails" in the "Selector" dropdown. For its "Value", type the email address to which you want Cloudflare to send you access codes.
Click the "Next" button.
Finally, look at the "Cookie settings" section to configure enhanced cookie settings for added security.
Enable the "HTTP Only " option to prevent client-side scripts from accessing the cookie.
Enable "Enable Binding Cookie" to protect your application against stolen authorization tokens. You can safely use this option if your web applications don't rely on protocols other than HTTP, such as SSH and RDP.
Finally, scroll down and click the "Add application" button.
The "Applications" page loads and shows your new local-development application under the "Your applications " table.
Test your Cloudflare Zero Trust application
Open a browser incognito or private window and visit the marketing.<your-domain> application. You shouldn't see the application's content this time around. All you see is a Cloudflare Access page with a form asking you to enter an email address to get a login code to proceed.
Enter the email address you defined in the access rule and click the "Send me a code" button.
The form will show a message that says, "A code has been emailed to you." Check your inbox and look for an email with a subject similar to "Login code..." from Cloudflare. Copy the code from the email, paste it into the Cloudflare Access form, and click the "Sign in " button.
You should now see the content of the application. Make more changes in the marketing application codebase to see the content update on your tunnel's public hostname.
The page should quickly update! For testing, visit the dashboard.<your-domain> application on that same browser incognito or private session. You should see the dashboard application content as you have already logged in to the Zero Trust application that protects both local apps.
However, if you use another browser to open an incognito or private window and try to visit the dashboard.<your-domain> application, Cloudflare will ask you to log in.
Using the Cloudflare Access application rules, you explicitly authorize who can access your local development application to a selected group. Everyone else on the web can't see it.
If you stop an application from running locally and refresh the page, you'll see a "Bad gateway Error" error page with code 502. The browser and Cloudflare are working, but the host, which is the local web server you use to run your application locally, is down.
Next Steps: Do More With Cloudflare Zero Trust
You have just scratched the surface of the comprehensive feature set that Cloudflare Zero Trust offers. Here are some immediate steps you can take to enhance your current setup:
- If different subdomains require different levels of access control (for example, only certain team members should access certain services), you may need to set up multiple Access applications with more granular policies instead of a single wildcard application.
- Create Access groups to reuse existing rules or create new ones. You can add as many include, exception, or require statements as needed.
- Experiment with integrating with an identity provider to apply Zero Trust policies and provide access. You can integrate a Google Workspace account with Cloudflare Access to quickly sign in without waiting for the one-time PIN to arrive by email.