README.md
Rama main · réplica de lectura del repositorio original.
# LinkBoard
A beautiful, customizable service dashboard for Nextcloud.



[](https://github.com/sponsors/tschuegy)
---
## About
LinkBoard turns your Nextcloud into a personal homelab dashboard.
Organize all your self-hosted services in one place — with live status checks,
real-time widgets, custom icons, and a fully configurable layout.
Inspired by [Gethomepage](https://gethomepage.dev), but deeply integrated into Nextcloud.
## Screenshots
| | | |
|---|---|---|
|  |  |  |
|  |  | |
## Features
- **Service Dashboard** – Organize services in categories with drag & drop sorting; sections can be placed side by side in a row or dropped between rows
- **Grid Layout** – Grafana-style grid layout with free drag, resize, and placement of cards within categories
- **Configurable Grid** – Set grid granularity per category (6, 12, or 24 columns) with auto-arrange and row-height options
- **Edit Mode** – Lock/unlock edit mode toggle to prevent accidental changes
- **Status Checks** – Live health checks with dot or border indicators; manual refreshes are rate-limited, deduplicated, runtime-bounded, and prioritize the stalest services
- **TLS Policy** – Administrators can enforce certificate verification globally or permit per-service exceptions for self-signed homelab services; failed checks name the reason (certificate, timeout, connection, DNS) in the status tooltip
- **Outbound Request Protection** – User-configured hosts are validated, pinned to their checked DNS addresses, and prevented from reaching loopback, link-local, multicast, or reserved targets
- **Validated Settings** – Dashboard settings use a typed server-side allowlist with strict normalization before persistence or import
- **Status History** – Response time charts, uptime tracking, and a dedicated status overview page
- **Offline Notifications** – Nextcloud notifications when services go down, with configurable threshold and recovery alerts
- **External Notification Channels** – 19 providers: Discord, Slack, Telegram, Matrix, Teams, Ntfy, Gotify, Pushover, E-Mail (SMTP), and more, with per-service overrides
- **Hardened SMTP** – Correct STARTTLS and implicit TLS handling with validated destinations, bounded I/O, and support for ports 25, 465, 587, 1025, and 2525
- **136 Built-in Widgets** – Real-time data from Proxmox, Patchman, Immich, Uptime Kuma, and 130+ more; plus an inline-editable Table widget ([full list](WIDGETS.md))
- **Hardened Widget Proxy** – Request URLs and upstream error details are not exposed; batch loads are paginated, time-bounded, rate-limited, deduplicated, and briefly cached
- **System Resources** – Monitor CPU, memory, disk usage, uptime, and CPU temperature with progress bars
- **Category Spacers** – Decorative separator categories with multiple styles (solid, dashed, dotted, dots, stars, and more)
- **Flexible Icons** – Upload custom images (PNG, JPEG, WebP, GIF, ICO), use Material Design Icons (inline SVG) by name in either kebab-case (`mdi-cloud`) or camelCase (`mdiCloud`), or any URL
- **Theming** – Dark, light, or auto mode with custom background images and blur effects
- **Card Styles** – Glass, Solid, Flat, or Transparent card backgrounds
- **Display Modes** – Show services as cards or as a compact single-line list, with the title, URL, or both per row; list rows can be reordered and moved between categories via drag & drop in edit mode
- **Link Target** – Open service links in a new tab, the same tab, or configure it per service
- **Per-Card Scrollbar Toggle** – Hide scrollbars by default for a cleaner look; enable them per card when needed (content stays scrollable either way)
- **Configurable Layout** – Adjust columns, card styles, search bar, and more
- **Import / Export** – YAML & JSON support, compatible with Gethomepage services.yaml
- **Keyboard Shortcuts** – Quick access via `/`, `E`, `R`, `Esc` ([see below](#keyboard-shortcuts))
- **Multi-Language** – Full i18n support with 57 languages
- **Per-User** – Each Nextcloud user gets their own private dashboard
- **Global Board** – Admins can designate one user's board as a shared read-only dashboard for all users
- **Group Restriction** – Optionally restrict LinkBoard access to specific Nextcloud groups
## Example Configuration
Want to see what a populated dashboard looks like? Check out
[`examples/linkboard-example.json`](examples/linkboard-example.json) —
a ready-to-import sample board with 11 categories, 21 services, and
10 widgets (Proxmox, AdGuard, custom API, system resources, table).
Download the file, then import it via **Settings → Import / Export →
Import JSON** inside LinkBoard. URLs (`192.168.1.1`) and auth headers
are placeholders — replace them with your own before importing, or
import as-is and edit each service afterwards.
## Keyboard Shortcuts
| Key | Action |
|-----|--------|
| `/` | Focus search bar |
| `E` | Toggle edit mode |
| `R` | Refresh all (status checks, widgets, resources) |
| `Escape` | Close editor / exit edit mode / clear search |
> Shortcuts are disabled while typing in input fields. `E` and `R` are ignored when Ctrl/Cmd is held.
## Requirements
- Nextcloud 32, 33, 34, or 35
- PHP 8.2 – 8.5 (Nextcloud 35 requires PHP 8.3 or later)
## Administration
LinkBoard provides admin settings under **Settings > Administration > LinkBoard**.
### Group Restriction
By default, LinkBoard is available to all users. Admins can restrict access to specific Nextcloud groups. Only users in the selected groups (and admins) will see LinkBoard in the navigation.
### Global Board
Admins can enable a global board that replaces all personal dashboards with a single shared board:
1. Go to **Settings > Administration > LinkBoard**
2. Enable **"Show a global LinkBoard for all users"**
3. Select a user whose board should be displayed to everyone
4. Click **Save**
When active, all users see the selected user's board in read-only mode. Only admins can edit the global board (add/remove categories and services). Personal boards are preserved and will reappear when the global board is disabled.
### Status Checks & Cron
LinkBoard uses Nextcloud's background job system for periodic status checks. The minimum check interval is 1 minute, but **status checks can only run as often as Nextcloud's cron is triggered**.
Most Nextcloud installations use a system cron job that runs every 5 minutes by default. If you need 1-minute status checks, you must ensure the Nextcloud cron runs every minute.
#### Recommended: Systemd Timer (Linux)
Create the service file `/etc/systemd/system/nextcloud-cron.service`:
```ini
[Unit]
Description=Nextcloud cron.php
After=network.target
[Service]
User=www-data
ExecStart=/usr/bin/php /var/www/nextcloud/cron.php
```
Create the timer file `/etc/systemd/system/nextcloud-cron.timer`:
```ini
[Unit]
Description=Run Nextcloud cron.php every minute
[Timer]
OnBootSec=5min
OnUnitActiveSec=1min
Unit=nextcloud-cron.service
[Install]
WantedBy=timers.target
```
Enable and start the timer:
```bash
sudo systemctl daemon-reload
sudo systemctl enable --now nextcloud-cron.timer
```
Verify it's running:
```bash
systemctl list-timers | grep nextcloud
# Should show: nextcloud-cron.timer with ~1min interval
```
#### Alternative: Crontab
If you prefer a traditional crontab entry:
```bash
sudo crontab -u www-data -e
```
Add this line to run every minute:
```
* * * * * php /var/www/nextcloud/cron.php
```
> **Note:** Make sure **Settings > Administration > Basic settings > Background jobs** is set to **Cron** in your Nextcloud instance.
## Installation
Download the latest release tarball and extract it into your Nextcloud `apps/` directory:
```bash
cd /path/to/nextcloud/apps
tar xzf linkboard.tar.gz
```
Then enable the app:
```bash
cd /path/to/nextcloud/
php occ app:enable linkboard
```
## Development Setup
### Prerequisites
- Node.js 20+
- npm
- PHP 8.2+
- Composer
- A Nextcloud development instance
### Getting Started
```bash
cd /path/to/nextcloud/apps/
git clone https://github.com/tschuegy/linkboard-nextcloud.git linkboard
cd linkboard
composer install
npm install
npm run build
cd /path/to/nextcloud/
php occ app:enable linkboard
```
### Development Commands
```bash
npm run watch # Auto-rebuild on changes
npm run build # Production build
npm run lint # Lint check
npm run lint:fix # Auto-fix lint issues
```
## Project Structure
```
linkboard/
├── appinfo/ # App metadata & routes
├── lib/ # PHP backend
│ ├── Controller/ # REST API controllers
│ ├── Db/ # Entity & mapper classes
│ ├── Service/ # Business logic
│ ├── Widget/ # 136 widget definitions
│ └── Migration/ # Database migrations
├── src/ # Vue.js frontend
│ ├── components/ # Vue components
│ ├── store/ # Pinia state management
│ └── services/ # API client
├── css/ # Global styles
├── img/ # App icon & screenshots
├── l10n/ # Translation files (57 languages)
└── templates/ # PHP templates
```
## API Overview
All endpoints under `/apps/linkboard/api/v1/`:
| Endpoint | Methods | Description |
|----------|---------|-------------|
| `/dashboard` | GET | Full dashboard (categories + services + settings) |
| `/categories` | GET, POST | List / create categories |
| `/categories/{id}` | GET, PUT, DELETE | Single category CRUD |
| `/categories/reorder` | PUT | Reorder categories |
| `/services` | GET, POST | List / create services |
| `/services/{id}` | GET, PUT, DELETE | Single service CRUD |
| `/services/reorder` | PUT | Reorder services |
| `/services/{id}/move/{catId}` | PUT | Move service to category |
| `/settings` | GET, PUT | User settings |
| `/icons` | GET, POST | List / upload icons |
| `/icons/{filename}` | GET, DELETE | Serve / delete icon |
| `/widgets/catalog` | GET | Available widget types |
| `/widgets/data` | GET | Fetch a bounded page of widget data (`offset`, `limit`; continuation via `X-LinkBoard-Widget-Next-Offset`) |
| `/status/{id}/history` | GET | Status history for a service |
| `/status/history` | GET | Status history for all services |
| `/resources/{categoryId}` | GET | System resources (CPU, memory, disk) |
## License
AGPL-3.0-or-later