A lightweight multi-server monitoring dashboard built on Cloudflare Workers, D1, and Durable Objects.
Live Demo · API Reference · Go Agent Guide · Theme Development
CF-Server-Monitor is a server monitoring system designed for Cloudflare Workers. Each server runs an Agent that reports metrics to a Worker. The Worker stores data in D1 and pushes realtime updates through Durable Objects and WebSocket, providing free-hosted, low-maintenance realtime monitoring.
It supports mainstream Linux distributions, Alpine Linux, OpenWrt, macOS, Synology DSM, Feiniu fnOS, Windows, and similar systems, and provides Docker image deployment.
Security is stricter by design: the Agent only reports metrics one way, does not provide WebSSH, remote command delivery, or a controller channel, and can run as a non-root user to reduce blast radius.
- Why CF-Server-Monitor
- Features
- Architecture
- Version Notes
- Quick Deployment
- First Use
- Agent Parameters and Security
- Configuration
- Notifications and Alerts
- Security Notes
- Themes and Appearance
- Upgrade and Maintenance
- Local Development
- Project Structure
- FAQ
- Screenshots
- Support
Compared with traditional controller-style monitoring tools, CF-Server-Monitor is designed for low cost, low maintenance, and security-first operation:
- Free hosting: the dashboard, API, database, and realtime push run on Cloudflare and are designed around free-tier limits; the default 60-second reporting interval supports roughly 60 servers, and changing it to 120 seconds can theoretically double that capacity.
- Safer one-way reporting: no WebSSH, no remote command delivery, and no controller channel; the Agent only reports metrics to the Worker.
- Practical feature coverage: realtime metrics, history charts, maps, offline notifications, resource alerts, expiration reminders, theme store, multi-language UI, and mobile support are built in.
- Dynamic Agent config delivery: ping nodes, collect interval, report interval, network interfaces, traffic reset day, upload/download traffic correction, and similar parameters can be changed from the admin panel and picked up by the Agent later; Worker URL,
API_SECRET, and the auto-update switch require running the install command again. - Non-root installation: Linux systems with
systemd --usercan run the Agent as a regular user, with files stored under~/.cf-probe/. - Clock-tolerant reporting: the Go Agent uses the Worker's HTTP
Dateresponse header to calibrate sample timestamps andboot_time, reducing the impact of wrong local server time on history charts; it does not change the system clock.
| Area | Capabilities |
|---|---|
| Realtime monitoring | CPU, GPU, memory, swap, disk, disk IO, network, connections, process count, load average, uptime |
| History | 7-day charts, long-range sampling, realtime network speed, monthly traffic and correction |
| Network quality | Latency and packet loss tracking for CT, CU, CM, and BGP nodes; when three-net details are enabled, the dashboard samples up to 20 real points from the last 2 hours of D1 history and caches them for 5 minutes |
| Dashboard views | Bar chart, ring chart, table, and map views for desktop and mobile |
| Admin panel | Server CRUD, drag sorting, hidden servers, import/export, batch delete, database maintenance |
| Cross-platform Agent | Mainstream Linux, Alpine Linux, OpenWrt, Synology DSM, Feiniu fnOS, FreeBSD, macOS, Windows, plus Docker image deployment; Go Agent by default, Shell/PowerShell still available |
| Realtime push | Durable Objects + WebSocket refresh the UI immediately after Agent reports |
| Alerts | Offline alerts, recovery notices, expiration reminders, resource load rules |
| Multi-language | Built-in Chinese and English frontend switch; Chinese and English documentation |
| Multi-site | GitHub Pages static frontend and aggregation of multiple Worker APIs |
| Widget | iOS Scriptable widget script for quick mobile status checks |
| Security | API Secret, admin password, JWT, Turnstile, CORS, CSP allowlists |
| Theme ecosystem | Built-in theme, Mikus mode, theme store, third-party theme proxy and preview |
| Cloudflare-friendly | Monthly table rotation, sampled history queries, caching, and rate controls for free-tier usage |
flowchart LR
Agent["Server Agent<br/>Go / Shell / PowerShell"] -->|"POST /update"| Worker["Cloudflare Worker"]
Worker --> D1["Cloudflare D1<br/>servers / settings / history"]
Worker <--> DO["Durable Object<br/>WebSocket broadcast"]
Worker --> Assets["Vue Dashboard<br/>Admin Panel"]
Browser["Browser / Mobile / Widget"] <--> Worker
Core flow:
- Add a server in the admin panel and copy the install command.
- Install the Agent on the target server.
- The Agent reports metrics to the Worker at the configured interval.
- The Worker verifies
API_SECRET, writes to D1, and broadcasts realtime data through Durable Objects. - The dashboard, server detail page, admin panel, and iOS widget read from the same API.
Recent changes:
2.8.6: Added GitHub login, WSS frontend subscription with 250ms batch reporting, added SMTP notification channel, added monthly traffic threshold alert, removed legacy database compatibility, added Docker installation method.2.8.5: Added custom Ping node names, ICMP mode, optimized WSS response logic, API interface optimization, and optimized frontend. Also added 4 default Ping nodes.2.8.4: Added Agent WSS reporting and active hours. Agents use POST outside selected hours to reduce Do duration, and this requires Agentv1.0.10+. Also added account Do usage display with optimized Do broadcast requests when no frontend subscription exists to reduce idle quota consumption, added custom Webhook channel in notification settings, and added frontend WSS timeout configuration.2.8.3: Added disk IO metrics, switched the default Agent to Go, and added realtime latency / packet-loss windows.2.8.2: Added Go Agent support.2.8.1: Optimized long-range D1 history reads, added resource load notifications, and improved the theme store API.2.8.0: Added the theme store and one-click third-party theme switching.2.7.x: Refactored database writes, monthly table rotation, notifications, security policy, billing fields, import/export, and admin workflows.
For the full Go Agent changelog, see cfsm-agent releases.
- Cloudflare account
- GitHub account
- A strong
API_SECRET, used as the Agent reporting secret and the initial admin password
The recommended deployment paths are Cloudflare Workers connected to GitHub, or GitHub Actions. One-click deploy is useful for trials, but it is less convenient for long-term updates.
Recommended for users who want Cloudflare to build and redeploy the project from a GitHub fork.
- Fork this repository.
- Open Cloudflare Dashboard and go to Workers & Pages.
- Create a Worker and import this repository from GitHub.
- Set the build command to
npm run build:frontend. - Use
npx wrangler deployas the deploy command. - After deployment, add
API_SECRETin the Worker's Variables and Secrets.
Chinese visual guide: https://huilang.me/cf-server-monitor-setup/
Recommended if you want GitHub Actions to own the full deployment workflow.
- Fork this repository.
- Create a Cloudflare D1 database, preferably named
server-monitor-db. - Copy your Cloudflare Account ID.
- Create a Cloudflare API Token with the required Workers and D1 deployment permissions.
- In your forked repository, open Settings -> Secrets and variables -> Actions.
- Add the following repository secrets.
| Secret | Required | Description |
|---|---|---|
CF_API_TOKEN |
Yes | Cloudflare API Token |
CF_ACCOUNT_ID |
Yes | Cloudflare Account ID |
D1_DATABASE_ID |
Yes | D1 database ID |
API_SECRET |
Yes | Agent reporting secret and initial admin password |
CORS_ALLOWED_ORIGINS |
No | Allowed API origins, comma-separated |
Pushing to main triggers deployment. You can also manually run the Deploy to Cloudflare Workers workflow from the Actions tab.
Before deploying:
- Use
npm run build:frontendas the build command. - Replace the default
API_SECRETwith a random strong value. - Change the admin username and password after the first login.
For long-term use, migrating to Option 1 or Option 2 is recommended.
After deployment, open:
https://your-worker-domain/admin#/admin
Default credentials:
| Item | Default |
|---|---|
| Username | admin |
| Password | API_SECRET |
Change the admin username and password after login. The admin password can be separated from API_SECRET; Agent reporting still uses the Cloudflare API_SECRET environment variable.
- Open
/admin#/admin. - Enter a server name.
- Add the server.
- Click the copy button, choose the target system and Agent version.
- Run the generated command on the target server.
Prefer the command generated by the admin panel because it includes the server ID, Worker URL, Secret, reporting interval, network quality nodes, and network interface settings.
Starting from V2.8.3, the default Agent is the standalone cfsm-agent. The installed service name is cf-probe. After adding a server, copy the install command from the admin panel; it generates the full command for the target system, server ID, Worker URL, and current parameters.
See cfsm-agent for full install paths, logs, status checks, and upgrade behavior.
| Parameter | Description | Default |
|---|---|---|
-id |
Unique server ID | Required |
-secret |
Agent reporting secret; must match API_SECRET |
Required |
-url |
Worker reporting URL | Required |
-collect_interval |
Local collection interval; 0 disables extra sampling |
0 |
-interval |
Reporting interval in seconds | 60 |
-ct / -cu / -cm / -bd |
Custom network quality test nodes, supports host[:port] |
Built-in nodes |
-reset_day |
Monthly traffic reset day | 1 |
-rx_correction |
Download traffic correction in GB | Empty |
-tx_correction |
Upload traffic correction in GB | Empty |
-collect_interval controls local sampling. -interval controls reporting frequency. Shorter intervals increase Workers requests and D1 writes.
Non-root installation is recommended on Linux systems that support systemd --user. The admin install command offers “Current user” and “Dedicated cfsm user”: the first runs directly as the invoking user, while the second creates and switches to cfsm. Files are stored in that user's ~/.cf-probe/.
For a regular user service to keep running after logout, run this as root:
loginctl enable-linger usernameWhen uninstalling, select the user that originally installed the Agent. For OpenWrt, Alpine/OpenRC, Synology DSM, and other systems without systemd --user, use the matching system command.
The admin copy-install dialog lets you choose Docker as the target system, generating a container command like the one below (server ID, secret, and Worker URL are filled in automatically for the current server; the image tag defaults to latest and can be customized in the Agent version field):
docker run -d --name cf-probe --restart=unless-stopped --network=host \
-v cf-probe-data:/data \
-e SERVER_ID=<server-id> -e SECRET='<API_SECRET>' -e WORKER_URL=https://<your-worker>/update \
ghcr.io/huilang-me/cfsm-agent:latestCollect interval, report interval, ping nodes, network interface, traffic reset day, and upload/download correction are pulled dynamically by the Agent from the admin panel via SERVER_ID, so they do not need to be repeated in the command; changing the image tag upgrades or rolls back to that version. To remove the container:
docker rm -f cf-probe && docker volume rm cf-probe-data| Variable | Required | Description |
|---|---|---|
API_SECRET |
Yes | Agent reporting secret and initial admin password |
API_BASE |
No | Worker API base URLs for frontend requests, comma-separated; useful for multi-Worker aggregation or separated frontend/backend deployments |
CORS_ALLOWED_ORIGINS |
No | Allowed API origins, comma-separated |
The project can build a static frontend for GitHub Pages and connect it to one or more remote Worker APIs. The workflow is .github/workflows/deploy-github-page.yml.
| Secret | Description |
|---|---|
API_BASE |
Worker API base URLs, comma-separated |
TITLE |
Static frontend title |
BACKGROUND_IMAGE |
Background image URL |
CSP_STATIC |
Extra CSP allowlist for static resources |
CSP_API |
Extra CSP allowlist for API / WebSocket endpoints |
Build command:
npm run build:github-page| Category | Main options |
|---|---|
| Site | Title, background, favicon, default display mode, default appearance, default language, three-net details, public access |
| Server | HTTP/WSS report intervals, collect interval, ping nodes, network interfaces, monthly traffic, price, expiration, auto-renew |
| Security | Admin account, password, JWT Secret, Turnstile |
| Notifications | Offline alerts, expiration reminders, resource alerts, test notification |
| Appearance | Custom CSS, custom <head>, CSP allowlists, Mikus mode |
| Database | Upgrade database, clear history |
| Cloudflare usage | Query D1 row reads/writes and Workers requests |
The project includes scripts/ios-scriptable-widget.js, which can show a single server on the iPhone home screen.
Usage:
- Install Scriptable on iPhone.
- Create a new script and paste the contents of
scripts/ios-scriptable-widget.js. - Set
CONFIG.baseURLat the top of the script to your site URL. - Add a Scriptable widget and select the script.
- Put the server ID in the widget Parameter field, or use
id:SERVER_ID.
The widget shows online status, CPU, memory, disk, monthly traffic, realtime upload/download speed, and update time. The actual refresh interval is controlled by iOS.
Configure notifications in Admin -> Global Settings -> Notifications. Notification delivery has three channel modes: built-in channels, SMTP email, and custom Webhook. When custom Webhook is selected, the backend sends only the Webhook request and does not call the built-in channel.
Built-in channels are detected from the Bot Token format.
| Platform | Bot Token format | Chat ID |
|---|---|---|
| Telegram | BotFather Bot Token | User, group, or channel ID |
| WeCom | Group robot Webhook URL | Empty |
| Feishu | Group robot Webhook URL | Empty |
| DingTalk | Custom robot Webhook URL | Empty |
| OneBot / QQ | onebot:http://host/send_private_msg?... or send_group_msg |
User ID or group ID |
| Bark | https://api.day.app/xxxx/ or bark:https://example.com/xxxx/ |
Empty |
| ServerChan | https://sctapi.ftqq.com/<SendKey>.send or server:https://example.com/s/<SendKey>.send |
Empty |
| WxPusher | https://wxpusher.zjiecode.com/api/send/message/[SPT_xxx]/Hello |
Empty |
| Gotify | https://gotify.example.com/message?token=xxx |
Empty |
When the SMTP email channel is selected, fill in the SMTP host, port, encryption, username, password, sender and recipients in the settings panel — no manual string assembly needed. The backend serializes them into the tg_bot_token field using the smtp:// prefix protocol and sends plain-text email directly via cloudflare-smtp (built on cloudflare:sockets).
Config format (generated by the frontend; also usable when typing the prefix protocol into the built-in Bot Token field):
smtp://<username>:<password>@<host>:<port>?from=<sender>&to=<rcpt1,rcpt2>&secure=<auto|tls|starttls>
Notes:
- Cloudflare Workers permanently blocks outbound port 25. Only
465(implicit TLS) and587(STARTTLS) work;secureis inferred from the port when omitted. - Special characters in username/password must be URL-encoded (e.g.
@as%40); the frontend form handles this automatically. - QQ / 163 mailboxes require an SMTP authorization code, not the login password. Sender defaults to the username when left empty.
- Only plain-text email is sent (no HTML, attachments or CC). Failed sends retry up to
NOTIFICATION_MAX_RETRIEStimes. - Deliverability also depends on the mail provider's checks of Cloudflare egress IPs and SPF / DKIM.
Custom Webhook supports GET and POST:
POST: supportsJSON,x-www-form-urlencoded, orText. The default JSON body contains onlytitleandcontent.GET: uses the same parameter editor and appends values to the URL query. Parameters may be written as a JSON object or as QueryString, for exampletitle={{emoji}} {{event}}&content={{notification}}.- Headers may be written as a JSON object or as multiline
Header: valuetext. - Test notification uses the current notification template before sending, so it can validate the final platform payload before saving.
Default Webhook parameters:
{
"title": "{{emoji}} {{event}}",
"content": "{{notification}}"
}Default notification template:
{{emoji}}【CF Server Monitor】{{event}}
{{message}}
{{time}}
Available template variables:
| Variable | Description |
|---|---|
{{emoji}} |
Event icon: recovery/test uses ✅, offline/alert uses ❌, expiration/mixed status uses ⚠️ |
{{event}} |
Event name, such as Offline Alert or Resource Recovery |
{{client}} / {{clients}} |
Server names in this notification, joined by comma for multiple servers |
{{count}} |
Number of affected servers; not shown by the default template, but available for custom templates |
{{message}} |
Detailed notification list |
{{time}} |
Send time formatted in the notification timezone |
{{notification}} |
Full content after applying the notification template, usually used as Webhook content |
{{title}} |
Fixed title 💌 Cloudflare Server Monitor |
Supported alert types:
- Offline alert: notify after a node stays offline for the configured delay; send recovery notice when it returns.
- Expiration reminder: notify daily 1 to 7 days before expiration at the configured notification timezone and expiration notification time, or disable it.
- Resource alert: define rules for CPU, memory, disk, inbound/outbound network speed, and similar metrics.
Send a test notification before saving.
- Use a random strong value and avoid characters that are likely to be escaped by shells or URLs.
- After changing
API_SECRET, redeploy the Worker and reinstall or update all Agents. - Keep the admin password separate from
API_SECRETfor long-term use.
Admin settings can configure the frontend WSS timeout in minutes. The default 0 disables time-based disconnects; a positive value closes the built-in frontend subscription at the limit and prompts the user to close or continue.
Cloudflare Turnstile can be enabled from the admin panel to reduce abuse of public APIs and login endpoints. In multi-site mode, use the same Site Key across sites when Turnstile is enabled.
Same-origin access is recommended by default. If you use an external static frontend or multi-site aggregation, add trusted origins to CORS_ALLOWED_ORIGINS.
- Create an OAuth App under GitHub
Settings → Developer settings → OAuth Apps. - Enter its Client ID and Client Secret under Admin Login Settings, then save the configuration.
- Copy the exact
Authorization callback URLshown by CFSM into the GitHub OAuth App. - While signed in with the admin password, click Bind GitHub Account and authorize it. CFSM stores the account's immutable numeric GitHub ID, and only that account can use GitHub login afterward.
The GitHub OAuth configuration and binding are stored in the existing D1 site_options JSON and do not require a schema upgrade. The Client Secret is not returned by the settings read API; leave it blank on later saves to preserve the stored value. Rebinding requires an authenticated admin session. Keep password login enabled as a recovery path.
The project enables a conservative Content Security Policy by default. Third-party backgrounds, external CSS/JS, fonts, images, and WebSocket/API origins must be added to the CSP allowlists in the admin panel before they can load.
Built-in sources include Cloudflare Turnstile, Cloudflare Analytics, Google Fonts, GitHub Raw, and several public APIs. Review third-party scripts before allowing them.
The project includes a built-in theme and supports:
- Dark / light display
- Chinese / English frontend switch
- Custom background, favicon, CSS, and
<head> - Mikus mode
- Theme store
- Third-party GitHub tree theme URLs
- Admin-only theme preview
Third-party themes only proxy index.html and assets/ from the theme repository. The admin panel always uses the built-in theme. See theme-develop.md for custom theme development.
If you deployed from a fork, sync the fork with upstream to trigger redeployment:
- Manual sync: click Sync fork -> Update branch in your GitHub repository.
- Automatic sync: enable the
Upstream Syncworkflow. It checks upstream updates daily at UTC 00:00.
For one-click deployment, redeploy to the same project or migrate to a fork-based deployment.
The Go Agent keeps existing configuration. Re-running the install command upgrades it.
Linux / OpenWrt / Synology DSM / FreeBSD / macOS:
curl -fsSL https://raw.githubusercontent.com/huilang-me/cfsm-agent/main/install.sh | sh -s -- installWindows administrator PowerShell:
$script = "$env:TEMP\install-cf-probe.ps1"
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/huilang-me/cfsm-agent/main/install.ps1" -OutFile $script -UseBasicParsing
PowerShell -ExecutionPolicy Bypass -File $script installGo Agent:
curl -fsSL https://raw.githubusercontent.com/huilang-me/cfsm-agent/main/install.sh | sh -s -- uninstallThe legacy Shell / PowerShell Agent is no longer maintained. The commands below are only for cleaning up historical Shell / PowerShell installations. Use the script that matches the system script used during the original install. If the current Agent is the Go Agent, use the Go uninstall command above.
| Legacy system script | Uninstall command |
|---|---|
| Linux / systemd | curl -sL https://your-worker-domain/install.sh | bash -s uninstall |
| Alpine / OpenRC | curl -sL https://your-worker-domain/install-alpine.sh | sh -s uninstall |
| OpenWrt / procd | curl -sL https://your-worker-domain/install-openwrt.sh | sh -s uninstall |
| macOS | curl -sL https://your-worker-domain/install-mac.sh | sudo bash -s uninstall |
| Synology DSM | curl -sL https://your-worker-domain/install-synology.sh | bash -s uninstall |
Legacy Windows PowerShell Agent:
irm https://your-worker-domain/cf-server-monitor.ps1 -OutFile cf-server-monitor.ps1
powershell -ExecutionPolicy Bypass -File .\cf-server-monitor.ps1 uninstallGo and legacy Shell / PowerShell uninstallers only remove the services and files they created. If you switched from Shell / PowerShell to Go, or the other way around, run the matching uninstaller for each version to avoid leftover services, scheduled tasks, or configuration files.
Admin -> Database Management provides:
- Upgrade database: add missing fields and indexes without deleting existing data.
- Clear history: delete monitoring history while keeping servers and site settings.
After upgrading from older versions to versions with GPU, disk IO, packet loss, or new history structures, run database upgrade first if the UI reports missing fields, then upgrade the Agent.
wrangler.toml includes two Cron triggers:
| Cron | Description |
|---|---|
*/1 * * * * |
Detect offline nodes/resource alerts every minute |
0 * * * * |
Run hourly combined tasks, including monthly table rotation, old table cleanup, and expiration checks at the configured notification timezone/hour |
- Node.js 18+
- npm
- Wrangler 4
# Install dependencies
npm install
# Create D1 database for the first time
npx wrangler d1 create server-monitor-db
# Start local Worker, default https://localhost:8787
npm run dev
# Start frontend-only Vite dev server, default http://localhost:5173
npm run dev:frontend
# Build frontend
npm run build:frontend
# Deploy to Cloudflare Workers
npm run deploy
# Test history queries
npm run test:history-query
# Test Agent config delivery
npm run test:agent-configLocal .env requires at least:
API_SECRET=123456node test/generate-sql.js
wrangler d1 execute server-monitor-db --file=test/mock-data.sqlSee test/README.md for more local testing notes.
https://localhost:8787/cdn-cgi/handler/scheduled?cron=*/1+*+*+*+* // Detect offline nodes/resource alerts every minute
https://localhost:8787/cdn-cgi/handler/scheduled?cron=0+*+*+*+* // Run hourly combined tasks
https://localhost:8787/cdn-cgi/handler/scheduled?cron=0+0+*+*+0 // Weekly maintenance tasks
https://localhost:8787/cdn-cgi/handler/scheduled?cron=0+12+*+*+* // Daily maintenance tasks (for testing)
node test/api-check.js
node test/api-check.js --base-url=http://localhost:8787 --api-secret=123456
node test/api-check.js --helpSee API.md for the complete API reference.
CF-Server-Monitor/
├── public/ # Install scripts, OS icons, flags, static assets
├── scripts/ # Build scripts, GitHub Pages build, iOS widget
├── src/
│ ├── database/ # D1 schema, indexes, migrations
│ ├── durable/ # Durable Object realtime broadcast
│ ├── frontend/ # Vue 3 dashboard and admin panel
│ ├── handlers/ # Worker route handlers
│ ├── middleware/ # Auth middleware
│ ├── services/ # Notification service
│ └── utils/ # Cache, CORS, CSP, metrics, version helpers
├── test/ # Local tests and mock data tools
├── API.md # REST / WebSocket API reference
├── theme-develop.md # Third-party theme development
├── wrangler.toml # Local Wrangler configuration
└── version.json # Worker / Agent versions
The Worker cannot read the environment variable. In Cloudflare Workers & Pages, open Variables and Secrets, remove any old API_SECRET, add it again, save, and wait for redeployment.
First make sure the server can reach the Worker URL. To enable debug logs, append -debug=1 to the install parameters. Log commands vary by system, so refer to the matching status and log instructions in the cfsm-agent documentation.
Remove the debug parameter and reinstall after troubleshooting to avoid excessive logs.
Update API_SECRET in Cloudflare, redeploy the Worker, then copy and run the install command again on every server. If you deploy through GitHub Actions, update the GitHub Secret as well.
Due to the current Cloudflare version issue, you may need to temporarily modify the value and save it once, then change it back to the original value and save again to trigger a new deployment.
The default 60-second reporting interval is designed for roughly 60+ servers. Increasing the interval to 120 seconds reduces writes further. Reads mainly come from frontend visits and history queries; caching, sampling, and login restrictions reduce usage. Always check the current Cloudflare dashboard for actual quota numbers.
This is usually caused by CSP blocking third-party image resources. Open Admin -> Appearance -> CSP Static Domains Whitelist and add the origin of the background image domain. For example, if the image URL is https://cdn.example.com/path/bg.webp, enter only https://cdn.example.com.
If the image URL redirects or goes through a CDN redirect, open the browser developer tools, check the final image URL that is actually loaded, and add that final domain to the allowlist. Save the settings and refresh the page.
Open the Cloudflare D1 database server-monitor-db, edit the setting table, and update the password field in site_options. The legacy MD5-compatible value e10adc3949ba59abbe56e057f20f883e maps to password 123456. Log in with it and set a strong password in the admin panel.
Binding a custom probe domain to the Worker is recommended. If needed, you can temporarily map the probe domain to a reachable Cloudflare CDN IP in hosts:
echo <CF_CDN_IP> <your-probe-domain> | sudo tee -a /etc/hostsCheck whether the server uses a proxy. On OpenWrt or router systems, some proxy plugins may affect latency tests. Disable the proxy or try another transparent proxy setup and test again.
The frontend may display Hong Kong, Macao, Taiwan, and country/region information side by side. The map follows the standard map reviewed by China's Ministry of Natural Resources, review number GS(2023)2767.
- API.md: REST API, WebSocket, auth, error codes, and data structures
- https://github.com/huilang-me/cfsm-agent: Go Agent configuration, upgrade, logs, and troubleshooting
- theme-develop.md: Third-party theme development
- test/README.md: Local mock data and testing workflow
- Telegram group: https://t.me/cfServerMonitor
- Live demo: https://demo.huilang.me/
If this project is helpful to you, you can support future maintenance through the options below.
- WeChat appreciation: scan the QR code
- CF-Server-Monitor-Pro
- Cloudflare Workers
- Vue 3
- Vite
- Chart.js
- Leaflet
- Thanks to the NodeSeek and LINUX DO communities for support and promotion
MIT License












