Dev Tunnels integration
이 콘텐츠는 아직 번역되지 않았습니다.
Dev tunnels allow developers to securely share local web services across the internet. Enabling you to connect your local development environment with cloud services, share work in progress with colleagues or aid in building webhooks. Dev tunnels is for adhoc testing and development, not for production workloads.
Dev tunnels are useful for:
- Sharing a running local service (for example, a Web API) with teammates, mobile devices, or webhooks
- Testing incoming callbacks from external SaaS systems (GitHub / Stripe / etc.) without deploying
- Sharing a running local service (for example, a Web API) with teammates, mobile devices, or webhooks.
- Testing incoming callbacks from external SaaS systems (GitHub / Stripe / etc.) without deploying.
- Quickly publishing a temporary, TLS-terminated endpoint during development.
Prerequisites
Section titled “Prerequisites”Before you create a dev tunnel, you first need to download and install the devtunnel CLI (Command Line Interface) tool that corresponds to your operating system. See the devtunnel CLI installation documentation for more details.
Hosting integration
Section titled “Hosting integration”To get started with the Dev Tunnels integration, install the 📦 Aspire.Hosting.DevTunnels NuGet package in the AppHost project:
aspire add devtunnelsThis updates your aspire.config.json with the Dev Tunnels hosting integration package:
{ "packages": { "Aspire.Hosting.DevTunnels": "13.6.0" }}aspire add devtunnelsAspire CLI는 대화형입니다. 프롬프트 시 알맞은 검색 결과 선택:
Select an integration to add:
> devtunnels (Aspire.Hosting.DevTunnels)> Other results listed as selectable options...#:package Aspire.Hosting.DevTunnels@*<PackageReference Include="Aspire.Hosting.DevTunnels" Version="*" />Add a dev tunnel resource
Section titled “Add a dev tunnel resource”In the AppHost project, add a dev tunnel and configure it to expose specific resources:
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const web = await builder.addNodeApp("web", "../web", "index.js");
const tunnel = await builder.addDevTunnel("my-tunnel") .withReference(web);var builder = DistributedApplication.CreateBuilder(args);
var web = builder.AddProject<Projects.Web>("web");
var tunnel = builder.AddDevTunnel("my-tunnel") .WithReference(web);When you run the AppHost, the dev tunnel is created to expose the web application endpoints publicly. The tunnel URLs are shown in the Aspire dashboard. By default, the tunnel requires authentication and is available only to the user who created it.
Allow anonymous access
Section titled “Allow anonymous access”To allow anonymous, public access to the entire tunnel, chain a call to the WithAnonymousAccess method:
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const web = await builder.addNodeApp("web", "../web", "index.js");
const tunnel = await builder.addDevTunnel("public-api") .withReference(web) .withAnonymousAccess();var builder = DistributedApplication.CreateBuilder(args);
var web = builder.AddProject<Projects.Web>("web");
var tunnel = builder.AddDevTunnel("public-api") .WithReference(web) .WithAnonymousAccess();Configure dev tunnel options
Section titled “Configure dev tunnel options”To configure other options for the dev tunnel, provide the DevTunnelOptions to the AddDevTunnel method:
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const web = await builder.addNodeApp("web", "../web", "index.js");
const tunnel = await builder.addDevTunnel("qa", "my-tunnel-id", false, "QA environment tunnel", ["qa", "testing"]) .withReference(web);var builder = DistributedApplication.CreateBuilder(args);
var web = builder.AddProject<Projects.Web>("web");
var options = new DevTunnelOptions{ Description = "QA environment tunnel", Labels = ["qa", "testing"], AllowAnonymous = false};
var tunnel = builder.AddDevTunnel("qa", tunnelId: "my-tunnel-id", options: options) .WithReference(web);Configure for mixed access
Section titled “Configure for mixed access”To allow anonymous access to specific endpoints, use the appropriate WithReference overload:
import { createBuilder } from './.aspire/modules/aspire.mjs';
const builder = await createBuilder();
const api = await builder.addNodeApp("api", "../api", "index.js");
const tunnel = await builder.addDevTunnel("mixed-access") .withReference(api, "public", { allowAnonymous: true }) .withReference(api, "admin", { allowAnonymous: false });var builder = DistributedApplication.CreateBuilder(args);
var api = builder.AddProject<Projects.Api>("api");
var tunnel = builder.AddDevTunnel("mixed-access") .WithReference(api, "public", allowAnonymous: true) .WithReference(api, "admin", allowAnonymous: false);The preceding code exposes:
- The
publicendpoint of theapiproject with anonymous access - The
publicendpoint of theapiproject with anonymous access. - The
adminendpoint of theapiproject that requires authentication.
Show tunnel URLs
Section titled “Show tunnel URLs”While the dev tunnel is running, the Aspire dashboard publishes the public tunnel URL, the inspect URL, and the local endpoint URL as highlighted properties on the tunnel port resource’s property pane so they’re discoverable at a glance.
You can also select the highlighted Show tunnel URLs command from the tunnel port resource’s command menu in the dashboard. This opens a message box listing:
- Tunnel URL — the public dev tunnel URL for the port
- Inspect URL — the Dev Tunnels inspection URL for viewing tunneled HTTP traffic
- Local endpoint URL — the local address the tunnel forwards to, once allocated
Service discovery integration
Section titled “Service discovery integration”When another resource references a dev tunnel, environment variables are injected using the Aspire service discovery configuration format:
WEB_HTTPS=https://myweb-1234.westeurope.devtunnels.ms/services__web__https__0=https://myweb-1234.westeurope.devtunnels.ms/This lets downstream resources use the tunneled address exactly like any other Aspire service discovery entry.
Configuration
Section titled “Configuration”Use the following properties to configure you dev tunnels:
Dev tunnel options
Section titled “Dev tunnel options”The DevTunnelOptions class provides several configuration options:
| Property | Description |
|---|---|
Description | A description for the tunnel that appears in the dev tunnels service |
Labels | A list of labels to apply to the tunnel for organization and filtering |
AllowAnonymous | Whether to allow anonymous access to the entire tunnel |
Region | The DevTunnelRegion to create the tunnel in; automatic when unset |
Dev tunnel port options
Section titled “Dev tunnel port options”The DevTunnelPortOptions class provides configuration for individual tunnel ports:
| Property | Description |
|---|---|
Protocol | The protocol to use (http, https, or auto). If not specified, uses the endpoint’s scheme |
Description | A description for this specific port |
Labels | Labels to apply to this port |
AllowAnonymous | Whether to allow anonymous access to this specific port |
Security recommendations
Section titled “Security recommendations”- Prefer authenticated tunnels during normal development
- Only enable anonymous access for endpoints that are safe to expose publicly
- Treat public tunnel URLs as temporary & untrusted (rate limit / validate input server-side)
Tunnel lifecycle
Section titled “Tunnel lifecycle”Dev tunnels automatically:
- Install the devtunnel CLI if not already available
- Ensure the user is logged in to the dev tunnels service
- Create and manage tunnel lifecycle
- Clean up unmodeled ports from previous runs
- Install the devtunnel CLI if not already available.
- Ensure the user is logged in to the dev tunnels service.
- Create and manage tunnel lifecycle.
- Clean up unmodeled ports from previous runs.
- Provide detailed logging and diagnostics.
Tunnels will expire after not being hosted for 30 days by default, so they won’t be forcibly deleted when the resource or AppHost is stopped.
Troubleshooting
Section titled “Troubleshooting”Authentication required
Section titled “Authentication required”If you see authentication errors, ensure you’re logged in to the dev tunnels service:
devtunnel user loginPort conflicts
Section titled “Port conflicts”If you encounter port binding issues, check that no other processes are using the same ports, or configure different ports for your endpoints.
Tunnel not accessible
Section titled “Tunnel not accessible”Verify that:
- The tunnel is running and healthy in the Aspire dashboard
- You’re using the correct tunnel URL
- Anonymous access is configured correctly if accessing without authentication
Dashboard doesn’t show a tunnel URL
Section titled “Dashboard doesn’t show a tunnel URL”Dev tunnel endpoints stay unallocated until the integration publishes the real tunnel endpoint. The dashboard and MCP resource snapshots then show the public tunnel URL.
If you’re using Aspire 13.5 and the resource reaches the Running and Healthy states without showing a URL, update to Aspire 13.6 or later to resolve a known endpoint-publication regression.