Trailing whitespace and comment/field alignment only; no behaviour change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
zhguchiy_perchik
Proxy checker panel with its own subscription system. It continuously pulls proxy configs (vless / vmess / trojan / ss) from source lists, checks each for validity by its exit IP, keeps only working ones, and serves them to clients as subscriptions (plain / base64 / Clash / sing-box).
See ARCHITECTURE.md for the design and TODO.md for the full feature wishlist.
Stack
| Service | Stack | Role |
|---|---|---|
postgres |
PostgreSQL 16 | Database |
checker |
Go (cmd/checker) |
Worker: fetch → canonicalize/dedup → check → geo → write sessions |
api |
Go (cmd/api) |
REST panel API + public subscription endpoints |
web |
React + Vite + TS + Tailwind + nginx | SPA panel (Dashboard / Proxies / Subscriptions / Settings), also routes /api + /sub |
The vless/vmess/trojan/ss dialers, upstream parser, geoip and fetcher are reused
from tessero-checker; the canonicalization, session model, DB layer,
subscription conversion and API/UI are new.
Quick start
Images are built and pushed to the Gitea container registry by CI, so the default compose pulls them:
cp .env.example .env
# edit .env: set ADMIN_PASSWORD and SESSION_SECRET (long random)
docker compose pull
docker compose up -d
To build the images locally from source instead of pulling, add the build override:
docker compose -f docker-compose.yml -f docker-compose.build.yml up -d --build
Open http://localhost:8088 and sign in with ADMIN_USER / ADMIN_PASSWORD.
Then in the panel:
- Settings → Sources: add one or more list URLs and pick the type
(
autotries base64 then plain, or forceplain/base64). See TODO.md for example lists. - Run check (top bar) or wait for the scheduled interval.
- Working proxies appear in Proxies; build client feeds in Subscriptions.
Model — "only working / last completed session"
The panel and subscriptions always serve the last completed check session; a
running or crashed session never affects output. When a session completes, one
transaction flips the is_current pointer. Per-canonical history (uptime,
consecutive failures) is kept even while a proxy is currently invalid, but only
working proxies from the current session are ever shown or served.
Development
Backend:
go test ./...
go vet ./...
go run ./cmd/api # needs DB_DSN, ADMIN_PASSWORD, SESSION_SECRET
go run ./cmd/checker # needs DB_DSN
Frontend (proxies /api + /sub to localhost:8080):
cd frontend
npm install
npm run dev
CI
.gitea/workflows/ci.yml runs go vet / go test / go build and the frontend
build on every push, then (on main) builds and pushes the three images to the
Gitea container registry.