diff --git a/Dockerfile b/Dockerfile index 97e1233..0434c5f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -39,6 +39,7 @@ RUN apk add --no-cache ca-certificates \ && addgroup -S -g 10001 nodeflare \ && adduser -S -D -H -u 10001 -G nodeflare -s /sbin/nologin nodeflare \ && mkdir -p /etc/nodeflare \ + && chmod 700 /etc/nodeflare \ && chown nodeflare:nodeflare /etc/nodeflare COPY --from=backend /usr/local/bin/nodeflare /usr/local/bin/nodeflare COPY --from=frontend /build/frontend/dist/ /opt/nodeflare/share/frontend/ diff --git a/README.md b/README.md index d49546f..9de3c95 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,11 @@ NodeFlare 是一款轻量级、可自托管的服务器监控面板:通过 Web ## 界面预览 -![公开看板](docs/frontend.png) +**公开看板** · [在线演示](https://elysia62.github.io/NodeFlareWiki/demo/) + +[![公开看板](docs/frontend.png)](https://elysia62.github.io/NodeFlareWiki/demo/) + +**管理后台** ![管理后台](docs/backend.png) @@ -30,7 +34,7 @@ NodeFlare 是一款轻量级、可自托管的服务器监控面板:通过 Web ## 快速开始 -安装服务端(自动下载最新 Release 并注册系统服务)。 +安装服务端(自动下载最新 Release 并注册系统服务): Linux / macOS: @@ -68,15 +72,24 @@ curl -fsSL https://raw.githubusercontent.com/elysia62/NodeFlare/main/agent/agent ## Docker 部署 -镜像:[`gxmandppx/nodeflare`](https://hub.docker.com/r/gxmandppx/nodeflare),支持 amd64 / arm64。两种方式均需先按[配置示例](docker/config.example.toml)准备 `./data/config.toml`,并确保 `./data` 及配置文件可由容器用户 `10001:10001` 读写。 +使用 Docker 或 Docker Compose 部署 NodeFlare。镜像 [`gxmandppx/nodeflare`](https://hub.docker.com/r/gxmandppx/nodeflare) 支持 amd64 / arm64,配置和数据保存在宿主机的 `/etc/nodeflare`。 + +首次启动前,准备配置文件并为容器设置数据目录的读写权限: + +```bash +sudo mkdir -p /etc/nodeflare +sudo curl -fsSL https://raw.githubusercontent.com/elysia62/NodeFlare/main/docker/config.example.toml -o /etc/nodeflare/config.toml +# 编辑 /etc/nodeflare/config.toml,填好管理员账号密码 +sudo chown -R 10001:10001 /etc/nodeflare +``` Docker: ```bash docker run -d --name nodeflare \ --restart unless-stopped \ - -p 127.0.0.1:2206:2206 \ - -v "$PWD/data:/etc/nodeflare" \ + -p 2206:2206 \ + -v /etc/nodeflare:/etc/nodeflare \ gxmandppx/nodeflare:latest ``` @@ -89,28 +102,32 @@ services: container_name: nodeflare restart: unless-stopped ports: - - "127.0.0.1:2206:2206" + - "2206:2206" volumes: - - ./data:/etc/nodeflare + - /etc/nodeflare:/etc/nodeflare ``` ```bash docker compose up -d ``` +启动后访问 `http://<服务器地址>:2206/admin/login`。面板自身不提供 HTTPS,对外网提供服务时建议只发布到本机(`-p 127.0.0.1:2206:2206`)并配合 HTTPS 反向代理;升级、日志与卸载见 [Docker 部署](https://elysia62.github.io/NodeFlareWiki/guide/docker.html)。 + ## 文档 | 文档 | 说明 | | --- | --- | | [安装服务端](https://elysia62.github.io/NodeFlareWiki/guide/quick-start.html) | 一键安装、首次初始化、脚本参数与更新 | +| [Docker 部署](https://elysia62.github.io/NodeFlareWiki/guide/docker.html) | 官方镜像、Compose 部署与数据持久化 | | [安装 Agent](https://elysia62.github.io/NodeFlareWiki/guide/agent.html) | 各平台安装脚本与参数 | +| [平台支持与默认目录](https://elysia62.github.io/NodeFlareWiki/guide/platforms.html) | 支持的系统与架构、默认目录与日志位置 | | [卸载](https://elysia62.github.io/NodeFlareWiki/guide/uninstall.html) | 服务端与 Agent 的卸载及数据清理 | | [配置](https://elysia62.github.io/NodeFlareWiki/guide/config.html) | 配置项说明与完整示例 | | [反向代理](https://elysia62.github.io/NodeFlareWiki/guide/proxy.html) | nginx / Caddy 配置与 trusted_proxies | | [数据库与备份](https://elysia62.github.io/NodeFlareWiki/guide/database.html) | 备份恢复、SQLite ↔ PostgreSQL 在线迁移 | | [监控口径与采样](https://elysia62.github.io/NodeFlareWiki/guide/monitoring.html) | 采样频率与内存统计口径 | | [告警与通知](https://elysia62.github.io/NodeFlareWiki/guide/alerts.html) | 阈值、离线、到期、流量告警 | -| [主题定制](https://elysia62.github.io/NodeFlareWiki/guide/themes.html) | 主题商店与主题参数 | +| [主题开发](https://elysia62.github.io/NodeFlareWiki/guide/themes.html) | 主题包结构、设置表单与数据接口 | | [常见问题](https://elysia62.github.io/NodeFlareWiki/faq.html) | 排障与 FAQ | | [开发指南](https://elysia62.github.io/NodeFlareWiki/dev/develop.html) | 本地开发、测试与构建 | diff --git a/docker/config.example.toml b/docker/config.example.toml index 54a2034..bb50347 100644 --- a/docker/config.example.toml +++ b/docker/config.example.toml @@ -1,4 +1,4 @@ -# Copy to data/config.toml and set the initial administrator credentials. +# Save as /etc/nodeflare/config.toml and set the initial administrator credentials. database_url = "sqlite://nodeflare.db" bind_addr = "0.0.0.0:2206" admin_username = "admin" diff --git a/docs/README.en.md b/docs/README.en.md index c45334c..de0038f 100644 --- a/docs/README.en.md +++ b/docs/README.en.md @@ -15,7 +15,11 @@ NodeFlare is a lightweight, self-hosted server monitoring panel: view server sta ## Screenshots -![Public dashboard](frontend.png) +**Public dashboard** · [Live Demo](https://elysia62.github.io/NodeFlareWiki/demo/) + +[![Public dashboard](frontend.png)](https://elysia62.github.io/NodeFlareWiki/demo/) + +**Admin panel** ![Admin panel](backend.png) @@ -30,7 +34,7 @@ NodeFlare is a lightweight, self-hosted server monitoring panel: view server sta ## Quick Start -Install the server (downloads the latest release and registers a system service automatically). +Install the server (downloads the latest release and registers a system service automatically): Linux / macOS: @@ -68,15 +72,24 @@ Updating: re-run the install script. Config and data are preserved and a failed ## Docker Deployment -Image: [`gxmandppx/nodeflare`](https://hub.docker.com/r/gxmandppx/nodeflare), available for amd64 / arm64. Both options require `./data/config.toml` based on the [example configuration](../docker/config.example.toml), with `./data` and the configuration file writable by container user `10001:10001`. +Deploy NodeFlare with Docker or Docker Compose. The [`gxmandppx/nodeflare`](https://hub.docker.com/r/gxmandppx/nodeflare) image supports amd64 / arm64 and stores configuration and data in `/etc/nodeflare` on the host. + +Before the first start, prepare the configuration file and allow the container to write to the data directory: + +```bash +sudo mkdir -p /etc/nodeflare +sudo curl -fsSL https://raw.githubusercontent.com/elysia62/NodeFlare/main/docker/config.example.toml -o /etc/nodeflare/config.toml +# Edit /etc/nodeflare/config.toml and set the administrator username and password +sudo chown -R 10001:10001 /etc/nodeflare +``` Docker: ```bash docker run -d --name nodeflare \ --restart unless-stopped \ - -p 127.0.0.1:2206:2206 \ - -v "$PWD/data:/etc/nodeflare" \ + -p 2206:2206 \ + -v /etc/nodeflare:/etc/nodeflare \ gxmandppx/nodeflare:latest ``` @@ -89,21 +102,25 @@ services: container_name: nodeflare restart: unless-stopped ports: - - "127.0.0.1:2206:2206" + - "2206:2206" volumes: - - ./data:/etc/nodeflare + - /etc/nodeflare:/etc/nodeflare ``` ```bash docker compose up -d ``` +Then open `http://:2206/admin/login`. The panel does not serve HTTPS, so to expose it externally publish the port on loopback (`-p 127.0.0.1:2206:2206`) and put an HTTPS reverse proxy in front. Updates, logs, and uninstall: [Docker Deployment](https://elysia62.github.io/NodeFlareWiki/en/guide/docker.html). + ## Documentation | Document | Description | | --- | --- | | [Install the Server](https://elysia62.github.io/NodeFlareWiki/en/guide/quick-start.html) | One-line install, first-time setup, script options, updates | +| [Docker Deployment](https://elysia62.github.io/NodeFlareWiki/en/guide/docker.html) | Official image, Compose setup, and data persistence | | [Install the Agent](https://elysia62.github.io/NodeFlareWiki/en/guide/agent.html) | Per-platform scripts and options | +| [Platforms & Paths](https://elysia62.github.io/NodeFlareWiki/en/guide/platforms.html) | Supported systems and architectures, default paths and logs | | [Uninstall](https://elysia62.github.io/NodeFlareWiki/en/guide/uninstall.html) | Uninstalling the server and agent, data cleanup | | [Configuration](https://elysia62.github.io/NodeFlareWiki/en/guide/config.html) | Config options and a full example | | [Reverse Proxy](https://elysia62.github.io/NodeFlareWiki/en/guide/proxy.html) | nginx / Caddy setup and trusted_proxies | diff --git a/frontend/src/components/NodeCard.tsx b/frontend/src/components/NodeCard.tsx index 1af8dab..4301864 100644 --- a/frontend/src/components/NodeCard.tsx +++ b/frontend/src/components/NodeCard.tsx @@ -32,7 +32,7 @@ const USAGE_TEXT_TONE: Record = { good: "", warning: "warning function Metric({ label, value, used, sub, muted = false }: { label: string; value: string; used: number; sub: string; muted?: boolean }) { return (
-
{label}{value}
+
{label}{value}
{sub}
diff --git a/frontend/src/styles/dashboard.css b/frontend/src/styles/dashboard.css index 8fbe808..73db909 100644 --- a/frontend/src/styles/dashboard.css +++ b/frontend/src/styles/dashboard.css @@ -72,8 +72,9 @@ .metric.muted { opacity: .55; } /* 固定行高:CJK 回退字体的 normal 行高大于拉丁文本,浮动行高会把进度条与下一行顶偏 */ .metric > div { display: flex; min-width: 0; align-items: center; justify-content: space-between; gap: 8px; font-size: 13px; line-height: 16px; white-space: nowrap; } +.metric > div > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; } .metric span, .metric small { color: var(--muted-foreground); } -.metric strong { font-weight: 500; font-variant-numeric: tabular-nums; } +.metric strong { flex: 0 0 auto; font-weight: 500; font-variant-numeric: tabular-nums; } .metric small { overflow: hidden; font-size: 12px; font-variant-numeric: tabular-nums; text-overflow: ellipsis; white-space: nowrap; line-height: 14px; } .progress-track { display: block; width: 100%; height: 4px; overflow: hidden; border-radius: 2px; background: color-mix(in srgb, var(--foreground) 9%, transparent); } .progress-fill { display: block; height: 100%; border-radius: 2px; transition: width 300ms ease; }