Porthole supports isolated container environments through sessions. A session is a separate namespace managed by the WSL Containers runtime that groups containers, images, and volumes together.
Each session can have its own:
Named sessions are created explicitly by the user with a custom name. They are the most common type of session in Porthole.
Characteristics:
%LOCALAPPDATA%\Porthole\Sessions\<SessionName>Session class)--session <name> parameter: wslc --session myapp listExample:
# List containers in a named session
wslc --session myapp container list
# Run a container in a named session
wslc --session myapp container create --image nginx:latest --name web
The (Default) session represents the unnamed default WSL Containers session managed by the WSL runtime.
Characteristics:
(Default))--session parameter: wslc list (not wslc --session Default list)wslc before Porthole was installed(default) in the UI to indicate WSL-managed storageWhen it appears:
stirling-pdf container running from a previous wslc session, and Porthole detects it on first runCommands in the (Default) session:
# List containers in the default unnamed session
wslc container list
# Run a container in the default session
wslc container run --image nginx:latest
# Stop a container in the default session
wslc container stop <container-name>
# Note: No --session parameter is used
Use the Sessions page in Porthole to create a new named session. The UI will:
The active session determines which session receives all container, image, and volume operations.
Switching behavior:
How to switch:
For faster day-to-day switching, you can use the tray flyout without opening the full dashboard.
How to open:
What you can do:

Deleting a session removes:
Constraints:
(Default) session (it’s managed by WSL and may have system-managed containers)When Porthole starts for the first time (or when the session registry is missing), it discovers available sessions using this priority:
Example scenarios:
| Existing Sessions | Active Session (First Run) |
|---|---|
(Default) with stirling container only |
(Default) |
Porthole, porthole-devcontainers |
Porthole (first alphabetically) |
(Default), Porthole, porthole-devcontainers |
Porthole (other named sessions preferred) |
| None | porthole-devcontainers (created on demand) |
Session information is persisted to a JSON file at:
%LOCALAPPDATA%\Porthole\sessions.json
Registry content:
{
"activeSessionName": "(Default)",
"knownSessionNames": ["(Default)", "Porthole", "porthole-devcontainers"]
}
What’s persisted:
Container state for each session is managed by the WSL Containers SDK:
%LOCALAPPDATA%\Porthole\Sessions\<SessionName>UnnamedDefaultSessionName = "(Default)" — representation of the unnamed default sessionDefaultActiveSessionName = "porthole-devcontainers" — fallback default if no other session existsDetecting the (Default) session:
// On first run or registry reset, check for existing containers in default session
bool HasDefaultUnnamedSessionOnFirstRun()
{
try
{
string json = RunProcessCommandAsync("wslc", "container list --all --format json", CancellationToken.None)
.GetAwaiter().GetResult();
var containers = JsonSerializer.Deserialize<List<ContainerListItem>>(json, JsonOptions);
return containers is { Count: > 0 };
}
catch { return false; }
}
Command building:
// When building wslc commands, check if using (Default) session
private static string BuildSessionScopedWslcArguments(string sessionName, string arguments)
{
if (string.IsNullOrWhiteSpace(sessionName) ||
sessionName.Equals(UnnamedDefaultSessionName, StringComparison.OrdinalIgnoreCase))
{
// Use unnamed default session (no --session parameter)
return arguments;
}
return $"--session {EscapeCliArgument(sessionName.Trim())} {arguments}";
}
Session initialization:
// (Default) session doesn't need SDK initialization
private void EnsureSessionInitialized(string sessionName)
{
if (sessionName.Equals(UnnamedDefaultSessionName, StringComparison.OrdinalIgnoreCase))
{
// WSL manages the default session, just track it
_sessionSettings[sessionName] = GetSessionStoragePath(sessionName);
return;
}
// For named sessions: create SDK instance, initialize, etc.
...
}
Tests use skipDefaultSessionDetection = true in the WslcBackendService constructor to prevent detecting the real system’s default session during unit tests.
Create two named sessions:
Switch between them to keep workloads isolated.
If you have containers in the (Default) session and want to move them to a named session:
docker export <container>wslc --session <new> runwslc container rm <container>The porthole-devcontainers session is configured to work with VS Code’s DevContainers extension. When opening a DevContainer, it automatically uses this session.
Issue: You created a container with wslc but it doesn’t appear in Porthole.
Solution:
wslc container list --all (default session) or wslc --session <name> container list (named session)%LOCALAPPDATA%\Porthole\sessions.json and restart)Issue: The UI doesn’t allow deleting (Default).
Solution: The (Default) session is managed by WSL and cannot be deleted from Porthole. To remove containers from it, use:
wslc container rm <container-name>
Issue: You switch to a session, but after restarting the tray, the previous session is active again.
Solution: This is expected behavior. The active session is persisted to %LOCALAPPDATA%\Porthole\sessions.json. If that file was deleted or corrupted, Porthole will re-initialize and select a session based on discovery priority (see “Session Selection on First Run”).
To manually set the active session, edit the registry file (not recommended for normal use).