Enabling Health Checks for Private Resources in Pangolin: The Newt Solution

Enabling Health Checks for Private Resources in Pangolin: The Newt Solution

Health checks are a powerful feature in Pangolin for monitoring the status of your resources, enabling intelligent load balancing, automatic failover, and better visibility into service health. However, many users run into a common roadblock: health checks don’t work (or appear gray/unknown) for “local” or private resources until you properly configure Newt.

This guide, inspired by real community troubleshooting, walks through why this happens and how to fix it efficiently.

Understanding the Components

  • Pangolin: The core identity-aware VPN and tunneled reverse proxy server (based on WireGuard). It handles authentication, access control, and routing.
  • Newt: The companion client — a fully user-space WireGuard tunnel client and TCP/UDP proxy. It securely connects remote/private resources back to your Pangolin instance. Newt runs near (or alongside) your backend services and performs active health checks.
  • Resources/Sites: In Pangolin, you define “sites” and attach resources (containers, services, etc.). Resources can be marked as “local” (direct on the Pangolin host/network) or tunneled via Newt.

Key Insight: Health checks are executed from inside Newt. Without a Newt-connected site, Pangolin has no active monitor performing checks, so the status remains “unknown” (often shown as gray).

The Problem

Users often see something like this in the UI:

  • Cannot enable health checks for private resources.
  • Status stays gray/unknown even after attempting configuration.
  • Docker Compose examples (like the official docker-compose.example.yml) may not mention Newt, leading to confusion.

This is expected behavior in versions like v1.18.1 — health checks rely on Newt performing the probes and reporting back.

The Solution: Migrate to a Newt Site

  1. Create a New Site in Pangolin (preferably the top-level/default site for lowest latency, unless you have specific multi-site needs).
  2. Provision Newt for that site (copy the credentials/config from the Pangolin UI).
  3. Update your resources:
    • Change the resource selector/type from Local to Newt.
    • Point them to the Newt-connected site.
  4. Run Newt near your services (Docker recommended for self-hosted setups).

Once Newt is active and resources are attached, health checks become available and statuses update to green (healthy) or red (unhealthy).

Optimized Docker Compose Setup (Avoid Extra Hops)

To keep traffic efficient, use Docker network aliases so Newt can reach services directly via the internal Docker network instead of looping out through the public internet/WireGuard unnecessarily.

Here’s a recommended configuration:

services:
  gerbil:  # Example backend service (replace with your actual services)
    image: your-service-image
    networks:
      default:
        aliases:
          - pangolin.domain.com  # Alias so Newt resolves it locally via Docker DNS
          # Add more aliases as needed for your resource hostnames

  pangolin:
    # Your Pangolin container config...
    networks:
      - default
      # Do not attach to Traefik/external networks if not needed

  newt:
    image: fosrl/newt:latest
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
      gerbil:  # Ensure backends are ready
        condition: service_started
    environment:
      - PANGOLIN_ENDPOINT=https://pangolin.yourdomain.com
      - NEWT_ID=your_newt_id_from_pangolin
      - NEWT_SECRET=your_newt_secret_from_pangolin
    networks:
      - default

networks:
  default:
    name: pangolin
    enable_ipv6: true  # Optional, depending on your setup

Why aliases matter: They prevent unnecessary network hops (Newt → public → back in). Internal Docker resolution is faster and more reliable.

Post-Migration Steps

  • Restart services and verify Newt connects successfully in the Pangolin dashboard.
  • Edit existing resources to use the Newt site.
  • Enable health checks on resources (HTTP, TCP, etc., as supported).
  • Monitor the UI — statuses should now transition from gray/unknown to green.

Users report that after this migration, “health checks are working” and the system behaves as expected.

Best Practices & Tips

  • Latency: Use the top-level site unless you need geographic or logical separation.
  • Multiple Resources: Update selectors one by one or in bulk if your UI supports it.
  • Security: Newt handles the secure tunneling — keep your NEWT_ID and NEWT_SECRET protected.
  • Updates: Keep Pangolin and Newt versions aligned for best compatibility and performance.
  • Troubleshooting: Check Newt logs for connection/health check errors. Ensure firewall rules allow the WireGuard traffic.

Why This Architecture?

Newt’s design (user-space WireGuard + proxy) makes it ideal for distributed, zero-trust environments. It eliminates complex manual WireGuard configs and NAT issues while adding powerful capabilities like health monitoring directly from the resource’s network context.

This approach scales for self-hosted setups, IoT, internal tools, or hybrid cloud deployments.

Conclusion

Switching private resources to Newt unlocks the full power of Pangolin’s health checking and load balancing. While it requires a small migration step, the benefits in reliability, observability, and performance are well worth it.

Resources:

Have questions or a unique setup? Drop them in the comments or the community forums.

Gave it a shot as the lack of health checks using local site was annoying to say the least.
With the provided clear instruction, finally got health checks to work directly within pangolin dashboard :slight_smile:

Thanks!