By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Description
This change adds healthcheck support for local sites in Pangolin.
How to test?
You need a Pangolin instance with at least one Local site configured — a site where the target is directly reachable by the Pangolin server over the network (not tunnelled through Newt).
Test 1: Healthcheck turns healthy
Go to a resource attached to a local site, open the proxy settings, and click the healthcheck button on a target
Configure a simple HTTP check pointing at a running service (e.g. GET / expecting 200)
Enable it and save
Within a few seconds the target should transition from Unknown → Healthy
The resource card should also reflect Healthy
Test 2: Healthcheck detects a failure
With the healthcheck running and showing Healthy, stop or block the target service
Within one polling interval the target should transition to Unhealthy
Restart the service — it should return to Healthy
Test 3: TCP mode
Repeat tests 1 and 2 using TCP mode instead of HTTP to verify the TCP probe path works independently
Test 4: Config options
Set a custom interval (e.g. 10s) and verify the polling frequency changes
Set an unhealthy interval (e.g. 60s) and verify it polls less aggressively once unhealthy
Set a healthy/unhealthy threshold > 1 and verify the target doesn't flip status until that many consecutive results are seen
Test 5: WireGuard sites are unaffected
On a WireGuard site, verify the healthcheck button still does not appear and no probing happens
Test 6: Newt sites are unaffected
On a Newt site, verify healthchecks still work exactly as before — the Newt agent should still be doing the probing, not the server
Test 7: Enable/disable toggle
Disable an active healthcheck and verify the status resets to Unknown and polling stops. Re-enable it and verify it resumes from Unknown → Unhealthy → Healthy
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.
## 📋 Pull Request Information
**Original PR:** https://github.com/fosrl/pangolin/pull/2932
**Author:** [@pizzaandcheese](https://github.com/pizzaandcheese)
**Created:** 4/29/2026
**Status:** 🔄 Open
**Base:** `main` ← **Head:** `feature/local-resource-healthchecks`
---
### 📝 Commits (2)
- [`b755c39`](https://github.com/fosrl/pangolin/commit/b755c39b90aab5c0711180dede1ec5ad8b3b32ba) feat(healthcheck): run healthchecks for local sites server-side
- [`34d41d9`](https://github.com/fosrl/pangolin/commit/34d41d9e6434357ffec057c57e2a88ace623b8dc) feat(healthcheck): enable healthcheck UI for local site types
### 📊 Changes
**6 files changed** (+367 additions, -6 deletions)
<details>
<summary>View changed files</summary>
📝 `server/routers/target/index.ts` (+1 -0)
➕ `server/routers/target/localHealthChecker.ts` (+349 -0)
📝 `server/routers/target/updateTarget.ts` (+9 -4)
📝 `server/routers/ws/messageHandlers.ts` (+6 -0)
📝 `src/app/[orgId]/settings/resources/proxy/[niceId]/proxy/page.tsx` (+1 -1)
📝 `src/app/[orgId]/settings/resources/proxy/create/page.tsx` (+1 -1)
</details>
### 📄 Description
## Community Contribution License Agreement
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
## Description
This change adds healthcheck support for local sites in Pangolin.
## How to test?
You need a Pangolin instance with at least one Local site configured — a site where the target is directly reachable by the Pangolin server over the network (not tunnelled through Newt).
Test 1: Healthcheck turns healthy
1. Go to a resource attached to a local site, open the proxy settings, and click the healthcheck button on a target
2. Configure a simple HTTP check pointing at a running service (e.g. GET / expecting 200)
3. Enable it and save
4. Within a few seconds the target should transition from Unknown → Healthy
5. The resource card should also reflect Healthy
Test 2: Healthcheck detects a failure
1. With the healthcheck running and showing Healthy, stop or block the target service
2. Within one polling interval the target should transition to Unhealthy
3. Restart the service — it should return to Healthy
Test 3: TCP mode
Repeat tests 1 and 2 using TCP mode instead of HTTP to verify the TCP probe path works independently
Test 4: Config options
- Set a custom interval (e.g. 10s) and verify the polling frequency changes
- Set an unhealthy interval (e.g. 60s) and verify it polls less aggressively once unhealthy
- Set a healthy/unhealthy threshold > 1 and verify the target doesn't flip status until that many consecutive results are seen
Test 5: WireGuard sites are unaffected
On a WireGuard site, verify the healthcheck button still does not appear and no probing happens
Test 6: Newt sites are unaffected
On a Newt site, verify healthchecks still work exactly as before — the Newt agent should still be doing the probing, not the server
Test 7: Enable/disable toggle
Disable an active healthcheck and verify the status resets to Unknown and polling stops. Re-enable it and verify it resumes from Unknown → Unhealthy → Healthy
---
<sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
📋 Pull Request Information
Original PR: https://github.com/fosrl/pangolin/pull/2932
Author: @pizzaandcheese
Created: 4/29/2026
Status: 🔄 Open
Base:
main← Head:feature/local-resource-healthchecks📝 Commits (2)
b755c39feat(healthcheck): run healthchecks for local sites server-side34d41d9feat(healthcheck): enable healthcheck UI for local site types📊 Changes
6 files changed (+367 additions, -6 deletions)
View changed files
📝
server/routers/target/index.ts(+1 -0)➕
server/routers/target/localHealthChecker.ts(+349 -0)📝
server/routers/target/updateTarget.ts(+9 -4)📝
server/routers/ws/messageHandlers.ts(+6 -0)📝
src/app/[orgId]/settings/resources/proxy/[niceId]/proxy/page.tsx(+1 -1)📝
src/app/[orgId]/settings/resources/proxy/create/page.tsx(+1 -1)📄 Description
Community Contribution License Agreement
By creating this pull request, I grant the project maintainers an unlimited,
perpetual license to use, modify, and redistribute these contributions under any terms they
choose, including both the AGPLv3 and the Fossorial Commercial license terms. I
represent that I have the right to grant this license for all contributed content.
Description
This change adds healthcheck support for local sites in Pangolin.
How to test?
You need a Pangolin instance with at least one Local site configured — a site where the target is directly reachable by the Pangolin server over the network (not tunnelled through Newt).
Test 1: Healthcheck turns healthy
Test 2: Healthcheck detects a failure
Test 3: TCP mode
Repeat tests 1 and 2 using TCP mode instead of HTTP to verify the TCP probe path works independently
Test 4: Config options
Test 5: WireGuard sites are unaffected
On a WireGuard site, verify the healthcheck button still does not appear and no probing happens
Test 6: Newt sites are unaffected
On a Newt site, verify healthchecks still work exactly as before — the Newt agent should still be doing the probing, not the server
Test 7: Enable/disable toggle
Disable an active healthcheck and verify the status resets to Unknown and polling stops. Re-enable it and verify it resumes from Unknown → Unhealthy → Healthy
🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.