{"id":51417074,"url":"https://github.com/spy4x/zond","last_synced_at":"2026-07-04T20:30:35.052Z","repository":{"id":369140123,"uuid":"1280681237","full_name":"spy4x/zond","owner":"spy4x","description":"Internal health probe bridge for services behind SSO proxies","archived":false,"fork":false,"pushed_at":"2026-07-03T18:47:53.000Z","size":8,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-03T20:26:26.487Z","etag":null,"topics":["authelia","deno","docker","gatus","health-check","monitoring","probe","self-hosted","self-hosting","sso-bypass"],"latest_commit_sha":null,"homepage":"https://github.com/spy4x/zond","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/spy4x.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-25T20:43:14.000Z","updated_at":"2026-07-03T18:47:58.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/spy4x/zond","commit_stats":null,"previous_names":["spy4x/zond"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/spy4x/zond","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spy4x%2Fzond","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spy4x%2Fzond/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spy4x%2Fzond/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spy4x%2Fzond/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/spy4x","download_url":"https://codeload.github.com/spy4x/zond/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/spy4x%2Fzond/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35135341,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-04T02:00:05.987Z","response_time":113,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authelia","deno","docker","gatus","health-check","monitoring","probe","self-hosted","self-hosting","sso-bypass"],"created_at":"2026-07-04T20:30:34.409Z","updated_at":"2026-07-04T20:30:35.037Z","avatar_url":"https://github.com/spy4x.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Zond 🚀\n\n[![Docker](https://img.shields.io/badge/docker-ghcr.io%2Fspy4x%2Fzond-blue)](https://github.com/spy4x/zond/pkgs/container/zond)\n[![Deno](https://img.shields.io/badge/deno-2.2-black?logo=deno)](https://deno.com)\n[![License](https://img.shields.io/badge/license-MIT-green)](LICENSE)\n[![GitHub](https://img.shields.io/badge/github-spy4x%2Fzond-181717?logo=github)](https://github.com/spy4x/zond)\n\n**Zond** (Зонд — Russian: \"probe\") is a tiny internal health probe bridge.\nIt receives external health check requests from monitoring systems\nlike [Gatus](https://github.com/TwiN/gatus) and forwards them to internal\ncontainers via Docker DNS names — no authentication required, no internal\ndetails exposed.\n\n```\n┌──────────┐     ┌──────────┐     ┌─────────────┐\n│  Gatus   │────▶│  Zond    │────▶│ hl-metube   │\n│ (cloud)  │     │ (home)   │     │ :8081       │\n└──────────┘     └──────────┘     └─────────────┘\n```\n\n## Why Zond?\n\nMonitoring services behind an SSO proxy (Authelia, Authentik) is painful.\nYou either accept `302` redirects as \"healthy\" or expose your apps with\ndedicated monitoring users. Zond sits **_beside_** your containers (same\nDocker network) and probes them directly, returning only `200` or `503`.\nNo auth bypass, no password management.\n\n**One line in Gatus:**\n\n```yaml\n- name: Metube\n  url: \"https://zond.example.com/health/metube\"\n  conditions:\n    - \"[STATUS] == 200\"\n```\n\n## Features\n\n- **Zero attack surface** — returns `200` or `503`, no internal URLs, no tokens\n- **Single endpoint per service** — `GET /health/\u003cname\u003e`\n- **Bulk check** — `GET /` or `GET /health` lists all targets by name only\n- **Config-driven** — YAML file (`zond.yml` by default, falls back to `zond.yaml`) or `ZOND_TARGETS` env var\n- **Per-target timeout** — configure probe timeouts individually\n- **Docker-native** — 30MB Deno image, no dependencies\n- **Standalone binary** — `deno task compile` for bare-metal\n\n## Quick start\n\n### 1. Config file\n\n```yaml\n# zond.yml\nport: 8080\ntargets:\n  - name: metube\n    url: http://hl-metube:8081/\n  - name: ollama\n    url: http://hl-ollama:11434/api/tags\n    timeout: 10000  # ms, default 5000\n  - name: grafana\n    url: http://hl-grafana:3000/api/health\n    timeout: 3000\n```\n\n```bash\ndocker run -p 8080:8080 \\\n  -v $(pwd)/zond.yml:/app/zond.yml \\\n  ghcr.io/spy4x/zond:latest\n\ncurl http://localhost:8080/health/metube\n# ok\n```\n\n### 2. Environment variables\n\n```bash\ndocker run -p 8080:8080 \\\n  -e ZOND_TARGETS=\"metube=http://hl-metube:8081/,ollama=http://hl-ollama:11434/api/tags\" \\\n  ghcr.io/spy4x/zond:latest\n```\n\nNote: env var targets use the default timeout (5000ms). For custom timeouts,\nuse a config file.\n\n### 3. Docker Compose\n\n```yaml\nservices:\n  zond:\n    image: ghcr.io/spy4x/zond:latest\n    container_name: zond\n    restart: unless-stopped\n    ports:\n      - \"8080:8080\"\n    volumes:\n      - ./zond.yml:/app/zond.yml:ro\n    networks:\n      - internal  # same network as your probes\n    deploy:\n      resources:\n        limits:\n          memory: 32M\n          cpus: \"0.1\"\n```\n\n## API\n\n### `GET /health/\u003cname\u003e`\n\n| Response | Status | Meaning |\n|---|---|---|\n| `ok\\n` | `200` | Target responded 2xx/3xx |\n| `unreachable\\n` | `503` | Connection failed or 4xx/5xx |\n| `unknown target: \u003cname\u003e\\n` | `404` | Target not in config |\n\n### `GET /` or `GET /health`\n\nReturns one line per target, overall `200` if all healthy:\n\n```\nOK metube\nKO grafana\nOK ollama\n```\n\nNo internal URLs or other details exposed. Overall status is `503` if any\ntarget is down.\n\n## Configuration\n\n| Option | Env var | Default | Description |\n|---|---|---|---|\n| `port` | `ZOND_PORT` | `8080` | HTTP listen port |\n| `targets[].name` | — | required | URL slug in `/health/\u003cname\u003e` |\n| `targets[].url` | — | required | Internal URL to probe (Docker DNS or any) |\n| `targets[].timeout` | — | `5000` | Request timeout in ms |\n\nConfig resolution order:\n1. `ZOND_TARGETS` env var (default timeout applies to all)\n2. `ZOND_CONFIG_PATH` env var → YAML file (supports `.yml` and `.yaml`)\n3. `./zond.yml` in working directory (falls back to `./zond.yaml`)\n\n## Docker\n\n```bash\ndocker build -t ghcr.io/spy4x/zond:latest .\ndocker run --network proxy \\\n  -v $(pwd)/zond.yml:/app/zond.yml \\\n  ghcr.io/spy4x/zond:latest\n```\n\n## Compile (standalone)\n\n```bash\ndeno task compile\n./zond\n```\n\n## Development\n\n```bash\ndeno task dev    # run locally\ndeno task check  # type-check\ndeno task lint   # lint\ndeno task fmt    # format\n```\n\n## Why not TCP checks?\n\nTCP checks (`tcp://hl-metube:8081`) confirm a port is open. Zond performs\na real HTTP request and validates the response — catching cases where the\nprocess is listening but returning 5xx errors.\n\n## Why no authentication?\n\nZond returns only `ok` or `ko`. No data to protect, no session to steal,\nno action to perform. Adding auth would reintroduce the exact problem Zond\nsolves. If you must, proxy it through your SSO — but the health endpoint\nitself carries zero risk.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspy4x%2Fzond","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fspy4x%2Fzond","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fspy4x%2Fzond/lists"}