Skip to content

fix: reset stale Tailscale funnel/serve state on restart#2600

Merged
limetech merged 1 commit into
masterfrom
codex/fix-tailscale-funnel-reset
Mar 31, 2026
Merged

fix: reset stale Tailscale funnel/serve state on restart#2600
limetech merged 1 commit into
masterfrom
codex/fix-tailscale-funnel-reset

Conversation

@elibosley
Copy link
Copy Markdown
Member

@elibosley elibosley commented Mar 31, 2026

Summary

  • reset any persisted Tailscale Funnel and Serve config after tailscale up
  • reapply only the currently configured template-managed mode after the reset
  • prevent containers switched to Tailscale Serve = No from keeping an old funnel exposure after restart

Root cause

The container hook persisted serve/funnel state in the Tailscale state directory. When a user changed the Docker template from Funnel or Serve to No, the related env vars disappeared, but the hook never cleared the old state before startup completed.

Verification

  • bash -n share/docker/tailscale_container_hook

Related report

Notes

  • I attempted to verify this on the referenced Unraid dev host, but live SSH validation was blocked by hostname resolution and a host-key mismatch for the reachable box.

Summary by CodeRabbit

  • Bug Fixes
    • Tailscale Serve and Funnel configurations are now automatically reset during container startup, ensuring clean configuration state.

- Purpose: clear stale Tailscale Serve and Funnel state when a Docker template changes mode or disables serving.
- Before: switching a container from Funnel or Serve to No removed the env vars but left the persisted Tailscale config active after restart.
- Why: the hook only applied new serve settings when TAILSCALE_SERVE_PORT was present and never reset the existing serve or funnel config stored in the Tailscale state directory.
- What: reset both tailscale funnel and tailscale serve state after tailscale comes online, then reapply the current template-managed mode if one is configured.
- How: add explicit reset commands in the container hook before the Serve/Funnel capability check and before any new serve or funnel command is issued.
- Verification: bash -n share/docker/tailscale_container_hook
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 31, 2026

Walkthrough

A Docker hook script now clears persisted Tailscale Serve and Funnel configuration by executing tailscale funnel reset and tailscale serve reset commands after the container establishes connectivity. Output is suppressed and failures are ignored to prevent hook failures.

Changes

Cohort / File(s) Summary
Tailscale Container Hook
share/docker/tailscale_container_hook
Added reset commands to clear persisted Tailscale Serve/Funnel configuration after container comes online, with error suppression to prevent hook failures.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~5 minutes

Poem

🐰 In the container's home, where Tailscale configs sleep,
We whisper reset commands, secrets to keep,
Funnel and Serve, now cleared clean and bright,
Each fresh startup begins with a tidy new flight! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: reset stale Tailscale funnel/serve state on restart' directly and clearly summarizes the main change: resetting persisted Tailscale configuration on container restart to prevent stale state.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/fix-tailscale-funnel-reset

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

🔧 PR Test Plugin Available

A test plugin has been generated for this PR that includes the modified files.

Version: 2026.03.31.1417
Build: View Workflow Run

📥 Installation Instructions:

Install via Unraid Web UI:

  1. Go to Plugins → Install Plugin
  2. Copy and paste this URL:
https://preview.dl.unraid.net/pr-plugins/pr-2600/webgui-pr-2600.plg
  1. Click Install

Alternative: Direct Download

⚠️ Important Notes:

  • Testing only: This plugin is for testing PR changes
  • Backup included: Original files are automatically backed up
  • Easy removal: Files are restored when plugin is removed
  • Conflicts: Remove this plugin before installing production updates

📝 Modified Files:

Click to expand file list
share/docker/tailscale_container_hook

🔄 To Remove:

Navigate to Plugins → Installed Plugins and remove webgui-pr-2600, or run:

plugin remove webgui-pr-2600

