feat: add initial implementation of the frontend panel with app management features

Co-authored-by: Copilot <copilot@github.com>
This commit is contained in:
Jakub Dorfman 2026-04-26 23:53:17 +02:00
parent 8cb90be7cd
commit e15298fd3d
5 changed files with 1547 additions and 557 deletions

127
README.md
View file

@ -1,39 +1,102 @@
# panelctl quickstart
This repository now includes a small helper command named panelctl for Phase 2.
Minimal container management panel for rootless Podman + Caddy.
Base directory:
- /var/lib/containers
## Base directory
Generated structure:
- /var/lib/containers/stacks/<app>/compose.yaml
- /var/lib/containers/volumes/<app>/data
- /var/lib/containers/routes/<app>.caddy
- /var/lib/containers/state/apps/<app>.env
`/var/lib/containers`
Quick workflow:
1. Create a new app definition:
panelctl init whoami whoami.srazka.com 18080 true
2. Deploy it with Podman compose:
panelctl deploy whoami
3. If deploy says caddy reload needs root:
sudo systemctl reload caddy
4. List apps:
panelctl list
5. Inspect one app:
panelctl show whoami
6. Remove app but keep data:
panelctl remove whoami --keep-volumes
## Generated structure
Notes:
- The default compose file uses traefik/whoami for smoke testing.
- Edit each generated compose.yaml before production use.
- App names must be lowercase slugs.
- If deploy reports XDG_RUNTIME_DIR missing, enable lingering for the runtime user:
`sudo loginctl enable-linger reudy`
```
/var/lib/containers/
├── stacks/<app>/compose.yaml # Compose file per app
├── volumes/<app>/data # Persistent volumes
├── routes/routes.caddy # Single aggregate Caddy routes file
├── backups/<app>-<timestamp>.zip # Volume backups
└── state/apps/<app>.env # App manifest
```
API service:
- Nix now runs panel-api as a systemd service on 127.0.0.1:9911.
- Caddy proxies https://panel.srazka.com to panel-api with your existing forward_auth pattern.
- Open https://panel.srazka.com for the web UI.
- API docs are in panel/API.md.
All app routes are written to a single `routes/routes.caddy` file that Caddy imports.
## Quick workflow
```bash
# Create a new app (single domain)
panelctl init whoami whoami.srazka.com 18080 true
# Create with multiple domains
panelctl init myapp "app.srazka.com,www.srazka.com" 18081 true
# Create with wildcard domain (requires DNS challenge in Caddy)
panelctl init wild "*.srazka.com" 18082 false
# Deploy (compose up + caddy reload)
panelctl deploy whoami
# Check container status
panelctl status whoami
# View logs
panelctl logs whoami --tail 50
# Restart containers
panelctl restart whoami
# Stop containers
panelctl stop whoami
# Validate compose file
panelctl validate-compose whoami
# Backup volumes to zip
panelctl backup whoami
# List backups
panelctl list-backups whoami
# Restore from backup
panelctl restore whoami whoami-20260101-120000.zip
# List all apps
panelctl list
# Show app manifest
panelctl show whoami
# Remove app (keeps volumes)
panelctl remove whoami --keep-volumes
# Remove app and all data
panelctl remove whoami
# If deploy says caddy reload needs root:
sudo systemctl reload caddy
```
## Notes
- The default compose file uses `traefik/whoami` for smoke testing — edit before production use.
- App names must be lowercase slugs (`[a-z0-9-]`).
- Wildcard domains (`*.example.com`) require DNS challenge in Caddy (provider-specific).
- Backups stop containers for consistency, then restart if they were running.
- If deploy reports `XDG_RUNTIME_DIR` missing, enable lingering:
```
sudo loginctl enable-linger reudy
```
## Web UI & API
- Nix runs `panel-api` as a systemd service on `127.0.0.1:9911`.
- Caddy proxies `https://panel.srazka.com` → panel-api with Authelia forward_auth.
- Open `https://panel.srazka.com` for the web UI.
- API docs: [API.md](API.md)
### 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