panel: redesign web UI and make syncing responsive
Web UI (panel/frontend/index.html) rewritten: - Cards update in place from a single /status poll instead of being rebuilt on every action, so open tabs, unsaved compose/route edits, logs and the file browser position survive refreshes. Polling speeds up while an operation runs and pauses in background tabs; a header indicator shows when the panel last synced and detects an expired Authelia session. - New-app dialog (starter / compose / git), suggested port and domain, proper confirm dialogs (the old "OK = keep volumes" remove prompt is gone), toasts, an activity drawer with operation output, overflow menu, search, status filters, keyboard shortcuts, deep links, dark mode and mobile layout. - Tabs: overview (containers + routes), compose editor (dirty tracking, Ctrl+S), logs with follow, validated routes editor, file browser with drag-and-drop upload, backups, and a git source tab (deployed commit, check for updates, sync & deploy). API (panel/panel-api.py): - ThreadingHTTPServer so a long deploy no longer blocks every other request. - Per-app operation lock; concurrent writes to a busy app return 409. - GET /status: all apps, routes and container status in one request (statuses gathered in parallel); status reports running/partial/stopped. - Git sync is fetch + hard reset instead of pull-or-reclone, keeps the stored token, reports before/after commits; GET /apps/<name>/repo[?fetch=1]. - Any http(s) git host (e.g. Forgejo), default branch detection, git timeouts, no credential prompts, tokens redacted from errors, and manifest values validated before being written into the bash-sourced manifest. panelctl: - flock around routes.caddy rewrites (util-linux added to the service path). - deploy returns compose output so failures are visible in the UI. - inspect-volumes no longer fails for apps without named podman volumes, which broke the file browser. Docs: README/API.md updated; fixed outdated panelctl init examples. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UbWSNkXxZhYf7eqHTyx3Bf
This commit is contained in:
parent
85e29b8734
commit
2d3b30d078
5 changed files with 2741 additions and 1326 deletions
52
README.md
52
README.md
|
|
@ -22,14 +22,19 @@ All app routes are written to a single `routes/routes.caddy` file that Caddy imp
|
|||
## Quick workflow
|
||||
|
||||
```bash
|
||||
# Create a new app (single domain)
|
||||
panelctl init whoami whoami.srazka.com 18080 true
|
||||
# Routes are "domain|upstream[|path]" entries, comma-separated.
|
||||
|
||||
# Create with multiple domains
|
||||
panelctl init myapp "app.srazka.com,www.srazka.com" 18081 true
|
||||
# Create a new app (single route, protected by Authelia)
|
||||
panelctl init whoami "whoami.srazka.com|127.0.0.1:18080" true
|
||||
|
||||
# Create with multiple routes (different ports, optional path)
|
||||
panelctl init myapp "app.srazka.com|127.0.0.1:18081,api.srazka.com|127.0.0.1:18082|/api/*" true
|
||||
|
||||
# Create with wildcard domain (requires DNS challenge in Caddy)
|
||||
panelctl init wild "*.srazka.com" 18082 false
|
||||
panelctl init wild "*.srazka.com|127.0.0.1:18083" false
|
||||
|
||||
# Change routes later (Caddy reloads automatically)
|
||||
panelctl set-routes whoami "whoami.srazka.com|127.0.0.1:18080,who.srazka.com|127.0.0.1:18080"
|
||||
|
||||
# Deploy (compose up + caddy reload)
|
||||
panelctl deploy whoami
|
||||
|
|
@ -91,9 +96,34 @@ panelctl remove whoami
|
|||
|
||||
### Web UI features
|
||||
|
||||
- Create apps with multiple domains and wildcard support
|
||||
- Live container status indicators (auto-refreshes)
|
||||
- Deploy, restart, stop, remove from the UI
|
||||
- Inline compose editor with save, validate, and save+deploy
|
||||
- Log viewer with configurable tail length
|
||||
- Volume backup management: create, list, download, restore
|
||||
- Live status: one `/status` poll every few seconds (faster while something is
|
||||
running, paused when the tab is hidden) updates cards in place, so open tabs,
|
||||
unsaved edits and scroll positions are never lost. The header shows when the
|
||||
panel last synced and warns when the Authelia session has expired.
|
||||
- Per-app status (running / partial / stopped), container list, and a busy
|
||||
indicator that is shared between browsers while an operation runs.
|
||||
- New-app dialog: starter container, pasted compose file or git repository;
|
||||
suggests the next free port and a domain based on the app name.
|
||||
- Compose editor with unsaved-changes tracking, Ctrl+S, save & deploy, validate.
|
||||
- Logs with follow mode, routes editor with validation, file browser with
|
||||
drag-and-drop upload, backups with restore (and optional redeploy).
|
||||
- Git source tab: deployed commit, "check for updates", and sync & deploy.
|
||||
- Activity drawer with the output of every operation (e.g. why a deploy failed).
|
||||
- Keyboard: `/` search, `N` new app, `Esc` closes menus. Deep links like
|
||||
`#/whoami/logs` open an app on a specific tab.
|
||||
|
||||
### Git-backed apps
|
||||
|
||||
Apps created from a repository (GitHub, Forgejo/Gitea or any https git host)
|
||||
are cloned to `stacks/<app>/repo`. **Sync** fetches the configured branch and
|
||||
hard-resets the checkout to it before redeploying, so the repository is the
|
||||
source of truth: compose edits made in the panel are discarded on the next sync
|
||||
(the UI warns about this). An access token for a private repository is stored in
|
||||
the clone's `.git/config`; use a read-only token.
|
||||
|
||||
### Concurrency
|
||||
|
||||
`panel-api` handles requests concurrently, so a long deploy never blocks status
|
||||
or logs. Mutating operations are serialised per app — a second operation on a
|
||||
busy app gets HTTP 409 — and `panelctl` takes a `flock` on the shared routes
|
||||
file while rewriting it.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue