mirror of
https://github.com/coder/coder.git
synced 2026-09-21 20:51:01 +08:00
docs: add Coder Desktop stale-tunnel recovery and improve macOS log capture (#26735)
## What Adds a **Recovering from a stale tunnel** section to the Coder Desktop user guide, with separate macOS and Windows procedures, and tightens the existing macOS log-collection instructions. ## Why Users in the field have hit a state where Coder Desktop's menu bar / tray shows **Coder Connect** as enabled but the embedded tunnel is no longer working: * `workspace.coder` fails to resolve (`No such host`), or * DNS returns stale `fd60:627a:a42b::/48` addresses that no longer route, causing `coder ssh`, file sync, and the directory picker to hang. Related issues: * coder/coder#26669 — `ExistsViaCoderConnect` false positives when Coder Desktop has stale DNS * coder/coder-desktop-windows#171 — Tray reports Coder Connect as healthy while tunnel/DNS is broken Until the underlying state-management gap is fixed in the apps, the docs should give users (and support) a safe, repeatable way to recover without rebooting. ## Changes `docs/user-guides/desktop/index.md`: 1. **New "Recovering from a stale tunnel" section** under Troubleshooting: * **macOS:** stop the VPN configuration with `scutil --nc stop`, quit the app via `osascript`, restart the helper daemon in place with `launchctl kickstart -k system/com.coder.Coder-Desktop.Helper`, flush DNS caches, then relaunch. * Includes a warning to **not** use `launchctl bootout`, which removes the daemon from launchd's system domain entirely and is not re-bootstrapped on app relaunch. * Includes a verification step using the built-in sentinel hostname `is.coder--connect--enabled--right--now.coder` (defined in `tailnet/conn.go` as `IsCoderConnectEnabledFmtString`) so users don't need a workspace name to confirm the tunnel is healthy. * Uses `dig @fd60:627a:a42b::53` (explicit server) and `dscacheutil -q host -a name` because plain `dig` does not respect the macOS system resolver. * **Windows:** stop the app and `Coder Desktop` service, flush DNS, restart, then verify the NRPT rule and Wintun adapter. Notes that `ipconfig /flushdns` does not reset the embedded resolver and that filtering agents (e.g., Zscaler) may still shadow `.coder` lookups. 2. **macOS log-collection improvements:** * Switch the predicate from `subsystem == "com.coder.Coder-Desktop"` to `subsystem BEGINSWITH "com.coder.Coder-Desktop"` so the export captures the app, helper daemon, and network extension (which all log under prefixed subsystems). * Add a `log stream` example for live tailing while reproducing an issue. ## Verification * `npx markdownlint-cli2 docs/user-guides/desktop/index.md` — 0 errors. * macOS recovery steps were validated end-to-end on a real install (the `kickstart -k` form, in particular, was confirmed to restart the helper without breaking the install, unlike `bootout`). --- Created on behalf of @mdanter --------- Co-authored-by: blink-so[bot] <211532188+blink-so[bot]@users.noreply.github.com> Co-authored-by: Atif Ali <atif@coder.com> Co-authored-by: Nick Vigilante <nickvigilante@users.noreply.github.com> Co-authored-by: Matyas Danter <mdanter@gmail.com>
This commit is contained in:
co-authored by
blink-so[bot]
Atif Ali
Nick Vigilante
Matyas Danter
parent
57dc47dc42
commit
043bebb7bc
@@ -169,7 +169,121 @@ You can also configure a `Updater:ForcedChannel` string value to lock users to a
|
||||
- Check system permissions for network extensions
|
||||
- Ensure only one copy of Coder Desktop is installed
|
||||
|
||||
### Collecting Logs
|
||||
### Recover from a stale tunnel
|
||||
|
||||
If the menu bar or tray shows **Coder Connect** as enabled but workspaces are
|
||||
unreachable (SSH hangs, `workspace.coder` fails to resolve, or file sync cannot
|
||||
list the workspace directory), the embedded tunnel may be in a stale state.
|
||||
Restart the helper components first.
|
||||
If that doesn't resolve the issue, reboot your computer.
|
||||
|
||||
<div class="tabs">
|
||||
|
||||
#### macOS
|
||||
|
||||
Run the following commands in a terminal.
|
||||
These steps leave the app and helper daemon installed.
|
||||
They only restart the running tunnel and flush DNS caches.
|
||||
|
||||
1. Stop the Coder VPN configuration:
|
||||
|
||||
```shell
|
||||
vpn_name=$(scutil --nc list | grep "com.coder.Coder-Desktop" | awk -F'"' '{print $2}' | tail -n1)
|
||||
if [ -n "$vpn_name" ]; then scutil --nc stop "$vpn_name"; fi
|
||||
```
|
||||
|
||||
2. Quit the Coder Desktop app:
|
||||
|
||||
```shell
|
||||
osascript -e 'tell application id "com.coder.Coder-Desktop" to quit'
|
||||
```
|
||||
|
||||
3. Restart the helper daemon in place:
|
||||
|
||||
```shell
|
||||
sudo launchctl kickstart -k system/com.coder.Coder-Desktop.Helper
|
||||
```
|
||||
|
||||
> [!WARNING]
|
||||
> Do not use `launchctl bootout` here. `bootout` removes the daemon from
|
||||
> launchd's system domain entirely, and relaunching the app does not
|
||||
> re-bootstrap it. Use `kickstart -k` to restart it in place.
|
||||
|
||||
4. Flush DNS caches:
|
||||
|
||||
```shell
|
||||
sudo dscacheutil -flushcache
|
||||
sudo killall -HUP mDNSResponder
|
||||
```
|
||||
|
||||
5. Confirm the stale tunnel is gone (the command should print nothing):
|
||||
|
||||
```shell
|
||||
scutil --nc list | grep "com.coder.Coder-Desktop"
|
||||
```
|
||||
|
||||
6. Relaunch **Coder Desktop** from your `/Applications` folder and toggle **Coder Connect** back on.
|
||||
|
||||
To verify the tunnel is healthy after relaunching, query the built-in sentinel
|
||||
hostname against Coder Desktop's embedded DNS server:
|
||||
|
||||
```shell
|
||||
dig @fd60:627a:a42b::53 AAAA is.coder--connect--enabled--right--now.coder +short
|
||||
dscacheutil -q host -a name is.coder--connect--enabled--right--now.coder
|
||||
```
|
||||
|
||||
Both commands should return an `fd60:627a:a42b::/48` address.
|
||||
If `dig` returns nothing or `dscacheutil` reports no entries, Coder Connect is not publishing DNS.
|
||||
[Collect logs](#collect-logs) and file an issue.
|
||||
|
||||
#### Windows
|
||||
|
||||
Run the following in an **elevated PowerShell** session.
|
||||
The service restart clears the embedded DNS state.
|
||||
The NRPT and adapter checks confirm the system routing policy is intact.
|
||||
|
||||
1. Stop the app and the VPN service:
|
||||
|
||||
```ps1
|
||||
Get-Process -Name "Coder Desktop" -ErrorAction SilentlyContinue | Stop-Process -Force
|
||||
Stop-Service -Name "Coder Desktop" -Force
|
||||
```
|
||||
|
||||
2. Flush DNS caches:
|
||||
|
||||
```ps1
|
||||
ipconfig /flushdns
|
||||
Clear-DnsClientCache
|
||||
```
|
||||
|
||||
3. Start the service again and relaunch the app:
|
||||
|
||||
```ps1
|
||||
Start-Service -Name "Coder Desktop"
|
||||
Start-Process "C:\Program Files\Coder Desktop\CoderDesktop.exe"
|
||||
```
|
||||
|
||||
4. After re-enabling Coder Connect in the tray, verify the NRPT rule and the Wintun adapter exist:
|
||||
|
||||
```ps1
|
||||
Get-DnsClientNrptRule | Where-Object { $_.Namespace -like "*.coder" }
|
||||
Get-NetAdapter | Where-Object { $_.InterfaceDescription -like "*Wintun*" }
|
||||
```
|
||||
|
||||
If either command returns nothing while Coder Connect shows as enabled,
|
||||
the tunnel did not finish coming up. Disable and re-enable the toggle, or
|
||||
repeat the steps above.
|
||||
|
||||
> [!NOTE]
|
||||
> `ipconfig /flushdns` does not reset Coder Desktop's embedded DNS resolver;
|
||||
> restarting the service is what clears its internal cache. If you are running
|
||||
> a network filtering agent (for example, Zscaler), it may shadow `.coder`
|
||||
> lookups even after the tunnel comes back. Check with your IT team if DNS
|
||||
> still fails after a clean restart.
|
||||
|
||||
</div>
|
||||
|
||||
### Collect logs
|
||||
|
||||
When reporting an issue, attach the relevant log files so we can diagnose it faster.
|
||||
|
||||
@@ -182,11 +296,24 @@ Coder Desktop and its network extension write to the Apple [unified logging syst
|
||||
1. Export the unified logs for the last hour with the `log` command:
|
||||
|
||||
```sh
|
||||
log show --predicate 'subsystem == "com.coder.Coder-Desktop"' \
|
||||
log show --predicate 'subsystem BEGINSWITH "com.coder.Coder-Desktop"' \
|
||||
--info --debug --last 1h > ~/Desktop/coder-desktop.log
|
||||
```
|
||||
|
||||
Adjust `--last` (e.g. `30m`, `2h`, `1d`) to cover the time the issue occurred. You can also view the same logs interactively in **Console.app** by filtering on the `com.coder.Coder-Desktop` subsystem.
|
||||
The `BEGINSWITH` predicate captures the app, the helper daemon, and the
|
||||
network extension, which all log under subsystems prefixed with
|
||||
`com.coder.Coder-Desktop`. Adjust `--last` (e.g. `30m`, `2h`, `1d`) to
|
||||
cover the time the issue occurred.
|
||||
|
||||
You can stream the logs live while reproducing an issue:
|
||||
|
||||
```shell
|
||||
log stream --predicate 'subsystem BEGINSWITH "com.coder.Coder-Desktop"' --info --debug
|
||||
```
|
||||
|
||||
You can also view the same logs interactively in **Console.app** by
|
||||
filtering on `subsystem:com.coder.Coder-Desktop` with Info and Debug
|
||||
messages enabled.
|
||||
|
||||
2. If you're using file sync, also collect the Mutagen daemon log:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user