Debugging a distributed application usually means moving between several tools.
You may start with the application dashboard, switch to a terminal to inspect a container, open another terminal for logs, and then return to the dashboard to check whether another service is failing.
.NET Aspire 13.6 improves this local development experience by adding a more capable terminal experience directly inside the Aspire Dashboard. The release includes a persistent, resizable terminal dock, detached terminal windows, and resource or AppHost-owned terminal sessions. It also adds database REPL support for several database and cache resources.
That matters because the dashboard already knows about the resources in your distributed application. Having terminal access alongside resource status, logs, metrics, and traces makes it easier to investigate a problem without constantly switching context.
This article explains how to use the capability, where it helps, and what developers should keep in mind when debugging containers.
What Changed in Aspire 13.6?
Aspire 13.6 adds a persistent terminal dock to the dashboard. The terminal can be resized, opened in tabs, or detached into its own window. The new terminal rendering system also improves copy and paste behavior and provides sizing controls.
The release also adds AppHost-owned interactive terminals, allowing an AppHost to create terminal processes that are not necessarily tied directly to a DCP-managed resource. These terminals can appear in the dashboard dock or in a separate dialog or window.
For developers, the practical difference is straightforward:
Before
Aspire Dashboard
|
+---- Logs
+---- Metrics
+---- Traces
Separate Terminal
|
+---- Container inspection
+---- Commands
+---- Database toolsWith the newer dashboard experience:
Aspire Dashboard
|
+---- Resources
+---- Logs
+---- Metrics
+---- Traces
|
+---- Terminal
|
+---- Commands
+---- Container inspection
+---- REPLThe goal is not to replace your normal terminal. It is to put runtime investigation closer to the application context.
Why Container Debugging Needs This Context
Consider a local application with several services:
Aspire
|
+---------------+---------------+
| | |
v v v
API PostgreSQL Redis
|
v
FrontendSuppose the API reports a database connection error.
You need to answer several questions:
Is PostgreSQL running?
Is the database accepting connections?
Is the API using the correct endpoint?
Is the expected database present?
Are the required environment variables available?
Is the problem inside the API or the database?
The dashboard can show resource state and telemetry.
The terminal gives you another level of inspection.
That combination is useful because you can move from:
Something is failing
|
v
Dashboard
|
v
Identify the resource
|
v
Terminal
|
v
Inspect the runtimeOpening the Terminal
Aspire 13.6 provides a terminal dock directly in the dashboard. The terminal can remain available while you move between dashboard views, and terminal sessions can also be detached into separate windows.
This is useful during a debugging session because you can keep the terminal open while checking resource logs.
For example:
+------------------------------------------------+
| Aspire Dashboard |
| |
| Resources | Logs | Traces | Metrics |
| |
|------------------------------------------------|
| Terminal |
| |
| $ pwd |
| $ ls -la |
| $ dotnet --info |
| |
+------------------------------------------------+The exact commands available depend on the resource and its environment.
Inspecting a Container
Suppose your AppHost includes a PostgreSQL resource.
A simplified AppHost might look like this:
var builder = DistributedApplication.CreateBuilder(args);
var postgres = builder
.AddPostgres("postgres")
.AddDatabase("appdb");
var api = builder
.AddProject<Projects.Api>("api")
.WithReference(postgres);
builder.Build().Run();When the application is running, Aspire understands that the API depends on PostgreSQL.
If the database behaves unexpectedly, the dashboard gives you the application-level view, while terminal access lets you inspect the runtime environment.
Depending on the resource, you may be able to run commands that inspect files, environment information, processes, or available tools.
For example:
pwdand:
ls -lacan help establish where you are and what files are available.
Checking the Runtime Environment
One of the first things to check when a container behaves differently from your local machine is the runtime environment.
For a .NET container:
dotnet --infocan show the installed .NET SDK and runtime information.
You can also inspect the operating system:
uname -aif the command is available.
The point is to replace assumptions with evidence.
Instead of assuming that the container has the runtime you expected, inspect it.
Checking Environment Variables Safely
Configuration is another common source of container problems.
You may need to determine whether a required variable exists.
For example:
if [ -n "$ASPNETCORE_ENVIRONMENT" ]; then
echo "Environment variable is configured"
else
echo "Environment variable is missing"
fiThis is safer than dumping the entire environment.
Avoid casually running:
envin an environment that contains secrets.
Environment variables may contain:
Connection strings
API keys
Access tokens
Passwords
Cloud credentials
The dashboard and terminal make investigation easier, but they do not remove the need for careful handling of sensitive information.
Debugging a Database Connection
Suppose the API cannot connect to PostgreSQL.
Start by checking whether the PostgreSQL resource is running.
Then inspect the application logs.
If the error looks like:
Connection refusedyou can investigate the database environment.
If the PostgreSQL client is available, you can check its version:
psql --versionYou can then use the appropriate connection information to test connectivity.
For example:
psql \
-h "$POSTGRES_HOST" \
-U "$POSTGRES_USER" \
-d "$POSTGRES_DB"The exact variables depend on how your application is configured.
Do not paste real passwords directly into commands or source files.
Database REPLs
Aspire 13.6 also adds opt-in REPL commands for database and cache integrations. The release includes bundled clients for PostgreSQL, MySQL, MongoDB, SQL Server, Redis, and Valkey.
This can make database troubleshooting more convenient.
For example, instead of manually finding the container and starting a client, the resource can expose an appropriate interactive database command through the Aspire development experience.
The workflow becomes:
Database Resource
|
v
Resource Command / REPL
|
v
Database Client
|
v
Inspect DataThis is particularly useful for local development and debugging.
It should not be interpreted as a reason to give developers unrestricted database access in production.
Checking Redis
A similar workflow can be used with Redis.
If the appropriate client is available, a simple health check might look like:
redis-cli pingA healthy Redis instance normally returns:
PONGYou can then inspect the data or configuration required for the development scenario.
Again, be careful with data that may contain credentials or other sensitive information.
Debugging Files Inside a Container
A common container problem is that a file exists on the developer's machine but not inside the container.
For example, the application expects:
/app/config/settings.jsonYou can inspect the directory:
ls -la /appand then:
ls -la /app/configThis can quickly reveal whether the issue is related to:
Docker build context
Volume mounts
Copy instructions
Working directory
Generated files
Configuration paths
The terminal is useful here because it shows the actual runtime filesystem rather than what exists on the host.
Host Files vs Container Files
This distinction causes many debugging mistakes.
Imagine:
Developer Machine
|
+-- C:\Projects\MyApp
|
+-- Docker
|
+-- API Container
|
+-- /appA file in:
C:\Projects\MyApp\config.jsondoes not automatically exist at:
/app/config.jsoninside the container.
Whether it exists depends on the container image and volume configuration.
The dashboard terminal gives you a direct way to inspect the resource's environment.
AppHost-Owned Terminals
Aspire 13.6 also introduces experimental AppHost-owned interactive terminals.
This is slightly different from simply opening a shell inside a resource.
The AppHost can create an interactive terminal process independently of the resources orchestrated by DCP. These terminals can be displayed in the dashboard dock, opened in a dialog, or used in headless scenarios for automation.
This can be useful when the application needs an interactive development tool that is not itself a container resource.
The architecture can look like:
AppHost
|
+---- API
+---- Database
+---- Cache
|
+---- Interactive ToolThis provides another way to integrate developer tooling into the local application experience.
Terminal Debugging vs Dashboard Observability
Terminal access does not replace the rest of the dashboard.
Each tool answers a different question.
Tool | Best Use |
|---|---|
Resources | Is the service running? |
Console Logs | What is the application reporting? |
Structured Logs | What events are being emitted? |
Traces | Where is a request spending time or failing? |
Metrics | What is happening over time? |
Terminal | What is actually present inside the runtime? |
Database REPL | What does the development database contain? |
A good debugging workflow uses them together.
For example:
API Request Fails
|
v
Trace
|
v
Database Span Looks Suspicious
|
v
PostgreSQL Resource
|
v
Terminal / REPL
|
v
Inspect DatabaseThis is much more efficient than immediately opening a terminal and guessing.
A Practical Debugging Workflow
When a container is not behaving as expected, follow a consistent process.
Step 1: Check the Resource
Confirm whether the container is running.
Step 2: Check Logs
Look for startup failures, configuration errors, and dependency failures.
Step 3: Check Traces
If the problem occurs during a request, determine where the request fails.
Step 4: Open the Terminal
Inspect the actual runtime environment.
Step 5: Verify Configuration
Check the required variables without exposing sensitive values.
Step 6: Test the Dependency
Use the appropriate client or command to verify connectivity.
Step 7: Fix the Source Configuration
If the problem is caused by the AppHost, container image, or application code, make the permanent change there.
Do not rely on an interactive terminal change.
Common Mistakes
Assuming the Host and Container Are the Same
They are different environments.
A command working on your machine does not prove that it will work inside the container.
Treating Manual Changes as Permanent
Suppose you install a package interactively:
apt-get install some-packageThe package may disappear when the container is recreated.
If the dependency is required, update the container image or development configuration.
Printing All Environment Variables
This can expose credentials.
Inspect only what you need.
Using the Terminal Instead of Observability
A shell can tell you what is happening inside a resource, but it is not a replacement for traces and metrics.
Debugging Without a Hypothesis
Do not run dozens of commands without knowing what question you are trying to answer.
Start with the failure and work toward the likely cause.
Troubleshooting Terminal Problems
Terminal Does Not Open
First confirm that the Aspire dashboard is running the expected version and that the terminal capability is available for the current resource.
If a terminal is resource-specific, verify that the selected resource supports the operation you are attempting.
A Command Is Missing
Minimal container images may not include common utilities.
Check:
which <command>when which is available.
If the command is genuinely required by the application, add it through the correct image or development configuration instead of relying on a manual installation.
Terminal Works but the Fix Disappears
That is expected if you modified the running container directly.
Move the fix into:
Dockerfile
Container configuration
AppHost
Application source
Infrastructure configuration
depending on the actual cause.
Advantages
Less Context Switching
Developers can inspect resources without constantly moving between the dashboard and separate terminal applications.
Better Runtime Visibility
The terminal provides access to the environment where the resource is actually running.
Faster Database Troubleshooting
Database and cache REPL support can simplify local inspection.
Better Development Experience
The persistent terminal dock and detached windows make interactive debugging more convenient.
Disadvantages and Limitations
Not Every Resource Behaves Like a Shell
The available commands depend on the underlying resource and environment.
Manual Changes Are Temporary
Interactive modifications are generally lost when the resource is recreated.
Security Still Matters
A terminal can expose credentials and sensitive application data.
Experimental Features Can Change
Some of the terminal APIs in Aspire 13.6 are marked experimental, so teams should account for possible API or behavior changes when adopting them.
Best Practices
Use the dashboard first to understand the system-level problem.
Use the terminal to investigate a specific resource.
Do not expose secrets while inspecting environment variables.
Treat manual container changes as temporary experiments.
Put permanent fixes into source-controlled configuration.
Use explicit runtime and dependency versions where reproducibility matters.
Use database REPLs carefully and preferably with non-production data.
Keep production credentials out of local debugging environments whenever possible.
Use traces and logs together with terminal investigation.
Document repeatable troubleshooting commands for the development team.
Final Thoughts
Aspire 13.6 makes the local debugging experience more practical by bringing interactive terminals closer to the resources developers are already monitoring in the dashboard.
The real advantage is not simply having another terminal window. It is being able to move from a resource's status, logs, traces, and metrics to direct runtime inspection without losing the context of the distributed application.
For example, if an API cannot connect to PostgreSQL, you can start with the API resource, inspect the relevant trace, check the database resource, and then use a terminal or database REPL to verify the runtime state.
That makes debugging more deliberate and reduces unnecessary context switching.
Developers should still remember that a terminal is an investigation tool. A manual change inside a running container is not a substitute for fixing the Dockerfile, AppHost configuration, application code, or infrastructure definition.
Used correctly, the combination of Aspire's dashboard and terminal capabilities provides a much more complete local development workflow for distributed .NET applications.
Join the conversation! Your thoughts help the community grow.