🤖 This comment is automatically generated and will be updated with each new push to this PR.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@share/docker/tailscale_container_hook`:
- Around line 305-306: The two silent reset calls (tailscale funnel reset and
tailscale serve reset) should not discard all errors; run each reset, capture
its stdout/stderr and exit code, and if the exit code is non-zero log a clear
warning including the command name (tailscale funnel reset / tailscale serve
reset) and the captured output so failures like permission or runtime errors are
visible; optionally retry once or escalate to a non-fatal error path (exit only
if you detect a fatal condition such as permission denied) so startup isn’t
silently allowed to continue with stale state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 800d4fa3-7332-426e-b5e9-a74bf413c3cb

📥 Commits

Reviewing files that changed from the base of the PR and between d57ae46 and b90ca2f.

📒 Files selected for processing (1)
  • share/docker/tailscale_container_hook

Comment on lines +305 to +306
tailscale funnel reset >/dev/null 2>&1 || true
tailscale serve reset >/dev/null 2>&1 || true
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Are tailscale funnel resetandtailscale serve reset available in all currently supported stable Tailscale CLI versions, and which version first introduced each command?

💡 Result:

Yes, tailscale funnel reset and tailscale serve reset are available in all currently supported stable Tailscale CLI versions. Tailscale's current stable versions are in the 1.9x series (e.g., up to 1.96.4 as of March 2026), and all supported stable versions are 1.52 and later. Both commands were first introduced in Tailscale v1.52 (October 2023), as part of a CLI rework for funnel and serve subcommands that added status and reset subcommands. Official docs (updated January 2026) confirm: "The CLI commands for both Tailscale Funnel and Tailscale Serve have changed in the 1.52 version" and document tailscale funnel reset and tailscale serve reset. The blog post "Reintroducing Serve and Funnel" (October 30, 2023) announces these changes for v1.52 or later. Funnel/Serve originated earlier (v1.38+), but the reset subcommands came with the v1.52 syntax update. No changelog entries contradict this, and security bulletins reference v1.52 for related serve/funnel fixes.

Citations:


Evaluate failure handling for reset commands; CLI availability is confirmed, but silent failures can hide stale state.

Lines 305–306 suppress all reset errors (>/dev/null 2>&1 || true), which can mask runtime failures and leave stale persisted config active. While tailscale funnel reset and tailscale serve reset are available in all supported Tailscale versions (v1.52+), silent suppression hides other failure modes (permissions, runtime errors) that could prevent the reset from completing while allowing startup to proceed normally.

Consider capturing reset failures explicitly:

💡 Proposed fix
 echo "Resetting Tailscale Serve/Funnel configuration"
-tailscale funnel reset >/dev/null 2>&1 || true
-tailscale serve reset >/dev/null 2>&1 || true
+RESET_FAILED="false"
+if ! tailscale funnel reset >/dev/null 2>&1; then
+  echo "WARNING: Failed to reset Tailscale Funnel configuration."
+  RESET_FAILED="true"
+fi
+if ! tailscale serve reset >/dev/null 2>&1; then
+  echo "WARNING: Failed to reset Tailscale Serve configuration."
+  RESET_FAILED="true"
+fi
+
+# If template-managed Serve/Funnel is disabled, failing reset means stale exposure
+# may persist; do not continue silently.
+if [ "${RESET_FAILED}" = "true" ] && [ -z "${TAILSCALE_SERVE_PORT}" ]; then
+  echo "ERROR: Could not clear persisted Serve/Funnel state while Tailscale Serve is disabled."
+  error_handler
+fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@share/docker/tailscale_container_hook` around lines 305 - 306, The two silent
reset calls (tailscale funnel reset and tailscale serve reset) should not
discard all errors; run each reset, capture its stdout/stderr and exit code, and
if the exit code is non-zero log a clear warning including the command name
(tailscale funnel reset / tailscale serve reset) and the captured output so
failures like permission or runtime errors are visible; optionally retry once or
escalate to a non-fatal error path (exit only if you detect a fatal condition
such as permission denied) so startup isn’t silently allowed to continue with
stale state.

@limetech limetech merged commit 3506cbd into master Mar 31, 2026
5 checks passed
@limetech limetech deleted the codex/fix-tailscale-funnel-reset branch March 31, 2026 14:49
@github-actions
Copy link
Copy Markdown

🧹 PR Test Plugin Cleaned Up

The test plugin and associated files for this PR have been removed from the preview environment.


🤖 This comment is automatically generated when a PR is closed.

@elibosley elibosley restored the codex/fix-tailscale-funnel-reset branch March 31, 2026 15:32
elibosley added a commit that referenced this pull request Apr 14, 2026
- Purpose: backport PR #2600 to the 7.2 branch so Docker template changes clear old Tailscale Serve and Funnel exposure.\n- Before: switching a container from Funnel or Serve to No removed the env vars but left the persisted Tailscale serve/funnel config active after restart.\n- Why: the container hook only applied new serve settings when TAILSCALE_SERVE_PORT was present and never reset existing serve state stored in the Tailscale state directory.\n- What: reset both tailscale funnel and tailscale serve state after tailscale comes online, then reapply the current template-managed mode when configured.\n- How: add explicit reset commands before the Serve/Funnel capability check and before issuing any new serve or funnel command.\n- Source: cherry-picked from b90ca2f.
@elibosley elibosley deleted the codex/fix-tailscale-funnel-reset branch April 28, 2026 20:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants