
如果你使用 DeepSeek、元宝 AI、Copilot、ChatGPT 等 AI 工具,协助配置轩辕镜像、编写 docker pull 命令、修改 Docker Compose 镜像地址、配置镜像加速、排查镜像拉取失败、分析报错日志等问题,请先让 AI 阅读并遵守轩辕镜像的规则文档。
只需在 AI 对话中先发送下面这句话即可:
请先完整阅读并严格遵守以下文档中的全部规则与要求:
https://xuanyuan.cloud/agents.md
在未充分阅读并理解该文档前,不要生成任何命令、配置、修改建议、故障排查方案或技术回答。后续所有输出都必须严格以该文档中的规范为最高优先级执行。查看 agents.md 用法指南与完整示范。国内用户首推 元宝 AI、DeepSeek 的深度思考模式,不推荐豆包 AI;Cursor 等编辑器可在对话 @ 该链接,或加入 User Rules。 若 AI 无法访问外链,可 打开说明文档 复制全文粘贴。文档会随站点更新,复制内容可能过期,建议定期检查。
Neko Master
See your network traffic clearly.
Real-time monitoring · Traffic auditing · Multi-gateway support
English | 中文
https://github.com/foru17/neko-master/stargazers https://hub.docker.com/r/foru17/neko-master https://hub.docker.com/r/foru17/neko-master https://hub.docker.com/r/foru17/neko-master https://github.com/foru17/neko-master/blob/main/LICENSE
https://github.com/foru17/neko-master/actions/workflows/docker-build.yml
[!IMPORTANT] Disclaimer
This project is a traffic analysis and visualization tool for local gateway environments.
It does not provide any network access service, proxy subscription, or cross-network connectivity. All data is collected from the user's own network environment.
This project is open-sourced under the MIT License. We assume no responsibility for any consequences resulting from the use of this software. Please use it in compliance with applicable laws and regulations.
|
|
Neko (ねこ) means cat in Japanese. Pronounced /ˈneɪkoʊ/ (NEH-ko).
Like a cat, Neko Master observes network traffic quietly and precisely. It is a lightweight analytics dashboard designed for modern gateway environments.
| Feature | Description |
|---|---|
| 📊 Real-time Monitoring | WebSocket real-time collection with millisecond latency |
| 📈 Trend Analysis | Multi-dimensional traffic trends: 30min / 1h / 24h |
| 🌐 Domain Analysis | View traffic, associated IPs, and connection count per domain |
| 🗺️ IP Analysis | ASN, geo-location, and associated domain display |
| 🚀 Proxy Statistics | Traffic distribution and connection count per proxy node |
| 📱 PWA Support | Install as desktop app for native experience |
| 🌙 Dark Mode | Light / Dark / System theme support |
| 🌍 i18n Support | English / Chinese seamless switching |
| 🔄 Multi-Backend | Monitor multiple Open*** backend instances simultaneously |
The repository's built-in
docker-compose.ymlmaps3000/3001/3002by default. Scenarios A/B below are minimal templates for common deployments.
Scenario A: Minimal deployment (only expose 3000)
yamlservices: neko-master: image: foru17/neko-master:latest container_name: neko-master restart: unless-stopped ports: - "3000:3000" # Web UI volumes: - ./data:/app/data # Local MMDB (optional, files should be downloaded into ./geoip) - ./geoip:/app/data/geoip:ro environment: - NODE_ENV=production - DB_PATH=/app/data/stats.db - COOKIE_SECRET=${COOKIE_SECRET}
Recommended in
.env(same directory asdocker-compose.yml):COOKIE_SECRET=<at least 32-byte random string>(generate withopenssl rand -hex 32)
This mode is fully upgrade-compatible and works out of the box. If WS is not routed, the app falls back to HTTP polling automatically.
Scenario B: Real-time WebSocket (recommended with reverse proxy)
yamlservices: neko-master: image: foru17/neko-master:latest container_name: neko-master restart: unless-stopped ports: - "3000:3000" # Web UI - "3002:3002" # WebSocket (for Nginx / Tunnel forwarding) volumes: - ./data:/app/data # Local MMDB (optional, files should be downloaded into ./geoip) - ./geoip:/app/data/geoip:ro environment: - NODE_ENV=production - DB_PATH=/app/data/stats.db - COOKIE_SECRET=${COOKIE_SECRET}
Then run:
bashdocker compose up -d
Open http://localhost:3000 to get started.
If you use the repository's built-in Compose file (default 3000/3001/3002), run the same command.
bash# Generate a fixed cookie secret first (for session persistence) export COOKIE_SECRET="$(openssl rand -hex 32)"
bash# Minimal (only 3000) docker run -d \ --name neko-master \ -p 3000:3000 \ -v $(pwd)/data:/app/data \ -e COOKIE_SECRET="$COOKIE_SECRET" \ --restart unless-stopped \ foru17/neko-master:latest # Real-time WS (with reverse proxy) docker run -d \ --name neko-master \ -p 3000:3000 \ -p 3002:3002 \ -v $(pwd)/data:/app/data \ -e COOKIE_SECRET="$COOKIE_SECRET" \ --restart unless-stopped \ foru17/neko-master:latest
Open http://localhost:3000 to get started.
The frontend uses same-origin
/apiby default, so port 3001 is usually not required externally. For real-time WS, your reverse proxy/tunnel must be able to reach port3002. If not, the app falls back to ~5s HTTP polling.
For
docker run, change external ports using-pmappings directly. Only if you use direct WS access (no reverse proxy) and external WS port is not3002, also pass-e WS_EXTERNAL_PORT=<external-ws-port>.Local MMDB lookup mode (optional): mount
-v $(pwd)/geoip:/app/data/geoip:ro, then switch source to Local inSettings -> Preferences -> IP Lookup Source.
Automatically detects port conflicts and configures everything:
bash# Using curl curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash # Or using wget wget -qO- https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
The script will automatically:
docker-compose.ymlbash# 1. Clone the repository git clone https://github.com/foru17/neko-master.git cd neko-master # 2. Install dependencies pnpm install # 3. Prepare collector env (source mode reads apps/collector/.env) cp apps/collector/.env.example apps/collector/.env # 4. Start development services pnpm dev
Open http://localhost:3000 to configure.
In source mode: collector listens on
3001/3002, web listens on3000by default. If you changedAPI_PORT(not 3001), setAPI_URLaccordingly (for exampleAPI_URL=http://localhost:4001) so web/apirewrite targets the correct API.apps/collector/.env.localtakes precedence overapps/collector/.env.
Use Agent mode when you want one centralized Neko Master service and multiple remote devices (OpenWrt, Linux, macOS) collecting local gateway data. The agent runs near the gateway, pulls data, and reports to the panel — the panel never connects to the gateway directly.
Supported gateway types: ***** / ***** (WebSocket real-time) and ***** v5+** (HTTP polling).
Settings → Backends, add an Agent backend, select gateway typebash# Clash / Mihomo gateway example curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \ | env NEKO_SERVER='http://your-panel:3000' \ NEKO_BACKEND_ID='1' \ NEKO_BACKEND_TOKEN='ag_xxx' \ NEKO_GATEWAY_TYPE='clash' \ NEKO_GATEWAY_URL='http://127.0.0.1:9090' \ sh # Surge gateway example curl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/apps/agent/install.sh \ | env NEKO_SERVER='http://your-panel:3000' \ NEKO_BACKEND_ID='2' \ NEKO_BACKEND_TOKEN='ag_yyy' \ NEKO_GATEWAY_TYPE='surge' \ NEKO_GATEWAY_URL='http://127.0.0.1:9091' \ sh
After install, manage instances with nekoagent:
bashnekoagent list # list all instances nekoagent status <instance> # check running state nekoagent logs <instance> # tail live logs nekoagent restart <instance> # restart nekoagent upgrade # global upgrade (CLI + binary)
The script auto-detects an existing installation — if
neko-agentis already present, it only adds the new instance without re-downloading. Multiple instances can run on the same host (differentNEKO_INSTANCE_NAME), each pointing to a different gateway.
!First Use
Clash / Mihomo192.168.101.1)9090)💡 Get Gateway Address: Go to your gateway control panel (e.g., Open***) → Enable "External Control" → Copy API address
!*** HTTP API Configuration
Neko Master supports connecting to *** gateways for complete rule chain visualization and traffic analysis.
1. Enable *** HTTP API
Enable HTTP remote API in your *** configuration:
ini[General] http-api = 127.0.0.1:9091 http-api-tls = false http-api-web-dashboard = true
Or configure via ***'s graphical interface:
Settings → General → HTTP Remote API90912. Add *** Backend in Neko Master
Surge192.168.1.1 or 127.0.0.1)9091)💡 Note: *** uses HTTP polling to fetch data (compared to ***'s WebSocket real-time stream), with a data refresh delay of approximately 2 seconds.
If you see "port already in use" error, here are the solutions:
Create a .env file in the same directory as docker-compose.yml:
envWEB_EXTERNAL_PORT=8080 # Change Web UI port API_EXTERNAL_PORT=8081 # Change API port WS_EXTERNAL_PORT=8082 # Change WebSocket external port (only for direct access) COOKIE_SECRET=your-long-random-secret # Strongly recommended to keep fixed
Then restart:
bashdocker compose down docker compose up -d
Now access http://localhost:8080
yamlports: - "8080:3000" # External 8080 → Internal 3000 - "8082:3002" # External 8082 → Internal 3002 (for proxy/tunnel WS forwarding)
Note: if you use direct WS access (no reverse proxy) and external WS port is not
3002, setWS_EXTERNAL_PORT=<external-ws-port>.
bashcurl -fsSL https://raw.githubusercontent.com/foru17/neko-master/main/setup.sh | bash
The script will automatically detect and suggest available ports.
| Port | Purpose | External Required | Description |
|---|---|---|---|
| 3000 | Web UI | ✅ | Frontend entry point |
| 3001 | API | Optional | Frontend uses same-origin /api by default; usually no public exposure needed (default Compose maps it) |
| 3002 | WebSocket | Optional | Real-time push endpoint; recommended for reverse proxy/tunnel forwarding only (default Compose maps it) |
| Variable | Default | Purpose | When to set |
|---|---|---|---|
WEB_PORT | 3000 | Web listen port (inside container) | Usually unchanged |
API_PORT | 3001 | API listen port (inside container) | Usually unchanged |
COLLECTOR_WS_PORT | 3002 | WS listen port (inside container) | Usually unchanged |
DB_PATH | /app/data/stats.db | SQLite data path | Custom data path |
WEB_EXTERNAL_PORT | 3000 | External web port mapping in docker-compose.yml | External web port changed |
API_EXTERNAL_PORT | 3001 | External API port mapping in docker-compose.yml | Direct external API access needed |
WS_EXTERNAL_PORT | 3002 | External WS port mapping in docker-compose.yml; also used for direct WS port inference | Direct WS access without proxy and external WS port changed |
NEXT_PUBLIC_API_URL | empty | Override frontend API base URL (e.g. https://api.example.com) | API is not same-origin /api |
NEXT_PUBLIC_WS_URL | empty | Override frontend WS URL (absolute URL or /custom_ws) | Custom WS path/domain |
NEXT_PUBLIC_WS_PORT | 3002 | WS direct-connection fallback port (build-time only — setting this at Docker runtime has no effect; use WS_EXTERNAL_PORT instead) | Only for custom source builds |
API_URL | http://localhost:3001 | Next.js /api rewrite target (mainly source/custom builds) | API listen address changed |
COOKIE_SECRET | auto-generated | Cookie signing secret; if not fixed, sessions can be invalidated after restart when data dir is not persisted | Strongly recommended in production |
GEOIP_LOOKUP_PROVIDER | online | IP geolocation source (online / local) | Default to local MMDB lookup |
GEOIP_ONLINE_API_URL | https://api.ipinfo.es/ipinfo | Online IP geolocation API endpoint (must be compatible with ipinfo.my response schema) | Set only when you deploy a compatible endpoint |
FORCE_ACCESS_CONTROL_OFF | false | Force disable access control (emergency recovery) | Temporary use only when token is lost |
SHOWCASE_SITE_MODE | false | Read-only showcase mode (blocks sensitive write operations) | Public demo sites only |
| Variable | Default | Description |
|---|---|---|
FLUSH_INTERVAL_MS | 30000 | Buffer flush interval for collector writes |
FLUSH_MAX_BUFFER_SIZE | 5000 | Max buffer entries before early flush |
REALTIME_MAX_MINUTES | 180 | Realtime in-memory window size (minutes) |
REALTIME_RANGE_END_TOLERANCE_MS | 120000 | End-time tolerance for range queries |
SURGE_POLICY_SYNC_INTERVAL_MS | 600000 | *** policy sync interval |
DB_RANGE_QUERY_CACHE_TTL_MS | 8000 | Range-query cache TTL |
DB_HISTORICAL_QUERY_CACHE_TTL_MS | 300000 | Historical-query cache TTL |
DB_RANGE_QUERY_CACHE_MAX_ENTRIES | 1024 | Max range-query cache entries |
DB_RANGE_QUERY_CACHE_DISABLED | empty | Set 1 to disable range-query cache |
DEBUG_SURGE | false | Enable *** collector debug logs (true) |
runtime-config.API_URL → NEXT_PUBLIC_API_URL → same-origin /api/api server-side rewrite target: API_URL (default http://localhost:3001, applied in Next.js rewrites)runtime-config.WS_URL → NEXT_PUBLIC_WS_URL → auto candidates (when runtime-config.WS_PORT is set, direct port is preferred; otherwise /_cm_ws is tried first)runtime-config.WS_PORT (from WS_EXTERNAL_PORT) → NEXT_PUBLIC_WS_PORT → 3002NEXT_PUBLIC_WS_URL is usually unnecessary unless you use a custom WS path/domainenvNODE_ENV=production DB_PATH=/app/data/stats.db COOKIE_SECRET=<at least 32-byte random string> # Optional: default to local MMDB lookup # GEOIP_LOOKUP_PROVIDER=local # Keep false in normal operation # FORCE_ACCESS_CONTROL_OFF=false
Use openssl rand -hex 32 to generate COOKIE_SECRET.
Additional recommendations:
./data:/app/data) to avoid data and secret loss.3002, set WS_EXTERNAL_PORT accordingly.API_URL as well../geoip:/app/data/geoip:ro and switch source in Settings -> Preferences -> IP Lookup Source../geoip with fixed names:
GeoLite2-City.mmdb, GeoLite2-ASN.mmdb (required), and GeoLite2-Country.mmdb (optional).
Recommended source: https://github.com/P3TERX/GeoLite.mmdb.Advanced Agent details (install, config, release, compatibility) are maintained under
docs/agent/*.
SQLite is Neko Master's default storage engine and works well for most users. *** enabling ClickHouse if you need:
ClickHouse is entirely optional. SQLite remains as the configuration and metadata store regardless of whether ClickHouse is enabled.
When ClickHouse is enabled, the system enters dual-write mode:
BatchBuffer.flush() │ ├──→ SQLite (config / metadata, always written) └──→ ClickHouse (stats traffic data, dual-write) └── Buffer tables → SummingMergeTree async merge
Read source is controlled by STATS_QUERY_SOURCE (default: sqlite).
Step 1: Start the ClickHouse container
The repository's built-in docker-compose.yml already includes a ClickHouse service, gated by
profiles: [clickhouse] so it does not start by default. From the repository root, run:
bashdocker compose --profile clickhouse up -d
ClickHouse data is persisted to
./data/clickhouse, separate from the main app data directory.
If you use a custom docker-compose.yml (such as Scenario A/B above), add the ClickHouse
service block manually:
yamlservices: neko-master: # ... your existing config ... environment: # append to existing environment section: - CH_ENABLED=${CH_ENABLED:-0} - CH_HOST=${CH_HOST:-clickhouse} - CH_PORT=${CH_PORT:-8123} - CH_DATABASE=${CH_DATABASE:-neko_master} - CH_USER=${CH_USER:-neko} - CH_PASSWORD=${CH_PASSWORD:-neko_master} - CH_WRITE_ENABLED=${CH_WRITE_ENABLED:-0} - STATS_QUERY_SOURCE=${STATS_QUERY_SOURCE:-sqlite} networks: - neko-master-network clickhouse: image: clickhouse/clickhouse-server:24.8 container_name: neko-master-clickhouse restart: unless-stopped profiles: ["clickhouse"] ports: - "${CH_EXTERNAL_HTTP_PORT:-8123}:8123" - "${CH_EXTERNAL_NATIVE_PORT:-9000}:9000" volumes: - ./data/clickhouse:/var/lib/clickhouse environment: - CLICKHOUSE_DB=${CH_DATABASE:-neko_master} - CLICKHOUSE_USER=${CH_USER:-neko} - CLICKHOUSE_PASSWORD=${CH_PASSWORD:-neko_master} - CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 networks: - neko-master-network healthcheck: test: ["CMD-SHELL", "wget -q --spider http://127.0.0.1:8123/ping || exit 1"] interval: 30s timeout: 10s retries: 3 start_period: 40s networks: neko-master-network: driver: bridge
Step 2: Configure environment variables
Add to your .env (same directory as docker-compose.yml):
env# Enable ClickHouse connection CH_ENABLED=1 # Enable dual-write CH_WRITE_ENABLED=1 # Read source: sqlite (default) / auto (smart routing) / clickhouse (force) STATS_QUERY_SOURCE=auto # ClickHouse connection (defaults match docker-compose.yml, no change needed) CH_HOST=clickhouse CH_PORT=8123 CH_DATABASE=neko_master CH_USER=neko CH_PASSWORD=neko_master
Restart:
bashdocker compose --profile clickhouse up -d
| Variable | Default | Description |
|---|---|---|
CH_ENABLED | 0 | Enable ClickHouse connection (1 to enable) |
CH_WRITE_ENABLED | 0 | Enable dual-write (requires CH_ENABLED=1) |
CH_ONLY_MODE | 0 | When CH is healthy, skip SQLite stats writes (CH-only mode) |
CH_HOST | clickhouse | ClickHouse host address |
CH_PORT | 8123 | ClickHouse HTTP port |
CH_DATABASE | neko_master | Database name |
CH_USER | neko | Username |
CH_PASSWORD | neko_master | Password |
CH_SECURE | 0 | Use HTTPS connection |
CH_REQUIRED | 0 | Refuse to start if CH is unavailable |
CH_AUTO_CREATE_TABLES | 1 | Auto-create tables on first start |
CH_WRITE_MAX_PENDING_BATCHES | 200 | Max pending write batches |
CH_UNHEALTHY_THRESHOLD | 5 | Consecutive failures before marking unhealthy (auto-fallback to SQLite) |
STATS_QUERY_SOURCE | sqlite | Read source: sqlite / auto / clickhouse |
CH_COMPARE_ENABLED | 0 | Enable SQLite ↔ ClickHouse consistency check |
CH_EXTERNAL_HTTP_PORT | 8123 | ClickHouse HTTP external port (Compose mapping) |
CH_EXTERNAL_NATIVE_PORT |
您可以使用以下命令拉取该镜像。请将 <标签> 替换为具体的标签版本。如需查看所有可用标签版本,请访问 标签列表页面。
来自真实用户的反馈,见证轩辕镜像的优质服务