Installer UX improvements and servers page/card redesign#111
Conversation
Unify the binary install mode into a single base directory
(/opt/serverbee/{bin,etc,data}) to align with docker mode and
simplify management. Adds automatic in-place migration of existing
legacy FHS-split installs (/usr/local/bin, /etc/serverbee,
/var/lib/serverbee), rewriting server.toml and systemd units and
restarting running services.
Replace the case-based tr_text with maintainable per-language associative arrays (EN/ZH, 115 keys) with English fallback and a visible marker for missing keys. Localize the service and uninstall menus, all interactive confirmation prompts, the install/domain plan body, install result screens, and the status page; switch the docs link to the matching language. Diagnostic info/warn/error stay in English. Add a bash 4.0+ guard since i18n now uses associative arrays.
Resolve the latest release tag and display it in the binary URL, CLI script URL and docker image tag of the install/domain plan. Memoize get_latest_version so the plan and the subsequent install share a single GitHub API lookup.
The consolidated /opt layout moved server.toml to /opt/serverbee/etc, but the server binary only reads /etc/serverbee/server.toml, ./server.toml or SERVERBEE_* env. With WorkingDirectory=/opt/serverbee/data the config file was never read, so secure_cookie fell back to its default (true). Over plain HTTP the browser then dropped the Secure session cookie, making the forced onboarding request unauthenticated (401). Set the server unit (and legacy-migrated units) WorkingDirectory to the config dir so the relative server.toml resolves; data dir still comes from the absolute SERVERBEE_SERVER__DATA_DIR env.
Add the consolidated install layout's config path to the Figment chain so future binaries find the config without depending on the process working directory.
The snap-confined Docker daemon cannot bind-mount paths under /opt (its rootfs is read-only), so after the /opt layout consolidation the docker agent's config bind mount (/opt/serverbee/etc) failed and the container never started. Add a snap-aware docker config dir (/var/snap/docker/common/serverbee/etc under snap, CONFIG_DIR otherwise) and use it for docker server.toml/agent.toml, the agent bind mount, config/env/uninstall and plan/result output. Binary mode and non-snap Docker are unchanged.
install_cli always downloaded the release-tagged install.sh, so an installer carrying unreleased layout changes installed a mismatched CLI: serverbee status/config/env/uninstall then reported "no managed components" because the old-layout CLI looked under the legacy paths. Copy the running script when invoked as a file; fall back to the release download only when piped via stdin (curl | bash).
Instead of telling the user to run a command to dig the one-time password out of the logs, poll the server's startup logs (systemd journal or docker compose logs) after start and print the password directly, with a note that it must be changed on first login. Falls back to the previous "check the logs" hint when no password is found (re-install/adopt, or no captured log source).
…install The CLI is removed during uninstall and the script is often piped via stdin, so "re-run with --purge" was unactionable. Print the concrete rm/docker volume commands for the preserved config and data instead.
The Server URL prompt was empty with only a static example. Pre-fill it with http://<detected-local-ip>:9527 so single-machine and same-network setups can accept the default by pressing Enter.
Persist the interactively chosen language to a sidecar file in the config dir so subsequent runs (status, upgrade, uninstall) reuse it without re-prompting. A sidecar file is used instead of editing the hand-rolled meta JSON to avoid corrupting its fragile comma handling; it shares the meta-file's directory and uninstall lifecycle. Priority: --lang > SERVERBEE_LANG > cached > system locale > en. The cache is removed on full uninstall alongside the meta file.
serverbee upgrade previously only self-copied the running CLI, so it never picked up new installer logic. Add refresh_cli_from_release: it pulls the target release's deploy/install.sh, validates it (non-empty, bash -n, repo marker) and atomically replaces the CLI. Failures are non-fatal and the refresh runs at most once per upgrade run. The new CLI takes effect on the next serverbee invocation.
On a cold image pull the container starts and logs the credentials banner later than the previous 15s poll window, causing the installer to fall back to the manual "check logs" hint. Use a 45s budget for docker (15s unchanged for systemd); the loop still exits as soon as the password is found, so the warm-cache path stays fast.
Agents are installed far more often than the single server, so make Agent option [1] and Server option [2] in both the install and uninstall interactive menus (kept consistent to avoid the number meaning different things between the two menus).
Add a "Correcting a Wrong Enrollment Code" subsection (EN + CN) under the registration flow: how to fix a mistyped enrollment code or server_url via serverbee config set / reinstall, and clarify that the code is irrelevant once a token exists.
The shared DataTable applies table-fixed, but ui/table's base class sets min-w-max. Inside the nested ScrollArea the fixed table with min-width:max-content had no defined total width and resolved to a runaway ~1,000,000px, which table-fixed then distributed across columns proportionally — pushing all cell content off-screen so the servers table appeared empty despite data being present. Add min-w-full to the DataTable's Table className so tailwind-merge overrides the base min-w-max for these fixed-layout tables.
The shared scroll wrapper used overflow-hidden, so a fixed-layout table wider than its container had its rightmost columns clipped and unreachable, and the overflowing width pushed sibling page chrome (e.g. header actions) off-screen. Switch to overflow-x-auto so wide tables scroll within their bordered container.
Move agent enrollment out of Settings into an admin-only "Add Server" action on the Servers page. The dialog collects an optional name and code validity, generates a one-time enrollment code, then shows the code, ready-to-run install command and next steps, plus management of existing codes. Settings now only hosts the GeoIP card.
Restore the header's space-between layout so the admin Add Server action sits at the top-right of the page, matching the placement of primary actions elsewhere.
The tooltip overrode only the popup background (bg-background) while the base tooltip's text (text-background) and arrow (bg-foreground) were left intact. That made the body text the same color as its background and left a mismatched light arrow on a dark bubble in dark mode. Drop the partial override and use the shared tooltip surface, matching every other tooltip in the app and staying theme-correct in both light and dark.
Tooltips used bg-foreground/text-background, so in dark mode they rendered as a bright pill instead of a dark surface. Switch the tooltip popup and arrow to the popover tokens (bg-popover/ text-popover-foreground with a border), so tooltips are dark in dark mode and light in light mode, with the arrow matching the bubble.
Convert the bottom footer stats row from a centered wrapping flex to a two-column label/value grid so it matches the card's other 2-column sections. Traffic days-remaining now renders in the second column and the cost footnote spans both columns centered below.
Combine processes, TCP and UDP into a single footer row and render the cost as a regular label/value cell so it conforms to the two-column grid instead of a centered footnote.
Show full read/write labels prefixed with circular R/W badges, and relocate the load trend from the compact metrics grid into the bottom two-column footer stats so the compact grid is a clean 2x2.
Replace the value-score grade label in the configured cost footnote with the monthly-equivalent total cost so the card surfaces an absolute spend figure alongside the hourly rate.
Keep the days-left and cost grid slots occupied with invisible placeholders when unset so the card footer height stays stable, and render the load trend with the same dot separator spacing as the cost row.
Use the same auto-fill minmax column template as the dashboard server cards widget so wide viewports no longer stretch cards across only three columns with an oversized horizontal gap.
The backend overview already returns up to 30 buckets of historical latency/loss per server, but the card painted every synthetic point (which includes backend sparkline buckets) with the unknown color, so history rendered gray and only live points gained color after a refresh. Color a square by whether it has a value instead of the synthetic flag; genuinely empty buckets and padding still render as unknown.
Backend overview only ships server-level aggregate sparklines plus a single current per-target snapshot. The card reused that constant snapshot as the tooltip for every historical point, so all tooltips showed identical values. Carry each bucket's own aggregate latency/loss on its point and label it as the average.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughThis PR modernizes ServerBee's installation and onboarding by consolidating paths to ChangesEnd-to-end ServerBee modernization
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Summary
A batch of installer (
deploy/install.sh) UX work plus a servers page and card UI redesign with network-quality history fixes.Deploy / installer
/opt/serverbee; place docker-mode and snap-accessible config in directories the server actually loads (/opt/serverbee/etc/server.toml).<latest>); show the first-run admin password in the install result.upgrade.rmcommands instead of a--purgehint on uninstall; widen the docker first-run password poll budget; harden the noninteractive flow.Servers page & card UI (web)
Network quality
Docs
Test plan
cargo test --workspacebun run test(web)bun run typecheckcargo clippy --workspace -- -D warningsSummary by CodeRabbit
New Features
Documentation
Improvements