Compare commits

..
Author SHA1 Message Date
ajnart db64ded3f0 style: auto-fix lint and format 2026-06-09 19:28:49 +00:00
Thomas Camlong fe35a9cf68 refactor: reduce verbosity and dead code across new integrations
- Remove dead widget.audiobookshelf/navidrome i18n blocks (76 lines)
- Simplify audio-stats router (remove duplicated kind casts)
- Remove redundant defaultDisplayOptions in audio-stats component
- Dedup fetch helpers in uptime-kuma (fetchOkAsync) and
  paperless-ngx (fetchAuthenticatedAsync)
- Simplify navidrome asArray helper and getArtistCountAsync
- Simplify uptime-kuma averageUptimePercent and status derivation
2026-06-09 21:28:02 +02:00
ajnart ad76ce9cdc style: auto-fix lint and format 2026-06-09 19:04:24 +00:00
Thomas Camlong ced96a57b3 feat: add maxIntegrations property to widget definitions
Replaces the hardcoded audioStats check with a generic
maxIntegrations field on WidgetDefinition. The integration
select component respects this to enforce single-select mode.
2026-06-09 21:03:09 +02:00
ajnart 302a9f4e54 style: auto-fix lint and format 2026-06-09 18:59:39 +00:00
Thomas Camlong 69ed608241 refactor: remove deprecated navidrome/audiobookshelf widgets
Consolidate into the unified Audio Stats widget which adapts its UI
based on the linked integration kind — Navidrome shows artists/albums/
songs/now-playing, Audiobookshelf shows libraries/audiobooks/podcasts/
listening-time/sessions.

Removes: widget definitions, components, API routers, and the
deprecatedWidgetKinds mechanism (no longer needed).
2026-06-09 20:58:54 +02:00
Thomas 9da8ea1dec Update package.json 2026-06-09 18:18:27 +02:00
ajnart 2b4a18385d style: auto-fix lint and format 2026-06-09 16:10:56 +00:00
Thomas Camlong c9f003dadd feat: add Uptime Kuma, Audiobookshelf, Paperless-ngx, and Navidrome integrations
Add four new integrations with full widget support:

- Uptime Kuma: dashboard monitors, uptime percentage ring, status counts
- Audiobookshelf: library stats, audiobooks/podcasts counts, listening time
- Paperless-ngx: document stats, inbox ratio ring, correspondents/tags
- Navidrome: artist/album/song counts, now playing with track list

Also adds a unified "Audio Stats" widget that merges Navidrome and
Audiobookshelf into a single configurable widget with backend-specific
option visibility.

Includes Vitest specs for pagination, status mapping, and shared utils.
2026-06-09 18:09:22 +02:00
1316 changed files with 26038 additions and 154794 deletions

No files matched your search

+5 -20
View File
@@ -15,15 +15,13 @@ Homarr is an open-source, self-hosted dashboard for managing homelab services. I
- **ORM**: Drizzle (supports SQLite via better-sqlite3, MySQL, PostgreSQL)
- **API**: tRPC (HTTP + WebSocket subscriptions) with superjson + OpenAPI bridge via `trpc-to-openapi`
- **Auth**: NextAuth v5 (database sessions, Credentials/LDAP/OIDC providers)
- **UI**: Mantine v9 (not Tailwind) + Tabler icons
- **UI**: Mantine v7 (not Tailwind) + Tabler icons
- **State**: Jotai (atoms), TanStack Query (server state via tRPC)
- **Realtime**: WebSocket server (`ws`) for tRPC subscriptions, backed by Redis pub/sub
- **Cron**: `node-cron` in a standalone Fastify service (`apps/tasks`)
- **i18n**: next-intl with `[locale]` dynamic segment (prefix mode: `"never"`, locale from cookie)
- **Testing**: Vitest + jsdom, Playwright for E2E
- **Lint/Format**: oxlint + oxfmt (not ESLint/Prettier)
- **Docs**: Docusaurus 3 in `apps/docs/` (`@homarr/docs`)
- **Package manager**: pnpm 10.34.1, Node >= 24.16.0
- **Package manager**: pnpm 10.33.2, Node >= 24.15.0
## Repository Structure
@@ -31,7 +29,6 @@ Homarr is an open-source, self-hosted dashboard for managing homelab services. I
homarr/
├── apps/
│ ├── nextjs/ # Main Next.js application (port 3000)
│ ├── docs/ # Docusaurus 3 documentation site (@homarr/docs)
│ ├── tasks/ # Cron job runner + Fastify tRPC API (port 3002)
│ └── websocket/ # Standalone tRPC WebSocket server (port 3001)
├── packages/
@@ -70,6 +67,8 @@ homarr/
│ ├── old-schema/ # Legacy Homarr zod schemas
│ └── cli/ # Node CLI for ops (brocli)
├── tooling/
│ ├── eslint/ # Shared ESLint configs
│ ├── prettier/ # Shared Prettier config
│ ├── typescript/ # Base tsconfig
│ └── github/ # CI setup action
├── development/ # Dev docker-compose (Redis, MySQL, PostgreSQL)
@@ -177,8 +176,7 @@ Key env vars (from `.env.example`):
- `pnpm db:studio` — Drizzle Studio
- `pnpm test` — Vitest unit tests
- `pnpm test:e2e` — Playwright E2E
- `pnpm lint` / `pnpm format` — oxlint + oxfmt
- `pnpm dev:docs` — Docusaurus docs site (port 3003)
- `pnpm lint` / `pnpm format` — ESLint + Prettier
- `pnpm typecheck` — tsc --noEmit across all packages
## Conventions
@@ -191,16 +189,3 @@ Key env vars (from `.env.example`):
- Drag-and-drop via `@dnd-kit/*`
- `typescript.ignoreBuildErrors: true` in next.config (types checked separately via `typecheck`)
- `serverExternalPackages`: `dockerode`, `isomorphic-dompurify`, `jsdom`
## Documentation (`apps/docs`)
Docusaurus 3 site at `apps/docs/`, package name `@homarr/docs`.
- Run with `pnpm dev:docs` from root
- Build with `pnpm turbo build --filter=@homarr/docs`
- Uses Tailwind CSS 3 for custom pages (not Mantine)
- Imports `@homarr/definitions` for type-safe integration/widget metadata
- When adding or modifying widgets, integrations, cron jobs, API routes, env vars, or user-facing features, you MUST also update corresponding docs in `apps/docs/docs/`
- Integration docs: `apps/docs/docs/integrations/<slug>/index.mdx` + `index.ts`
- Widget docs: `apps/docs/docs/widgets/<slug>/index.mdx` + `index.ts`
- Strict link checking: broken links/anchors cause build failure
-50
View File
@@ -1,50 +0,0 @@
---
description: Keep documentation in sync with code changes
globs:
- packages/definitions/src/**
- packages/widgets/src/**
- packages/integrations/src/**
- packages/api/src/**
- apps/nextjs/src/**
- apps/docs/**
---
# Documentation Sync Rule
When modifying code that affects user-facing behavior, you MUST also update the documentation in `apps/docs/`.
## What triggers a doc update
| Code change | Doc location |
|---|---|
| New integration | `apps/docs/docs/integrations/<slug>/index.mdx` + `index.ts` |
| New widget | `apps/docs/docs/widgets/<slug>/index.mdx` + `index.ts` |
| Changed API surface | `apps/docs/docs/management/api.mdx` |
| New/changed env vars | `apps/docs/docs/advanced/` |
| New CLI commands | `apps/docs/docs/advanced/command-line/` |
| Changed auth providers | `apps/docs/docs/advanced/` SSO pages |
| UI/UX changes | Relevant getting-started or management pages |
| New cron job | `apps/docs/docs/management/tasks.mdx` |
| Changed permissions | `apps/docs/docs/management/users.mdx` |
## Integration doc pattern
Each integration has a folder under `apps/docs/docs/integrations/<slug>/`:
- `index.ts` — exports a typed `IntegrationDefinition` with name, description, iconUrl, path
- `index.mdx` — uses shared components: `IntegrationHeader`, `IntegrationCapabilites`, `IntegrationSecrets`
- Import metadata from `@homarr/definitions` where possible
## Widget doc pattern
Each widget has a folder under `apps/docs/docs/widgets/<slug>/`:
- `index.ts` — exports a typed `WidgetDefinition` with icon, name, description, path, configuration
- `index.mdx` — uses shared components: `WidgetHeader`, `WidgetConfig`, `WidgetAdding`
## Development
- Run docs locally: `pnpm dev:docs` from root
- Build docs: `pnpm turbo build --filter=@homarr/docs`
- The docs app can import from `@homarr/definitions` for type-safe integration/widget metadata
- Docusaurus strict mode throws on broken links — fix any broken references before committing
-103
View File
@@ -1,103 +0,0 @@
---
description: How to expose tRPC procedures as MCP tools for AI clients
globs: packages/api/src/router/**/*.ts
alwaysApply: false
---
# MCP Integration Guide
Every new tRPC procedure that provides useful functionality should be exposed as an MCP tool so AI assistants (Claude, Cursor, etc.) can use it. This is a first-class feature of Homarr.
## Adding MCP to a procedure
Add `.meta({ mcp: { enabled: true, description: "..." } })` to the procedure chain:
```typescript
// Read-only tool (query)
myProcedure: protectedProcedure
.meta({ mcp: { enabled: true, description: "Get all items with their status and metadata" } })
.input(z.object({ limit: z.number().default(50) }))
.query(async ({ ctx, input }) => { ... })
// Write tool (mutation)
myAction: protectedProcedure
.meta({ mcp: { enabled: true, description: "Delete an item by ID. Requires interact permission on the integration" } })
.input(z.object({ id: z.string() }))
.mutation(async ({ ctx, input }) => { ... })
// No-input procedure (z.void) — works fine, no .input() needed
getAll: protectedProcedure
.meta({ mcp: { enabled: true, description: "List all resources" } })
.query(async ({ ctx }) => { ... })
```
The `.meta()` call must come **before** `.input()` and `.query()`/`.mutation()` in the chain.
## Writing good descriptions
The description is the **only thing** an AI sees to decide when and how to use the tool. Write it like you're explaining to a colleague who has never used Homarr.
**Must include:**
- What the tool returns or does
- Which integrations/services it works with (if applicable)
- How to get required IDs (e.g., "Use integration_all to get the integrationId")
- Permission requirements (if non-obvious)
**Good:**
```
"Get calendar events for upcoming and recent media releases. Fetches from all connected Sonarr (TV), Radarr (movies), Lidarr (music), and Readarr (books) integrations. Requires integrationIds from integration_all"
```
**Bad:**
```
"Get calendar events"
```
**For tools that return permission fields**, explain what they mean:
```
"List all integrations. Returns permissions.hasUseAccess (read) and permissions.hasInteractAccess (actions) — false means the API key lacks that permission, not an error"
```
## Registering in the MCP router
After adding `.meta()` to procedures, you must register the router in `packages/api/src/mcp.ts`. This file uses **eager imports** (no `lazy()`) because MCP tool extraction requires synchronous access to all procedure definitions.
```typescript
// packages/api/src/mcp.ts
import { myNewRouter } from "./router/my-new-feature";
export const mcpRouter = createTRPCRouter({
// ... existing routers
myFeature: myNewRouter,
});
```
**If your router is nested** (e.g., widget sub-routers), import and register the sub-router directly — do not import a parent that uses `lazy()`.
## What to expose vs. what to skip
**Expose:**
- Data queries (list, search, get by ID)
- Actions users would ask an AI to do (toggle, create, delete, approve)
- Status checks (health, stats, summaries)
**Skip:**
- Subscriptions (WebSocket-only, not supported by MCP)
- Internal procedures (session management, onboarding steps)
- File upload/download procedures
- Procedures that return non-serializable data (streams, blobs)
## Input schema rules
- Use `z.object({...})` for inputs — this maps cleanly to MCP tool parameters
- `z.void()` (no `.input()`) works — the MCP handler patches these to accept empty objects
- Avoid `z.union()` or `z.discriminatedUnion()` at the top level — AI clients struggle with these
- Use `.default()` on optional fields so the AI doesn't need to guess values
## Checklist for new features
1. Add `.meta({ mcp: { enabled: true, description: "..." } })` to relevant procedures
2. Import and register the router in `packages/api/src/mcp.ts` (eager, no lazy)
3. Write descriptions that explain what the tool does, what it needs, and what it returns
4. If the tool requires an ID from another tool, say which one in the description
5. Test with `curl` against `/api/mcp/mcp` to verify the tool appears in `tools/list`
-1
View File
@@ -10,7 +10,6 @@ README.md
dev
.build
e2e
apps/docs
apps/nextjs/.next
.env
.env.*
+1 -8
View File
@@ -59,11 +59,4 @@ TURBO_TELEMETRY_DISABLED=1
# ENABLE_KUBERNETES=true
# Enable mock integration
UNSAFE_ENABLE_MOCK_INTEGRATION=true
# Enable demo mode (seeds a demo user "demo"/"demo", a sample board and a mock integration)
# DEMO_MODE=true
# Whether demo mode is read-only. Defaults to true (the public demo blocks all mutations).
# Set to false for writable preview deployments so the demo user can modify the dashboard.
# DEMO_READ_ONLY=false
UNSAFE_ENABLE_MOCK_INTEGRATION=true
-8
View File
@@ -33,14 +33,6 @@ body:
options:
# The below comment is used to insert a new version with on-release.yml
#NEXT_VERSION#
- 1.70.0
- 1.69.2
- 1.69.0
- 1.68.0
- 1.67.0
- 1.66.1
- 1.66.0
- 1.65.0
- 1.64.0
- 1.62.0
- 1.61.0
+1 -1
View File
@@ -11,7 +11,7 @@ outputs:
runs:
using: "composite"
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
persist-credentials: false
- name: Set up Docker Buildx
+2 -2
View File
@@ -22,7 +22,7 @@
automerge: true,
},
{
// disallow automerge for allowBuilds dependencies (native builds need manual verification)
// disallow automerge for onlyBuiltDependencies
matchPackageNames: [
"@tree-sitter-grammars/tree-sitter-yaml",
"bcrypt",
@@ -46,7 +46,7 @@
updateInternalDeps: true,
rangeStrategy: "bump",
automerge: false,
baseBranchPatterns: ["dev"],
baseBranches: ["dev"],
dependencyDashboard: false,
// prevent special characters in branch names (otherwise git errors occur on windows)
branchNameStrict: true,
+1 -1
View File
@@ -17,7 +17,7 @@ jobs:
if: github.actor_id == 158783068 || github.actor_id == 190541745 || github.actor_id == 210161987 || github.actor_id == 175486441
steps:
- name: Checkout code
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Obtain token
id: obtainToken
uses: actions/create-github-app-token@v3
+9 -9
View File
@@ -25,13 +25,13 @@ env:
jobs:
lint-format-autofix:
if: github.event_name == 'pull_request' && github.event.pull_request.head.repo.id == github.repository_id
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 5
permissions:
contents: write
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
fetch-depth: 0
ref: ${{ github.head_ref }}
@@ -52,7 +52,7 @@ jobs:
xargs -r -a /tmp/changed-files pnpm exec oxfmt --write
- name: Commit fixes
uses: stefanzweifel/git-auto-commit-action@v7
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "style: auto-fix lint and format"
@@ -60,7 +60,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -78,7 +78,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -92,7 +92,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
fetch-depth: 0
@@ -106,7 +106,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Setup
uses: ./tooling/github/setup
@@ -124,7 +124,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Setup
uses: ./tooling/github/setup
- name: Set up Docker Buildx
@@ -153,7 +153,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Setup
@@ -15,7 +15,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Obtain token
id: obtainToken
+1 -1
View File
@@ -18,7 +18,7 @@ jobs:
steps:
- name: Checkout
uses: actions/checkout@v7
uses: actions/checkout@v6
- name: Upload Crowdin translations
uses: crowdin/github-action@v2
@@ -26,7 +26,7 @@ jobs:
with:
args: "Beta release has been triggered: [run ${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
- name: Checkout repository
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get Next Version
@@ -57,7 +57,7 @@ jobs:
client-id: ${{ secrets.RENOVATE_MERGE_APP_ID }}
permission-contents: write # required to commit package.json & changelog changes, merge them to dev / next and publish the release
- uses: actions/checkout@v7
- uses: actions/checkout@v6
if: env.SKIP_RELEASE == 'false'
with:
persist-credentials: false
@@ -66,7 +66,7 @@ jobs:
- uses: actions/setup-node@v6
if: env.SKIP_RELEASE == 'false'
with:
node-version: 24.18.0
node-version: 24.16.0
package-manager-cache: false
- run: npm i -g pnpm
if: env.SKIP_RELEASE == 'false'
@@ -119,7 +119,7 @@ jobs:
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
ref: ${{ needs.release.outputs.git_ref }}
@@ -158,7 +158,7 @@ jobs:
outputs:
digest: ${{ steps.build.outputs.digest }}
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
with:
ref: ${{ needs.release.outputs.git_ref }}
-56
View File
@@ -1,56 +0,0 @@
name: "[Deployment] Documentation"
on:
push:
branches: ["dev"]
paths:
- "apps/docs/**"
- "packages/definitions/src/docs/**"
- ".github/workflows/deployment-docs.yml"
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
env:
SKIP_ENV_VALIDATION: true
TURBO_API: ${{ secrets.TURBO_API }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Setup
uses: ./tooling/github/setup
- name: Build docs
run: pnpm turbo build --filter=@homarr/docs
env:
CI: "true"
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Upload pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: "apps/docs/build"
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
@@ -3,7 +3,6 @@ name: "[Deployment] Automatic Weekly Release"
on:
schedule:
- cron: "0 19 * * 5" # https://crontab.guru/#0_19_*_*_5
timezone: Europe/Zurich
workflow_dispatch:
inputs:
send-notifications:
@@ -29,7 +28,7 @@ jobs:
with:
args: "Automatic release has been triggered: [run ${{ github.run_number }}](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }})"
- name: Checkout repository
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
fetch-depth: 0
- name: Get Next Version
@@ -1,58 +0,0 @@
name: "[Docs] Algolia Recrawl"
on:
workflow_run:
workflows: ["[Deployment] Documentation"]
types: [completed]
branches: [dev]
workflow_dispatch:
permissions:
contents: read
jobs:
recrawl:
if: >-
${{
(github.event.workflow_run.conclusion == 'success' && github.event.workflow_run.event != 'pull_request')
|| github.event_name == 'workflow_dispatch'
}}
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Setup
uses: ./tooling/github/setup
- name: Check Algolia crawler secrets
run: |
missing=0
for secret in ALGOLIA_CRAWLER_ID ALGOLIA_CRAWLER_USER_ID ALGOLIA_CRAWLER_API_KEY; do
if [ -z "${!secret}" ]; then
echo "::warning::Missing repository secret: $secret"
missing=1
fi
done
if [ "$missing" -eq 1 ]; then
echo "Add crawler secrets to enable automatic recrawls."
exit 1
fi
env:
ALGOLIA_CRAWLER_ID: ${{ secrets.ALGOLIA_CRAWLER_ID }}
ALGOLIA_CRAWLER_USER_ID: ${{ secrets.ALGOLIA_CRAWLER_USER_ID }}
ALGOLIA_CRAWLER_API_KEY: ${{ secrets.ALGOLIA_CRAWLER_API_KEY }}
- name: Wait for GitHub Pages to serve the new deployment
run: sleep 60
- name: Trigger Algolia DocSearch recrawl
uses: cssnr/algolia-crawler-action@v2
with:
crawler_id: ${{ secrets.ALGOLIA_CRAWLER_ID }}
crawler_user_id: ${{ secrets.ALGOLIA_CRAWLER_USER_ID }}
crawler_api_key: ${{ secrets.ALGOLIA_CRAWLER_API_KEY }}
- name: Verify search index
working-directory: apps/docs
run: pnpm verify:search
@@ -1,39 +0,0 @@
name: "[Docs] Update Contributors"
on:
schedule:
- cron: "0 12 * * FRI"
workflow_dispatch:
permissions:
contents: write
env:
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
HOMARR_CROWDIN_TOKEN: "${{ secrets.HOMARR_CROWDIN_TOKEN }}"
HOMARR_LABS_CROWDIN_TOKEN: "${{ secrets.HOMARR_LABS_CROWDIN_TOKEN }}"
SKIP_ENV_VALIDATION: true
jobs:
dump:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
with:
ref: dev
- name: Setup
uses: ./tooling/github/setup
- name: Dump contributors
working-directory: apps/docs
run: pnpm api-dump-contributors
- name: Commit updated contributors
uses: EndBug/add-and-commit@v10
with:
add: "apps/docs/static"
default_author: github_actor
message: "chore(docs): update contributors"
push: true
-66
View File
@@ -1,66 +0,0 @@
name: "[Docs] Update OpenAPI Spec"
on:
schedule:
- cron: "0 0 * * *"
workflow_dispatch:
permissions:
contents: write
env:
SKIP_ENV_VALIDATION: true
jobs:
update-spec:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
with:
ref: dev
- name: Setup
uses: ./tooling/github/setup
- name: Copy env
run: cp .env.example .env
- name: Start dev server
run: pnpm --filter @homarr/nextjs dev &
env:
TURBO_TELEMETRY_DISABLED: 1
DISABLE_TELEMETRY: 1
- name: Wait for server and fetch spec
run: |
set -euo pipefail
for i in $(seq 1 30); do
if curl -fsS http://localhost:3000/api/openapi -o /tmp/openapi.json 2>/dev/null; then
echo "Server is up, spec fetched"
break
fi
echo "Waiting for server... ($i/30)"
sleep 3
done
if [ ! -f /tmp/openapi.json ]; then
echo "::error::Server failed to start within timeout"
exit 1
fi
jq -e '.openapi and .paths' /tmp/openapi.json > /dev/null || {
echo "::error::Fetched file is not a valid OpenAPI spec"
exit 1
}
cp /tmp/openapi.json apps/docs/static/api/open-api-schema.json
echo "OpenAPI spec updated ($(jq '.paths | length' /tmp/openapi.json) paths)"
- name: Commit updated spec
uses: EndBug/add-and-commit@v10
with:
add: "apps/docs/static/api/"
default_author: github_actor
message: "chore(docs): update OpenAPI spec"
push: true
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Validate prebuilt dependencies for amd64
id: validate-amd64
uses: ./.github/actions/prebuilt-debian
@@ -30,7 +30,7 @@ jobs:
runs-on: ubuntu-24.04-arm
timeout-minutes: 5
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- name: Validate prebuilt dependencies for arm64
id: validate-arm64
uses: ./.github/actions/prebuilt-debian
@@ -13,7 +13,7 @@ jobs:
runs-on: ubuntu-latest
timeout-minutes: 2
steps:
- uses: actions/checkout@v7
- uses: actions/checkout@v6
- run: |
npx --yes --package renovate -- \
renovate-config-validator --strict .github/renovate.json5
+1 -1
View File
@@ -52,7 +52,7 @@ jobs:
permission-contents: write # required to commit to branch
permission-pull-requests: write # required to create pr & enable automerge
- name: Checkout code
uses: actions/checkout@v7
uses: actions/checkout@v6
with:
token: ${{ steps.obtainToken.outputs.token }}
ref: dev
+1 -1
View File
@@ -29,7 +29,7 @@ jobs:
permission-pull-requests: write # required to create pr & enable automerge
- name: Checkout repository
uses: actions/checkout@v7
uses: actions/checkout@v6
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
@@ -28,7 +28,7 @@ jobs:
permission-contents: write # required to commit to branch
permission-pull-requests: write # required to create pr & enable automerge
- name: Checkout code
uses: actions/checkout@v7
uses: actions/checkout@v6
env:
GITHUB_TOKEN: ${{ steps.obtainToken.outputs.token }}
- name: Setup
+3 -9
View File
@@ -2,7 +2,6 @@
# dependencies
node_modules
.pnpm-store/
.pnp
.pnp.js
.idea/
@@ -67,14 +66,9 @@ e2e/shared/tmp
#personal backgrounds
apps/nextjs/public/images/background.png
# next-intl
en.d.json.ts
# personal agent config
AGENTS.md
.opencode
.agents/
skills-lock.json
# docusaurus
apps/docs/.docusaurus
apps/docs/build
.pnpm-store
-2
View File
@@ -1,2 +0,0 @@
[tools]
node = "24.18.0"
+6 -2
View File
@@ -1,2 +1,6 @@
# pnpm v11: non-auth settings moved to pnpm-workspace.yaml
# Keep this file for any future registry/auth configuration
# Expo doesn't play nice with pnpm by default.
# The symbolic links of pnpm break the rules of Expo monorepos.
# @link https://docs.expo.dev/guides/monorepos/#common-issues
node-linker=hoisted
strict-peer-dependencies=false
engine-strict=true
+1 -1
View File
@@ -1 +1 @@
24.18.0
24.16.0
+1 -1
View File
@@ -3,5 +3,5 @@
"printWidth": 120,
"endOfLine": "lf",
"sortPackageJson": true,
"ignorePatterns": ["**/*.cjs", "**/lang/**", "static-data/**", "CHANGELOG.md", "apps/docs/.docusaurus/**", "apps/docs/build/**", "apps/docs/blog/**"]
"ignorePatterns": ["**/*.cjs", "**/lang/**", "static-data/**", "CHANGELOG.md"]
}
+1 -1
View File
@@ -30,7 +30,7 @@
"options": {
"reportUnusedDisableDirectives": "off"
},
"ignorePatterns": ["**/*.config.js", "**/*.config.mjs", "**/*.cjs", "**/lang/*.d.json.ts", ".next/**", "apps/docs/.docusaurus/**", "apps/docs/build/**"],
"ignorePatterns": ["**/*.config.js", "**/*.config.mjs", "**/*.cjs", "**/lang/*.d.json.ts", ".next/**"],
"settings": {
"react": { "version": "19" }
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"oxc.oxc-vscode",
"esbenp.prettier-vscode",
"yoavbls.pretty-ts-errors",
"million.million-lint",
"lokalise.i18n-ally"
+1 -1
View File
@@ -1,5 +1,5 @@
{
"js/ts.tsdk.path": "node_modules\\typescript\\lib",
"typescript.tsdk": "node_modules\\typescript\\lib",
"js/ts.implicitProjectConfig.experimentalDecorators": true,
"cSpell.words": [
"ajnart",
-83
View File
@@ -1,83 +0,0 @@
# Homarr Agent Rules
## Repository Structure
```
homarr/
├── apps/
│ ├── nextjs/ # Main Next.js application (port 3000)
│ ├── docs/ # Docusaurus 3 documentation site (@homarr/docs)
│ ├── tasks/ # Cron job runner + Fastify tRPC API (port 3002)
│ └── websocket/ # Standalone tRPC WebSocket server (port 3001)
├── packages/
│ ├── api/ # tRPC appRouter, procedures, OpenAPI
│ ├── auth/ # NextAuth config, providers, session, API keys
│ ├── db/ # Drizzle schema (3 DB drivers), migrations, queries
│ ├── core/ # Env validation, DB/Redis driver factories, logging
│ ├── definitions/ # Domain enums: WidgetKind, IntegrationKind, permissions
│ ├── widgets/ # All 39 dashboard widgets (definitions + components)
│ ├── integrations/ # Integration classes (HTTP clients to external apps)
│ ├── redis/ # Redis pub/sub channels, caching abstractions
│ ├── translation/ # next-intl setup, locale configs, lang JSON files
│ ├── ui/ # Shared Mantine components, theme, hooks
│ ├── validation/ # Shared zod schemas for API/forms
│ ├── common/ # Shared utilities, IDs, errors
│ ├── cron-jobs/ # Cron job implementations (25+ jobs)
│ ├── cron-jobs-core/ # Cron scheduling primitives
│ ├── cron-job-status/ # Cron status via Redis
│ ├── boards/ # Board context, edit mode, cache updater
│ ├── modals/ # Modal primitives on Mantine
│ ├── modals-collection/ # Feature modals (apps, boards, docker, etc.)
│ ├── form/ # useZodForm (Mantine + zod resolver)
│ ├── forms-collection/# Reusable form UIs (new app, icon picker, upload)
│ ├── spotlight/ # Command palette / search with multiple modes
│ ├── request-handler/ # Server request handlers (feeds, integrations)
│ ├── notifications/ # Mantine notifications wrapper
│ ├── docker/ # Dockerode-based Docker access
│ ├── icons/ # Icon DB/repo integration
│ ├── image-proxy/ # Image proxy + caching
│ ├── ping/ # Reachability / ping utilities
│ ├── analytics/ # Server-side analytics (Umami)
│ ├── server-settings/ # Server setting keys/types
│ ├── settings/ # User-facing settings UI context
│ ├── old-import/ # Legacy Homarr import
│ ├── old-schema/ # Legacy Homarr zod schemas
│ └── cli/ # Node CLI for ops (brocli)
├── tooling/
│ ├── typescript/ # Base tsconfig
│ └── github/ # CI setup action
├── development/ # Dev docker-compose (Redis, MySQL, PostgreSQL)
├── e2e/ # E2E test specs
└── Dockerfile # Multi-stage production build
```
## Documentation Sync
The documentation site lives at `apps/docs/` (Docusaurus 3, `@homarr/docs`).
When modifying user-facing code, you MUST also update the corresponding documentation:
- New integration → `apps/docs/docs/integrations/<slug>/index.mdx` + `index.ts`
- New widget → `apps/docs/docs/widgets/<slug>/index.mdx` + `index.ts`
- Changed API → `apps/docs/docs/management/api.mdx`
- New/changed env vars → `apps/docs/docs/advanced/`
- New CLI commands → `apps/docs/docs/advanced/command-line/`
- Auth changes → `apps/docs/docs/advanced/` SSO pages
- New cron job → `apps/docs/docs/management/tasks.mdx`
## Monorepo Commands
- `pnpm dev` — Next.js app only
- `pnpm dev:docs` — Docusaurus docs site only
- `pnpm turbo build` — build all packages
- `pnpm turbo build --filter=@homarr/docs` — build docs only
- `pnpm turbo typecheck` — typecheck all packages
- `pnpm lint` / `pnpm format` — oxlint / oxfmt
## Code Style
- Lint: oxlint (not ESLint)
- Format: oxfmt (not Prettier)
- UI: Mantine (not Tailwind) — Tailwind is only used in docs app
- Icons: @tabler/icons-react
- Docs app can import from `@homarr/definitions` for shared types
-121
View File
@@ -1,124 +1,3 @@
## [1.70.0](https://github.com/homarr-labs/homarr/compare/v1.69.2...v1.70.0) (2026-07-10)
## [1.69.2](https://github.com/homarr-labs/homarr/compare/v1.69.1...v1.69.2) (2026-07-06)
### Bug Fixes
* **layout:** raise AppShellHeader z-index above Indicator dots ([687edb9](https://github.com/homarr-labs/homarr/commit/687edb9226307cb83986097abb24fe7f672e1778)), closes [#6194](https://github.com/homarr-labs/homarr/issues/6194)
## [1.69.1](https://github.com/homarr-labs/homarr/compare/v1.69.0...v1.69.1) (2026-07-04)
### Bug Fixes
* unblock query cache mutations in demo mode and add cache buster ([#6176](https://github.com/homarr-labs/homarr/issues/6176)) ([a382c75](https://github.com/homarr-labs/homarr/commit/a382c75968e73bafff55b5890b1e95f0779b50d3))
## [1.69.0](https://github.com/homarr-labs/homarr/compare/v1.68.1...v1.69.0) (2026-07-03)
### Features
* add per-widget secret storage for release provider authentication ([77884a3](https://github.com/homarr-labs/homarr/commit/77884a31794e12a6f7bc59d96c8f61aa429ca68d))
* **config:** enable pnpm global virtual store for worktree support ([#6098](https://github.com/homarr-labs/homarr/issues/6098)) ([3864727](https://github.com/homarr-labs/homarr/commit/3864727502a64052c4e3838468094b30bf04a133))
* **docker-widget:** add per-column visibility toggle ([#6093](https://github.com/homarr-labs/homarr/issues/6093)) ([0765262](https://github.com/homarr-labs/homarr/commit/076526293d13379004461633d7ba4c2e83bd5ffe))
* **docs:** addd in documentation for archiveteam warrior ([f66469d](https://github.com/homarr-labs/homarr/commit/f66469d79797a2da214588f4e8253b03633c59a5))
* simplify caching — TanStack Query as single source of truth ([#6075](https://github.com/homarr-labs/homarr/issues/6075)) ([f19033e](https://github.com/homarr-labs/homarr/commit/f19033e0d53d248aed678737f3d04d5d8c7815b5))
* **widgets:** right-click context menu with auto-generated toggle actions ([#6126](https://github.com/homarr-labs/homarr/issues/6126)) ([7e58858](https://github.com/homarr-labs/homarr/commit/7e58858353ae866efd657270d4bb16d2c7d3e551))
* **widgets:** show calendar events on hover with pin on click ([#2637](https://github.com/homarr-labs/homarr/issues/2637)) ([#6081](https://github.com/homarr-labs/homarr/issues/6081)) ([db3d588](https://github.com/homarr-labs/homarr/commit/db3d58821e4de8d46b110125d0fa36919765248f))
### Bug Fixes
* add id to repository schema and handle missing ids gracefully ([8747d5f](https://github.com/homarr-labs/homarr/commit/8747d5f93ee9a295aad3c7035e8c6c7080bf5ee6))
* address PR review - atomic upsert, MCP metadata, stale tokens, save UX ([757d598](https://github.com/homarr-labs/homarr/commit/757d59854e5ec82d91c053b8bc3d7eaf2e70efc4))
* address PR review findings for widget-only integration refactor ([c892731](https://github.com/homarr-labs/homarr/commit/c892731479b47fab6218bd1f52fa6eccbdaa371e))
* address review - paginate GH releases, GitLab tag_name, docs, test ([e687bc8](https://github.com/homarr-labs/homarr/commit/e687bc8c9277797acaa164a09c74b3808a2cb346))
* apply version filter to LinuxServer.io provider ([34d976e](https://github.com/homarr-labs/homarr/commit/34d976eeea09e396334ce8fce5c492c07e7dd32b))
* catch individual repo fetch failures to prevent batch crashes ([d893515](https://github.com/homarr-labs/homarr/commit/d893515b932608ea08c9c6e90b83f340e40f6f8e))
* compile versionRegex once and add fetch timeouts ([64c7512](https://github.com/homarr-labs/homarr/commit/64c75122833981a49e9c8bf1789d501faff6d62d))
* **deps:** update dependency postcss to ^8.5.16 ([#6169](https://github.com/homarr-labs/homarr/issues/6169)) ([9252fdc](https://github.com/homarr-labs/homarr/commit/9252fdc13971bd982224a31d7be577112f99ec45))
* dns-hole widgets showing stale disconnected state ([#6096](https://github.com/homarr-labs/homarr/issues/6096)) ([2443f1c](https://github.com/homarr-labs/homarr/commit/2443f1cd3ff6765a91783d60d42aa03d9ba63fcd))
* gracefully degrade when widget_secret table is missing or access denied ([30107e4](https://github.com/homarr-labs/homarr/commit/30107e4e76a454ff7402de9a8bc2e0dd6f422aa8))
* handle missing widgetSecrets table and add default releases repo ([af35a50](https://github.com/homarr-labs/homarr/commit/af35a50fa05fee2f0118e98727eb108b0200f762))
* **immich:** v3 API compatibility — use searchAssets for album assets, drop deviceAssetId ([#5977](https://github.com/homarr-labs/homarr/issues/5977)) ([a5ec880](https://github.com/homarr-labs/homarr/commit/a5ec880eec276e0814d2ab3ed7f9bc0b804d0465))
* quick wins — calendar, about, glances, admin UX, releases, iframe, notes ([#6116](https://github.com/homarr-labs/homarr/issues/6116)) ([f9da71a](https://github.com/homarr-labs/homarr/commit/f9da71a19bdfa589aafe26b164d0e0782208ac0a))
* restore ArchiveTeam Warrior as a proper integration ([8a5ad58](https://github.com/homarr-labs/homarr/commit/8a5ad5861ba4c2d0978f1fa3f6115a1c5974f8a2))
* **timetable:** restore station search by removing disabled query guard ([d670b69](https://github.com/homarr-labs/homarr/commit/d670b6939672932c1a3d17ab9913901491cb46e3))
* update CHANGES.md for ArchiveTeam Warrior restoration, remove typo translation key ([62baaf7](https://github.com/homarr-labs/homarr/commit/62baaf78130c4b74e899a948cee17097d8c02593))
* verbose error messages in all release providers ([2155f13](https://github.com/homarr-labs/homarr/commit/2155f13f245f601b99458e227b6e058fbfa44cd9))
* **widgets:** make downloads widget table background transparent ([#6025](https://github.com/homarr-labs/homarr/issues/6025)) ([73bed51](https://github.com/homarr-labs/homarr/commit/73bed51df895250f415efd7a87e721e403b3fd99))
## [1.68.1](https://github.com/homarr-labs/homarr/compare/v1.68.0...v1.68.1) (2026-06-30)
### Bug Fixes
* make source maps opt-in to restore v1.67.0 memory baseline ([57ef0af](https://github.com/homarr-labs/homarr/commit/57ef0af4a252ea39727caeba7e13587dabc6254e)), closes [#6123](https://github.com/homarr-labs/homarr/issues/6123)
* revert production source maps to restore v1.67.0 memory baseline ([60a69e3](https://github.com/homarr-labs/homarr/commit/60a69e31efc7168b8f4309daf75954d7730d883b)), closes [#6123](https://github.com/homarr-labs/homarr/issues/6123)
## [1.68.0](https://github.com/homarr-labs/homarr/compare/v1.67.0...v1.68.0) (2026-06-26)
### Features
* add VPN status widget ([#5812](https://github.com/homarr-labs/homarr/issues/5812)) ([a2bb53a](https://github.com/homarr-labs/homarr/commit/a2bb53a8b8fd17da3d2e23851b75d4e179f66225))
* re-add Docker quick-access button in user menu ([#6054](https://github.com/homarr-labs/homarr/issues/6054)) ([abd1635](https://github.com/homarr-labs/homarr/commit/abd16354bc9ef3dddbb497fd16b03476535046ac)), closes [#2165](https://github.com/homarr-labs/homarr/issues/2165)
* ship source maps for readable production stack traces ([#6031](https://github.com/homarr-labs/homarr/issues/6031)) ([89380f8](https://github.com/homarr-labs/homarr/commit/89380f81ddd132f5b1041a8f2c3b6c6b138923dd))
### Bug Fixes
* **beszel:** harden cache layer and prevent blank widgets ([#6052](https://github.com/homarr-labs/homarr/issues/6052)) ([49c2663](https://github.com/homarr-labs/homarr/commit/49c266374df12fea2404710232ced42e2de11dbf)), closes [#6030](https://github.com/homarr-labs/homarr/issues/6030)
* **beszel:** improve stats date display, add click-to-stats modal, fix grid ordering ([#6026](https://github.com/homarr-labs/homarr/issues/6026)) ([55fb227](https://github.com/homarr-labs/homarr/commit/55fb227305fe51963e486ffb25c4ce6811a2f0e4))
* **beszel:** leverage TanStack Query for stale-while-revalidate caching ([#6055](https://github.com/homarr-labs/homarr/issues/6055)) ([bbc4589](https://github.com/homarr-labs/homarr/commit/bbc4589c9e1608721fb58a6f9b03cca8d65c1c4a))
* **beszel:** use 480m interval for 1w/30d stats views ([4383da3](https://github.com/homarr-labs/homarr/commit/4383da38ef634327c288626c58480cc1e5a2f805))
* **beszel:** widget transparency, error handling, and cache invalidation ([#5993](https://github.com/homarr-labs/homarr/issues/5993)) ([39e4245](https://github.com/homarr-labs/homarr/commit/39e424563a3187dcf0dba5f654e2225be76aef51))
* **icon-picker:** keep URL visible in edit mode, add SVG-first ordering ([#6051](https://github.com/homarr-labs/homarr/issues/6051)) ([e01571b](https://github.com/homarr-labs/homarr/commit/e01571b221812cd19a6d67ebe3cf44432104ec27))
* **integrations:** prevent certificate trust button from submitting the form ([#6020](https://github.com/homarr-labs/homarr/issues/6020)) ([0f66bfd](https://github.com/homarr-labs/homarr/commit/0f66bfd6c128253ba644d80d7c908de5314cf997))
* **manage/about:** bypass self-fetch + add manage error boundary (LLM exploration) ([#6009](https://github.com/homarr-labs/homarr/issues/6009)) ([19f9769](https://github.com/homarr-labs/homarr/commit/19f9769d9e669d56d793e9f6a0d265316113d743)), closes [#6008](https://github.com/homarr-labs/homarr/issues/6008) [#6008](https://github.com/homarr-labs/homarr/issues/6008) [#6008](https://github.com/homarr-labs/homarr/issues/6008)
* **plex:** use series title for media releases instead of season label ([#6083](https://github.com/homarr-labs/homarr/issues/6083)) ([2443b89](https://github.com/homarr-labs/homarr/commit/2443b89b46f88fddbf41f0382a9f3bc5469c6fa8))
* show app first in add item modal ([#6087](https://github.com/homarr-labs/homarr/issues/6087)) ([915c8a3](https://github.com/homarr-labs/homarr/commit/915c8a3501551fdccf786d0c34dc01107d873ce0))
* **truenas:** report actual memory usage and pool free space ([#6017](https://github.com/homarr-labs/homarr/issues/6017)) ([f69e545](https://github.com/homarr-labs/homarr/commit/f69e545d6429aece0e55975c3b2426f20e91e545))
* **unraid:** report disk free space instead of total size ([#6018](https://github.com/homarr-labs/homarr/issues/6018)) ([1fb97ee](https://github.com/homarr-labs/homarr/commit/1fb97ee9c6fbe656a7dd3a9d1e436125982533f4))
* **widgets:** clean up health monitoring disk and size display ([#6019](https://github.com/homarr-labs/homarr/issues/6019)) ([e29c79a](https://github.com/homarr-labs/homarr/commit/e29c79a9028d9311dcb3d8323e0950a444589c7a))
* **widgets:** hide health monitoring default tab option for non-proxmox integrations ([#6021](https://github.com/homarr-labs/homarr/issues/6021)) ([52df56b](https://github.com/homarr-labs/homarr/commit/52df56b19da8e0bcb6c2e5df47b7936ec63f3149))
* **widgets:** hide system disk usage value when it overflows and show it in a tooltip ([#6022](https://github.com/homarr-labs/homarr/issues/6022)) ([a19c9d8](https://github.com/homarr-labs/homarr/commit/a19c9d88caacc86b42854c732818f0b5e5cc8dd5))
## [1.67.0](https://github.com/homarr-labs/homarr/compare/v1.66.1...v1.67.0) (2026-06-19)
### Features
* **analytics:** migrate from Umami to PostHog server-side analytics ([#5983](https://github.com/homarr-labs/homarr/issues/5983)) ([d059023](https://github.com/homarr-labs/homarr/commit/d059023b51a323df027c1cf033454440bd0d7e57))
* Calculate and display total CPU and memory usage ([#5911](https://github.com/homarr-labs/homarr/issues/5911)) ([d9cbd54](https://github.com/homarr-labs/homarr/commit/d9cbd5427d0e5be3e5dbecca8d6069dc8074d810))
### Bug Fixes
* **auth:** isolate session cookies from other Auth.js apps on same host ([#5996](https://github.com/homarr-labs/homarr/issues/5996)) ([e1a245f](https://github.com/homarr-labs/homarr/commit/e1a245ff2d8520d08957c4a7dbe01d039607a973))
* **deps:** update tailwindcss monorepo to ^4.3.1 ([#5988](https://github.com/homarr-labs/homarr/issues/5988)) ([78b6e52](https://github.com/homarr-labs/homarr/commit/78b6e520ac095129398d3da8f2441df408e93e9f))
* **downloads:** sort stalled torrents last when sorting by finish time ([#6011](https://github.com/homarr-labs/homarr/issues/6011)) ([c56d9d6](https://github.com/homarr-labs/homarr/commit/c56d9d6894c717b5c70ab75d6a100d4d1071c2d3)), closes [#5416](https://github.com/homarr-labs/homarr/issues/5416)
## [1.65.0](https://github.com/homarr-labs/homarr/compare/v1.64.0...v1.65.0) (2026-06-12)
### Features
* add MCP server for AI assistant integration ([#5882](https://github.com/homarr-labs/homarr/issues/5882)) ([6baff7b](https://github.com/homarr-labs/homarr/commit/6baff7be3dc8f2473d93d17862b6d0b2df5c4d15))
* add Technitium DNS integration, usable with DNS Hole widgets ([#5832](https://github.com/homarr-labs/homarr/issues/5832)) ([cd1a82a](https://github.com/homarr-labs/homarr/commit/cd1a82a640101cdca88d1e825edb11bd51f5ce66))
* add Uptime Kuma, Audiobookshelf, Paperless-ngx, and Navidrome integrations ([#5910](https://github.com/homarr-labs/homarr/issues/5910)) ([d77c6f8](https://github.com/homarr-labs/homarr/commit/d77c6f8d4e50108f50831ee365e382a535acb254))
* **beszel:** add Beszel integration with system monitoring widgets ([#5900](https://github.com/homarr-labs/homarr/issues/5900)) ([a4db9cf](https://github.com/homarr-labs/homarr/commit/a4db9cf0dcd8034015064f9d23f2d351b1d0c50a))
* **board:** add widget hover overlay on dashboard ([#5888](https://github.com/homarr-labs/homarr/issues/5888)) ([29bd710](https://github.com/homarr-labs/homarr/commit/29bd7101b180acfb750c7d4414c30bd6450065e2))
* custom widgets ([#5889](https://github.com/homarr-labs/homarr/issues/5889)) ([aecbca2](https://github.com/homarr-labs/homarr/commit/aecbca2b81ad1693c599e3168fd0c0723311b3b4))
* **docs:** migrate documentation site into monorepo ([#5912](https://github.com/homarr-labs/homarr/issues/5912)) ([9e421c6](https://github.com/homarr-labs/homarr/commit/9e421c67bd87b5b7065118afedd08e7eb2140773))
* **lang:** add Finnish language support ([#5892](https://github.com/homarr-labs/homarr/issues/5892)) ([2fb7bde](https://github.com/homarr-labs/homarr/commit/2fb7bde9002c2670aa49db804e352c3821fa8097))
* search widgets by integration type when adding items ([#5909](https://github.com/homarr-labs/homarr/issues/5909)) ([48e1844](https://github.com/homarr-labs/homarr/commit/48e1844b5b9dc6d322bc22a972fdd29b6e03d3d2))
* SQLite backup & restore with WASM preview ([#5887](https://github.com/homarr-labs/homarr/issues/5887)) ([5d1f268](https://github.com/homarr-labs/homarr/commit/5d1f268438b84bd19f5a79658a43931dd874cd41))
* **ui:** add global query cache leveraging Redis ([#5811](https://github.com/homarr-labs/homarr/issues/5811)) ([74443a4](https://github.com/homarr-labs/homarr/commit/74443a49b2330b7d71c5ccdb873c61b270d1c72a))
### Bug Fixes
* **boards:** add permissions to board summary schema to fix manage page crash ([#5917](https://github.com/homarr-labs/homarr/issues/5917)) ([a42af0e](https://github.com/homarr-labs/homarr/commit/a42af0e678b58b6c63a8bac4978fb2951c6ddef8))
* **ci:** rename baseBranches to baseBranchPatterns in renovate config ([15e061c](https://github.com/homarr-labs/homarr/commit/15e061cf03f2301996aaf11a25095194e5759fb5))
* **db:** inline custom widget seed data to fix CJS migration crash ([f26007a](https://github.com/homarr-labs/homarr/commit/f26007a29a0b04765baba72122d38a9e5c639a0b))
* **definitions:** gracefully handle sitemap fetch failure in codegen ([7f8b012](https://github.com/homarr-labs/homarr/commit/7f8b0121b303fa09a213c73e6a690463e9fc6b44))
* **docs:** add trailingSlash for GitHub Pages compatibility ([28ceb37](https://github.com/homarr-labs/homarr/commit/28ceb37cbfe45f8ce45fd88e6a8c87ffe4c9b5c2))
* **docs:** disable swcHtmlMinimizer and fix broken links ([905f795](https://github.com/homarr-labs/homarr/commit/905f795b5607744d0aeec4bb65d84aabd1505047))
* gracefully skip widgets with unknown kind instead of crashing ([#5915](https://github.com/homarr-labs/homarr/issues/5915)) ([484b8cf](https://github.com/homarr-labs/homarr/commit/484b8cf9f18122a298dc7fae1027653cd287c09c))
* **image-proxy:** use ArrayBuffer instead of Blob to prevent OOM on Node v24 ([#5926](https://github.com/homarr-labs/homarr/issues/5926)) ([3e464a7](https://github.com/homarr-labs/homarr/commit/3e464a76f2d1e5985f259270a4258f3db4f17c18))
* **integrations:** support truenas json-rpc api, certificate trust, and api key auth ([#5861](https://github.com/homarr-labs/homarr/issues/5861)) ([f6d5f97](https://github.com/homarr-labs/homarr/commit/f6d5f97933cd257ee8851f2d6a27f56e2942076d))
## [1.64.0](https://github.com/homarr-labs/homarr/compare/v1.63.0...v1.64.0) (2026-06-05)
### Features
-96
View File
@@ -1,96 +0,0 @@
# Changes
## Goal
Remove widget-only services from Homarr's global Integration system.
The affected services are release providers and Search.ch. They are only used by specific widgets, so keeping them as global integrations added unnecessary setup, UI, database rows, docs pages, and integration package code.
ArchiveTeam Warrior remains a proper integration but is no longer auto-seeded on first install.
## Why
These services do not need shared integration state.
- Release providers are selected per Releases widget repository.
- Search.ch is only used by the Timetable widget.
Moving them into widget options makes configuration simpler and removes dead-weight integration code from `packages/integrations`.
## What Changed
### Release Providers
- Added release provider definitions in `packages/definitions/src/release-provider.ts`.
- Removed release providers from `IntegrationKind`.
- Moved release-fetching code out of `packages/integrations` and into `packages/request-handler/src/release-providers.ts`.
- Updated the Releases widget to store provider configuration directly in widget options:
- `provider`
- `identifier`
- `versionFilter`
- `providerUrl`
- Updated the Releases widget editor to use a provider select instead of an integration select.
- Updated Docker import mapping so `ghcr.io` maps to `gitHubContainerRegistry`.
- GitHub Container Registry now uses the public OCI registry API and accepts full image references such as `ghcr.io/homarr-labs/homarr:latest`.
### Timetable / Search.ch
- Removed Search.ch as an integration.
- Added a Timetable widget `baseUrl` option, defaulting to `https://search.ch`.
- Moved Search.ch request/parsing logic into `packages/request-handler/src/timetable.ts`.
- Updated the Timetable API to receive `baseUrl` directly from widget options.
### ArchiveTeam Warrior
- Kept as a proper integration (not removed).
- Removed `defaultUrl` from the integration definition to prevent auto-seeding on first install.
### Integration Cleanup
- Removed creators, exports, docs references, and implementation files for the deleted integrations.
- Removed unused dependencies from `packages/integrations/package.json`.
### Database Migration
- Added `packages/db/migrations/custom/0003_remove_widget_only_integrations.ts`.
- The migration moves old integration-linked widget config into widget options, then deletes the old widget-only integration rows.
- Updated the earlier release widget migration to use the new `provider` field instead of `providerIntegrationId`.
### Docs
- Updated Releases widget docs to describe providers instead of integrations.
- Updated Timetable docs to remove Search.ch integration setup.
- Removed obsolete integration docs pages for the deleted integration kinds.
- Updated docs sitemap and integration docs mappings.
### Translations
- Added English labels for the new widget options:
- `widget.timetable.option.baseUrl.label`
- `widget.releases.option.repositories.providerUrl.label`
## How It Works Now
Release provider configuration lives on each Releases widget repository entry. The request handler resolves provider metadata and fetches releases directly from the provider-specific endpoint. GHCR uses anonymous OCI registry access for public packages.
Timetable passes its widget URL option directly to its API router and request handler. No global integration lookup is needed.
ArchiveTeam Warrior continues to use the standard integration system, but users must manually add the integration (it is not auto-created on install).
## Deliberate Non-Goals
- No provider secret/token support was added.
- No new secret storage model was introduced.
- No compatibility layer was kept in `packages/integrations`.
Widget options are client-visible, so storing provider credentials there would be wrong. If authenticated provider requests are needed later, they need a separate secret-storage design.
## Verification So Far
- Focused typechecks passed for affected packages.
- Full `pnpm turbo typecheck` passed.
- Full `pnpm lint` passed with existing warnings.
- Focused release provider normalization tests passed.
- Widget translation test passed.
- Live GHCR smoke checks passed for `ghcr.io/muchobien/pocketbase:latest` and `ghcr.io/homarr-labs/homarr:latest`.
- `pnpm test packages/integrations/test/pi-hole.spec.ts` passed earlier, but failed on rebased reruns because Pi-hole reported `domainsBeingBlocked` as `-2`/`0` instead of `> 1`.
+1 -214
View File
@@ -1,220 +1,7 @@
# ── CODEOWNERS ───────────────────────────────────────
* @homarr-labs/maintainers
# Specific features / integrations
# These owners come from the PR that introduced each integration implementation.
# Specific rules override the global fallback because CODEOWNERS uses the last
# matching pattern; do not include @homarr-labs/maintainers here unless they
# should also be requested for that integration.
# AdGuard Home - introduced in https://github.com/homarr-labs/homarr/pull/929 by @hillaliy
apps/docs/docs/integrations/adguard-home @hillaliy
packages/integrations/src/adguard-home @hillaliy
# Anchor - introduced in https://github.com/homarr-labs/homarr/pull/5040 by @ohmzi
apps/docs/docs/integrations/anchor @ohmzi
packages/integrations/src/anchor @ohmzi
# ArchiveTeam Warrior - introduced in https://github.com/homarr-labs/homarr/pull/5784 by @darbyjack
apps/docs/docs/integrations/archive-team-warrior @darbyjack
packages/integrations/src/archive-team-warrior @darbyjack
# Bazarr - introduced in https://github.com/homarr-labs/homarr/pull/6156 by @Ayush7614
apps/docs/docs/integrations/bazarr @Ayush7614
apps/docs/docs/widgets/bazarr @Ayush7614
packages/api/src/router/widgets/bazarr.ts @Ayush7614
packages/integrations/src/bazarr @Ayush7614
packages/request-handler/src/bazarr.ts @Ayush7614
packages/widgets/src/bazarr @Ayush7614
# Audiobookshelf - introduced in https://github.com/homarr-labs/homarr/pull/5910 by @ajnart
apps/docs/docs/integrations/audiobookshelf @ajnart
packages/integrations/src/audiobookshelf @ajnart
# Beszel - introduced in https://github.com/homarr-labs/homarr/pull/5900 by @ajnart
apps/docs/docs/integrations/beszel @ajnart
packages/integrations/src/beszel @ajnart
# Codeberg - introduced in https://github.com/homarr-labs/homarr/pull/3253 by @Aandree5
apps/docs/docs/integrations/codeberg @Aandree5
packages/integrations/src/codeberg @Aandree5
# Coolify - introduced in https://github.com/homarr-labs/homarr/pull/4789 by @Rhiz3K
apps/docs/docs/integrations/coolify @Rhiz3K
packages/integrations/src/coolify @Rhiz3K
# Dash. - introduced in https://github.com/homarr-labs/homarr/pull/1541 by @manuel-rw
apps/docs/docs/integrations/dash-dot @manuel-rw
packages/integrations/src/dashdot @manuel-rw
# Docker Hub - introduced in https://github.com/homarr-labs/homarr/pull/3253 by @Aandree5
apps/docs/docs/integrations/docker-hub @Aandree5
packages/integrations/src/docker-hub @Aandree5
# Emby - introduced in https://github.com/homarr-labs/homarr/pull/2466 by @Meierschlumpf
apps/docs/docs/integrations/emby @Meierschlumpf
packages/integrations/src/emby @Meierschlumpf
# GitHub - introduced in https://github.com/homarr-labs/homarr/pull/3253 by @Aandree5
apps/docs/docs/integrations/github @Aandree5
packages/integrations/src/github @Aandree5
# GitHub Container Registry - introduced in https://github.com/homarr-labs/homarr/pull/3727 by @Aandree5
apps/docs/docs/integrations/github-containerregistry @Aandree5
packages/integrations/src/github-container-registry @Aandree5
# GitLab - introduced in https://github.com/homarr-labs/homarr/pull/3253 by @Aandree5
apps/docs/docs/integrations/gitlab @Aandree5
packages/integrations/src/gitlab @Aandree5
# Glances - introduced in https://github.com/homarr-labs/homarr/pull/5102 by @manuel-rw
apps/docs/docs/integrations/glances @manuel-rw
packages/integrations/src/glances @manuel-rw
# Gluetun - introduced in https://github.com/homarr-labs/homarr/pull/5812 by @Lok3sh-kumar
apps/docs/docs/integrations/gluetun @Lok3sh-kumar
packages/integrations/src/gluetun @Lok3sh-kumar
# Gotify - introduced in https://github.com/homarr-labs/homarr/pull/5847 by @Nerdy-Technician
apps/docs/docs/integrations/gotify @Nerdy-Technician
packages/integrations/src/gotify @Nerdy-Technician
# Home Assistant - introduced in https://github.com/homarr-labs/homarr/pull/578 by @manuel-rw
apps/docs/docs/integrations/home-assistant @manuel-rw
packages/integrations/src/homeassistant @manuel-rw
# ICal - introduced in https://github.com/homarr-labs/homarr/pull/3980 by @NicolasNewman
apps/docs/docs/integrations/ical @NicolasNewman
packages/integrations/src/ical @NicolasNewman
# Immich - introduced in https://github.com/homarr-labs/homarr/pull/5165 by @manuel-rw
apps/docs/docs/integrations/immich @manuel-rw
packages/integrations/src/immich @manuel-rw
# Jellyfin - introduced in https://github.com/homarr-labs/homarr/pull/672 by @manuel-rw
apps/docs/docs/integrations/jellyfin @manuel-rw
packages/integrations/src/jellyfin @manuel-rw
# Jellyseerr - introduced in https://github.com/homarr-labs/homarr/pull/774 by @manuel-rw
apps/docs/docs/integrations/jellyseerr @manuel-rw
packages/integrations/src/jellyseerr @manuel-rw
# LinuxServer.io - introduced in https://github.com/homarr-labs/homarr/pull/3607 by @Aandree5
apps/docs/docs/integrations/linux-server-io @Aandree5
packages/integrations/src/linuxserverio @Aandree5
# Navidrome - introduced in https://github.com/homarr-labs/homarr/pull/5910 by @ajnart
apps/docs/docs/integrations/navidrome @ajnart
packages/integrations/src/navidrome @ajnart
# Nextcloud - introduced in https://github.com/homarr-labs/homarr/pull/2501 by @manuel-rw
apps/docs/docs/integrations/nextcloud @manuel-rw
packages/integrations/src/nextcloud @manuel-rw
# npm - introduced in https://github.com/homarr-labs/homarr/pull/3253 by @Aandree5
apps/docs/docs/integrations/npm @Aandree5
packages/integrations/src/npm @Aandree5
# ntfy - introduced in https://github.com/homarr-labs/homarr/pull/2900 by @itzTheMeow
apps/docs/docs/integrations/ntfy @ajnart @manuel-rw
packages/integrations/src/ntfy @ajnart @manuel-rw
# OpenMediaVault - introduced in https://github.com/homarr-labs/homarr/pull/1142 by @hillaliy
apps/docs/docs/integrations/open-media-vault @hillaliy
packages/integrations/src/openmediavault @hillaliy
# OPNsense - introduced in https://github.com/homarr-labs/homarr/pull/3424 by @Oupsman
apps/docs/docs/integrations/opnsense @Oupsman
packages/integrations/src/opnsense @Oupsman
# Overseerr - introduced in https://github.com/homarr-labs/homarr/pull/774 by @manuel-rw
apps/docs/docs/integrations/overseerr @manuel-rw
packages/integrations/src/overseerr @manuel-rw
# Paperless-ngx - introduced in https://github.com/homarr-labs/homarr/pull/5910 by @ajnart
apps/docs/docs/integrations/paperless-ngx @ajnart
packages/integrations/src/paperless-ngx @ajnart
# PatchMon - introduced in https://github.com/homarr-labs/homarr/pull/6119 by @mrjoshuap
apps/docs/docs/integrations/patchmon @mrjoshuap
packages/integrations/src/patchmon @mrjoshuap
packages/widgets/src/patchmon @mrjoshuap
packages/api/src/router/widgets/patchmon.ts @mrjoshuap
packages/request-handler/src/patchmon.ts @mrjoshuap
# PeaNUT - introduced in https://github.com/homarr-labs/homarr/pull/5862 by @afonsojramos
apps/docs/docs/integrations/peanut @afonsojramos
packages/integrations/src/peanut @afonsojramos
# Pi-hole - introduced in https://github.com/homarr-labs/homarr/pull/521 by @Meierschlumpf
apps/docs/docs/integrations/pi-hole @Meierschlumpf
packages/integrations/src/pi-hole @Meierschlumpf
# Plex - introduced in https://github.com/homarr-labs/homarr/pull/1342 by @hillaliy
apps/docs/docs/integrations/plex @hillaliy
packages/integrations/src/plex @hillaliy
# Prowlarr - introduced in https://github.com/homarr-labs/homarr/pull/965 by @hillaliy
apps/docs/docs/integrations/prowlarr @hillaliy
packages/integrations/src/prowlarr @hillaliy
# Proxmox - introduced in https://github.com/homarr-labs/homarr/pull/1969 by @Meierschlumpf
apps/docs/docs/integrations/proxmox @Meierschlumpf
packages/integrations/src/proxmox @Meierschlumpf
# Quay - introduced in https://github.com/homarr-labs/homarr/pull/3607 by @Aandree5
apps/docs/docs/integrations/quay @Aandree5
packages/integrations/src/quay @Aandree5
# search.ch - introduced in https://github.com/homarr-labs/homarr/pull/5180 by @Meierschlumpf
apps/docs/docs/integrations/search-ch @Meierschlumpf
packages/integrations/src/search-ch @Meierschlumpf
# Speedtest Tracker - introduced in https://github.com/homarr-labs/homarr/pull/5363 by @kylegrieder
apps/docs/docs/integrations/speedtest-tracker @kylegrieder
packages/integrations/src/speedtest-tracker @kylegrieder
# Synology - introduced in https://github.com/homarr-labs/homarr/pull/6121 by @mrjoshuap
apps/docs/docs/integrations/synology @mrjoshuap
packages/integrations/src/synology @mrjoshuap
# Technitium DNS - introduced in https://github.com/homarr-labs/homarr/pull/5832 by @lopsch
apps/docs/docs/integrations/technitium-dns @lopsch
packages/integrations/src/technitium @lopsch
# Tracearr - introduced in https://github.com/homarr-labs/homarr/pull/5060 by @StrandedTurtle
apps/docs/docs/integrations/tracearr @StrandedTurtle
packages/integrations/src/tracearr @StrandedTurtle
# TrueNAS - introduced in https://github.com/homarr-labs/homarr/pull/3745 by @manuel-rw
apps/docs/docs/integrations/truenas @manuel-rw @afonsojramos
packages/integrations/src/truenas @manuel-rw @afonsojramos
# Umami - introduced in https://github.com/homarr-labs/homarr/pull/5362 by @febrile42
apps/docs/docs/integrations/umami @febrile42
packages/integrations/src/umami @febrile42
# UniFi Controller - introduced in https://github.com/homarr-labs/homarr/pull/2236 by @pitschi
apps/docs/docs/integrations/unifi-controller @pitschi
packages/integrations/src/unifi-controller @pitschi
# Unraid - introduced in https://github.com/homarr-labs/homarr/pull/4439 by @manuel-rw
apps/docs/docs/integrations/unraid @manuel-rw
packages/integrations/src/unraid @manuel-rw
# Uptime Kuma - introduced in https://github.com/homarr-labs/homarr/pull/5910 by @ajnart
apps/docs/docs/integrations/uptime-kuma @ajnart
packages/integrations/src/uptime-kuma @ajnart
# Traefik - by @Nerdy-Technician
apps/docs/docs/integrations/traefik @Nerdy-Technician
apps/docs/docs/widgets/traefik @Nerdy-Technician
packages/api/src/router/widgets/traefik.ts @Nerdy-Technician
packages/integrations/src/traefik @Nerdy-Technician
packages/request-handler/src/traefik.ts @Nerdy-Technician
packages/widgets/src/traefik @Nerdy-Technician
# Exempt Renovate-managed files (no owners)
# Exempt Renovate‑managed files (no owners)
package.json
**/package.json
package-lock.json
+1 -2
View File
@@ -1,4 +1,4 @@
FROM node:24.18.0-alpine AS base
FROM node:24.16.0-alpine AS base
FROM base AS builder
RUN apk add --no-cache libc6-compat
@@ -42,7 +42,6 @@ RUN mkdir -p /var/cache/nginx && \
COPY --from=builder /app/apps/nextjs/next.config.ts .
COPY --from=builder /app/apps/nextjs/package.json .
COPY --from=builder /app/pnpm-workspace.yaml ./pnpm-workspace.yaml
COPY --from=builder /app/node_modules/better-sqlite3/build/Release/better_sqlite3.node /app/build/better_sqlite3.node
-6
View File
@@ -1,6 +0,0 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.git
-1
View File
@@ -1 +0,0 @@
* text=auto eol=lf
-58
View File
@@ -1,58 +0,0 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
.idea/
# dependencies
/node_modules
/.pnp
.pnp.js
.pnpm-store/
# testing
/coverage
# next.js
/.next/
/out/
# production
/build
# misc
.DS_Store
*.pem
# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# local env files
.env.local
.env.development.local
.env.test.local
.env.production.local
# vercel
.vercel
*.tsbuildinfo
# storybook
storybook-static
static/data/configs
# https://yarnpkg.com/getting-started/qa#which-files-should-be-gitignored
# Yarn v2
.pnp.*
.yarn/*
!.yarn/patches
!.yarn/plugins
!.yarn/releases
!.yarn/sdks
!.yarn/versions
# docusaurus
.docusaurus
# CI Stuff
screenshots
test-results
-33
View File
@@ -1,33 +0,0 @@
{
"$schema": "../../node_modules/oxlint/configuration_schema.json",
"plugins": ["eslint", "typescript", "unicorn", "oxc", "react", "import", "jsx-a11y"],
"categories": {
"correctness": "error",
"suspicious": "warn",
"pedantic": "off",
"perf": "off",
"style": "off",
"restriction": "off",
"nursery": "off"
},
"rules": {
"eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_" }],
"typescript/consistent-type-imports": "off",
"typescript/no-non-null-assertion": "warn",
"import/consistent-type-specifier-style": "off",
"jsx-a11y/alt-text": "warn",
"jsx-a11y/control-has-associated-label": "warn",
"jsx-a11y/prefer-tag-over-role": "warn",
"react/jsx-key": "warn",
"react/react-in-jsx-scope": "off",
"react-hooks/exhaustive-deps": "warn",
"eslint/no-unused-expressions": "warn"
},
"options": {
"reportUnusedDisableDirectives": "off"
},
"ignorePatterns": ["**/*.config.js", "**/*.config.mjs", "**/*.cjs", ".docusaurus/**", "build/**"],
"settings": {
"react": { "version": "19" }
}
}
-10
View File
@@ -1,10 +0,0 @@
{
"cSpell.words": [
"Homarr",
"Lidarr",
"Nextcloud",
"Radarr",
"Readarr",
"Sonarr"
]
}
-201
View File
@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2025 Meier Lukas, Thomas Camlong and Homarr Labs
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-105
View File
@@ -1,105 +0,0 @@
# Homarr Documentation (`@homarr/docs`)
The official [homarr.dev](https://homarr.dev) documentation site, built with [Docusaurus 3](https://docusaurus.io/) and living inside the Homarr monorepo.
## Why it's in the monorepo
Having documentation alongside the application code enables:
- **Two-way linking** — the docs app imports from `@homarr/definitions` for type-safe integration/widget metadata, and the main app references doc paths via generated sitemap types
- **Atomic PRs** — code changes and their documentation updates ship in the same pull request
- **Shared tooling** — same Node version, pnpm catalog, oxlint/oxfmt, CI pipeline
- **Build-time validation** — Docusaurus strict mode catches broken links and references at build time
## Development
From the **monorepo root**:
```bash
# Start the docs dev server (port 3003)
pnpm dev:docs
# Or from within this directory
pnpm dev
```
## Build
```bash
# Build docs only
pnpm turbo build --filter=@homarr/docs
# Build everything (docs + main app + tasks + websocket)
pnpm build
```
## Lint & Format
Uses oxlint and oxfmt (same as the rest of the monorepo):
```bash
pnpm lint # oxlint
pnpm format # oxfmt (check)
pnpm format -- --write # oxfmt (fix)
```
## Typecheck
```bash
pnpm typecheck
```
## Content Structure
```
docs/
├── getting-started/ # Installation guides, glossary, prerequisites
├── management/ # Boards, apps, users, integrations, settings, tasks, API
├── integrations/ # 55 integration guides (one folder each)
├── widgets/ # 42 widget guides (one folder each)
├── advanced/ # SSO, env vars, proxy, styling, CLI, development
└── community/ # FAQ, donate, license, translations, get-in-touch
```
Each integration/widget doc follows a consistent pattern:
- `index.ts` — typed metadata (`IntegrationDefinition` / `WidgetDefinition`)
- `index.mdx` — content using shared React components (`IntegrationHeader`, `WidgetHeader`, etc.)
## Importing from homarr packages
The docs app has `@homarr/definitions` as a workspace dependency. You can import integration kinds, widget kinds, and other definitions directly:
```typescript
import { IntegrationKind } from '@homarr/definitions';
```
This enables type-safe references to homarr domain concepts within documentation code.
## Search (Algolia DocSearch)
Search uses the `Docusaurus` Algolia index (crawler `cd77a285-2756-4557-bf21-ee703748df15`). A separate `markdown` index is built for LLM markdown indexing.
Crawler reference config: [`docsearch.config.js`](docsearch.config.js).
**Verify search health:**
```bash
pnpm verify:search
```
## Tech Stack
| Layer | Technology |
|---|---|
| Site generator | Docusaurus 3 (`@docusaurus/preset-classic`) |
| Styling | Tailwind CSS 3 + Docusaurus Infima |
| Icons | `@tabler/icons-react` |
| Diagrams | Mermaid (`@docusaurus/theme-mermaid`) |
| Search | Algolia DocSearch |
| Analytics | PostHog |
| Charts | @nivo/line |
## Contributing
When making changes to the homarr codebase that affect user-facing behavior, **always update the corresponding documentation in this app**. See `.cursor/rules/documentation-sync.mdc` for the complete mapping of code changes to doc locations.
@@ -1,35 +0,0 @@
---
slug: documentation-migration
title: Migration of Documentation
authors:
- ajnart
- manuel-rw
tags: [documentation, migration]
---
We are happy to announce that the documentation of Homarr has been migrated to Docusaurus - An opensource documentation tool.
The documentation has been re-written partly and includes now many animations, guides and additional crucial information.
We are still figuring things out and highly depend on your feedback.
<!-- truncate -->
## Why we migrated
The default GitHub Wiki feature is decent - but very confusing to read.
Our possibilites for searching the documentation in the Wiki are highly limited.
Additionally, Users are unable to contribute to the documentation if they have not sufficient permissions.
We could not review any chanegs made to the documentation. This is why we migrated to Docusaurus.
## How you can contribute
The documentation will soon be merged into the master branch of Homarr.
You'll find a ``doc/`` directory in the root of Homarr.
We'll obviously not include this in our Docker images.
In the future, everyone may modify the documentation by creating a pull request.
After we've reviewed your changes, we'll merge your PR and this documentation will automatically update.
## TL;DR
The documentation on GitHub Wiki will soon disappear. It will be replaced with this Docusaurus-powered website. You'll find much more information here with higher detail and searchability.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 29 KiB

@@ -1,20 +0,0 @@
---
slug: translations
title: Help us make Homarr multilingual
authors:
- ajnart
- manuel-rw
tags: [translations, homarr, update, contributions]
---
We've been working hard to offer Homarr in many languages. The next update of Homarr will be using [i18next](https://www.i18next.com/) to translate almost any part of your Dashboard.
### We need your help
![](img/homarr-we-need-you.webp) <br/>
Yes, we need **YOU**! We want to make Homarr accessible to as many people as possible. Thus, we need to translate all content into many different languages. We need your help for that! [You can help us now to translate Homarr into as many languages as possible](/docs/community/translations).
<!-- truncate -->
### About global translations / translations per user
We are aware that many people would like to configure translations globally or configure language per user. Currently, translations are stored in the Cookies, which will expire after some time (currently, it's set to 30 days). We will implement more granular language settings in future versions of Homarr, since it requires major changes to Homarr. Stay tuned! 😎
Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

@@ -1,67 +0,0 @@
---
title: "We present: Homarr 0.11 - the most complex Homarr version yet!"
authors:
- ajnart
- manuel-rw
- walkx
- meierschlumpf
tags: [homarr, update, breaking changes, version, gridstack, dnd, documentation]
---
We are *incredibly* proud to serve you Homarr 0.11!
It contains many breaking changes and huge improvements to your favourite dashboard app:
- Integration of Gridstack for much more complex dashboard configuration and drag and drop
- Added icon picker with smart search and automatic icons
- Complete overhaul of the module system
- Added an edit mode for making changes easier
- Form validation for better user experience
- Better security with new built-in credentials system
- Huge design and usability improvements to older components to Homarr
- Better handeling of exceptions and unexpected issues
<!-- truncate -->
## Complete implementation of highly customizable drag and drop library "Gridstack"
In 0.11, we have replaced our quite limited drag and drop system with Gridstack.
Gridstack enables you to create much more complex and advanced dashboards while keeping everything organized.
<video style={{ maxWidth: "min(100%, 600px)", borderRadius: "0.5rem"}} controls preload='auto' autoplay >
<source src="https://user-images.githubusercontent.com/30572287/217098893-5880e7de-13d0-42c5-b505-f7921593396f.mp4" type="video/mp4" />
<p>
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank">
supports HTML5 video
</a>
</p>
</video>
We've also introduced more advanced categories this time:
![](../../../docs/getting-started/img/category-menu.webp)
We'll continute to improve this system according to your feedback.
## Modules have been overhauled and renamed to widgets
Widgets are now much snappier and have been completely recoded.
This fixes some of the bugs a few users have previously experienced and improves overall customization.
![](./img/choose-widget-in-modal.webp)
## Fancy icon picker for speeding up your creation process
We've also added a new fancy icon picker, you can use to get access to any icons much faster.
We will add more icon sources in the future, as we made this icon picker very modular, and we plan to make local icons accessible via this picker very soon.
![](../../../docs/advanced/customizations/img/icons/icons-picker.gif)
## Design and documentation improvements to homarr.dev
https://homarr.dev has been overhauled with better design, updated documentation, more images and better explanations.
## Download Homarr now!
Homarr is completly free, even for commercial usage!
@@ -1,75 +0,0 @@
---
title: "We present: Homarr 0.12 - The fastest homarr version ever!"
authors:
- ajnart
- manuel-rw
- walkx
- meierschlumpf
tags: [homarr, update, breaking changes, version, dnd, documentation]
---
## Multiple widgets of the same type
**It's finally here!** You can decorate your dashboard now with as many widgets as you want.
This applies to all widgets, but in the case of the IFrame widget, it enables you to:
- Integrate as many websites as you want
- Integrate monitoring tools like Grafana, Splunk or Elasticsearch
- Integrate your services (for example Sonarr, Radarr and Overseerr) directly into Homarr
![](https://media.discordapp.net/attachments/988335098493542410/1094665745226539168/update-teaser.png?width=1046&height=666)
## Edit mode password
We've added a setting to disable editing completely. This will allow you to restrict edit access without password-protection.
use the `EDIT_MODE_PASSWORD` ENV variable to set a password for edit mode.
turn on `DISABLE_EDIT_MODE=TRUE` to disable edit mode on startup.
<!-- truncate -->
## 😎 Blazingly fast
We've implemented a new caching system, that will cache all data in your browser, meaning that Homarr will load within milliseconds, as if it was *powered by rust and blazingly fast* !!!
## Media request widgets (Overseerr & Jellyseerr)
We've implemented a new widget, that displays a history of all requests.
You can't approve from the widget yet, but we plan to add this in the future.
![image](https://user-images.githubusercontent.com/30572287/231829411-f61f03e9-79a0-45fc-9a87-94d69ea3ea84.png)
## Multiple RSS feeds
You can now consume multiple RSS feeds at the same time:
![image](https://user-images.githubusercontent.com/30572287/231829886-69133a84-3ae7-4fa3-a6d2-c582f4cc9eea.png)
## Tab refresh / close confirmation
Since some have lost their changes, by refreshing the page in the edit mode. We've added a popup that will ask you to confirm you want to reload the page :
![image](https://user-images.githubusercontent.com/30572287/231823776-9cbb12d4-3cb3-422e-b2e8-f9917bb3f8cc.png)
## Environment variable for default theme
You can now set the default color scheme using environment variables:
``DEFAULT_COLOR_SCHEME`` = ``[dark, light]``
## Global error catching for widgets
Previously, widgets were able to crash your entire dashboard and just a blank page would be displayed.
Now, users will still be able to use their dashboard and an information message will be displayed instead.
## Migration to Mantine V6
We've migrated Mantine to version 6. This will bring some upstream changes for responsiveness and usability.
## Fix width and height in the calendar
In 0.11.5 and previous versions, the calendar scaled poorly if the widget was resized.
Now, the calendar will fill out the entire available space and scale nicely with your dashboard.
![](https://cdn.discordapp.com/attachments/988335098493542410/1095416419816067175/homarr-calendar-scaling.gif)
## Performance improvements
We now use several methods to improve performance and reduce network requests.
Homarr will load now within milliseconds and cache data in your browser.
## Docker Socket via TCP
Previously, it was not possible to mount sockets via TCP (eg. ``tcp://traefik-docker-socket-proxy:2375``).
Now, you can use the following environment variables to configure this:
- ``DOCKER_HOST``
- ``DOCKER_PORT``
**Full Changelog**: https://github.com/ajnart/homarr/compare/v0.11.5...v0.12.0
@@ -1,86 +0,0 @@
---
title: "Authentication in Homarr - 0.14 is here!"
authors:
- ajnart
- manuel-rw
- tagashi
- meierschlumpf
tags: [homarr, update, breaking changes, version, authentication, notepad, security]
---
One of the most requested features ever has arrived.
We worked for months to prepare Homarr for this update and we're happy that we can finally
provide you a viable solution today.
## Highlights at a glance
- :rocket: Completly overhauled authentication system with user management
- :sparkles: Improved UI for boards (renamed dashboards to boards).
- :computer: Server side preferences -> Dark mode and language are not synced accross all your devices
- :link: Invitation links to easily onboard new users
- :busts_in_silhouette: Overhauled board management with easy control if anonymous users can view your board
- :brain: AI assistant on the documentation to answer your questions: https://homarr.dev/
- 📝 Overhauled notepad widget with a complex graphical editor that enables easy editing right from your browser.
- :globe_with_meridians: Live Translation on Crowdin that enable you to directly translate using images to see what exactly you're translating
<!-- truncate -->
## Breaking changes
- Removed ``PASSWORD`` environment variable
- Removed ``DISABLE_EDIT_MODE`` environment variable
- Removed ``EDIT_MODE_PASSWORD`` environment variable
- Added mounting point ``/data`` for your database
- Require at least one administrator account on your instance. An onboarding process will automatically set this up.
- We've added analytics to the documentation and Homarr itself. We use [Umami Analytics](https://umami.is/) which collects anonymous data exclusively and protects your personal data rights. You can disable this using the environment variable ``DISABLE_ANALYTICS``.
## Changes in detail
### Management pages
![image](https://github.com/ajnart/homarr/assets/30572287/b325eb92-57a6-4b07-a281-f10f7471642e)
One of the most requested features ever has been ___authentication___. We've completely *removed* the ``PASSWORD``, ``DISABLE_EDIT_MODE`` and ``EDIT_MODE_PASSWORD`` and replaced it by [a secure authentication system](https://next-auth.js.org/) that enables you to manage multiple users easily. We will allow for more detailed permission and user management soon. LDAP and OIDC integrations are currently also in progress and will arrive in a future version.
### New dashboard layout
![image](https://github.com/ajnart/homarr/assets/30572287/3396da13-816a-434f-a4c1-0efc7f86154c)
We've updated the dashboard user interface slightly to an updated design.
### Server side preferences page
![image](https://github.com/ajnart/homarr/assets/30572287/2c1f4dbe-7aa7-4c56-aaa3-d6c49e2beeec)
Previously, preferences were stored per dashboard and applied to all users.
In this release, we moved this page to a separate link and store this on the server.
This means that regardless what device your on - your preferences will stay the same when you're logged in.
### Invitations for new users
![image](https://github.com/ajnart/homarr/assets/30572287/a929b345-c014-48fb-aef9-ea2c3c581376)
Tired of creating user accounts by yourself? With the new "invites" feature you can invite new users by simply sending them a link.
This link is valid only once and must have an expiration date - more info on that in our documentation.
Additionally, you can deny users, that are not logged into an account, to access your board with a simple toggle:
![image](https://github.com/ajnart/homarr/assets/30572287/aa3ff3fb-66fc-4f88-93fb-b2dd819599a8)
### New "boards" page
Previously, dashboards were managed in an ugly and hard to control popup.
We've moved this now to the new management pages as well and it's now much easier to control:
![image](https://github.com/ajnart/homarr/assets/30572287/2b24222e-da33-45eb-a54f-89a33a21881d)
### Read-only for non-administrators and guests
Yes, managing access to your dashboard is now much easier!
Guests and non-administrators cannot edit your dashboard in any way (edit is hidden):
![image](https://github.com/ajnart/homarr/assets/30572287/01c48beb-5453-4626-ac4d-f8d7177e999b)
This is not an definite solution and will be significantly improved in an upcoming update.
-----
We are aware that this update has many breaking changes and may confuse some users.
For that reason, we updated our documentation and will enhance it further within the next few weeks.
We've also added this small button at the bottom of the page were you can ask **your questions** to an AI assistant:
![image](https://github.com/ajnart/homarr/assets/30572287/a56f721a-d022-42ad-813a-d85c89462a8c)
@@ -1,21 +0,0 @@
---
title: "Updated documentation with better organization & design"
authors:
- manuel-rw
tags: [homarr, documentation, design, docs]
---
We'd like to let you know that we've updated our documentation and reorganized the pages.
This means, that some links may no longer be valid - we apologise if this causes any inconvenience for you.
<!-- truncate -->
A few highlights include:
- Updated navigation bar for much easier navigation
- Improvements to the landing page
- Completely revamped [about us page.](/about-us)
- Bug fixes for image zoom
- Added documentation for management pages and [new CLI tool](/docs/advanced/command-line/password-recovery/)
Please [let us know](/docs/community/get-in-touch) is something is not working as expected.
@@ -1,88 +0,0 @@
---
authors:
- manuel-rw
---
# Homarr 1.0 - complete rewrite of all systems
We proudly present to you - Homarr ``1.0``.
We have started work on this new version back in 2023 and have worked tirelessly for months on this brand-new dashboard.
This isn't our usual update. ``1.0`` doesn't use the same code from previous versions, but has been written from the ground up.
Therefore, this version contains an unusual amount of breaking changes.
This will be a one time occurrence and version > ``1.0`` will have less breaking changes.
This time more important than every; **read the breaking changes** list and **create a backup** before updating.
Some third party installation methods may take multiple days or weeks to update to the new version.
See [this guide on how to import your previous Homarr dashboard](/docs/getting-started/after-the-installation#importing-a-zip-from-version-before-100)
## Changes at a glance
- **Asynchronous integrations system**: In versions prior to ``1.0``, we fetched data upon each request synchronously.
This means that the user had to wait for the requests to finish so any data would appear.
A page reload will trigger another request - and worse, this will happen for every user accessing your dashboard.
In ``1.0``, we have implemented a new system that gets rid of this system and scales linearly.
It will fetch data in background, even if you are not on the page.
- **Permissions system**: You can now use detailed permissions to allow or prohibit users from certain actions.
For easier management, you can organize users into groups and manage them all at the same time.
- **Integration testing**: Starting from ``1.0``, we will require you to test the integration before you can use it.
This guarantees that you've configured your integration correctly and helps you find errors faster.
- **Re-imagined widgets**: All widgets have been rewritten & improved. They offer much better performance,
reliability and scalability compared to < ``1.0``.
- **Improved performance**: We have upgraded the underlying framework of Homarr and take advantage
of an in-memory message bus and websockets to deliver data near realtime to you.
<!-- truncate -->
## Breaking changes
:::warning
Please consult the breaking changes list & upgrade guide if you used third-party installation methods.
:::
- Docker Image
- Removed support for ``arm/v7`` -> upgrade to newer architectures as an alternative
- Renamed image from ``ghcr.io/ajnart/homarr`` to ``ghcr.io/homarr-labs/homarr``. We now use semantic versioning for our release numbers.
- Environment Variables
- New required env variable ``SECRET_ENCRYPTION_KEY`` used for encryption of secrets in the database
- Removed ``DISABLE_ANALYTICS``, can now be configured via UI
- Renamed ``AUTH_PROVIDER`` to ``AUTH_PROVIDERS``
- Renamed ``DATABASE_URL`` to ``DB_URL`` and made it optional conditionally. If ``DB_HOST`` is set, this is optional - otherwise it's required.
- Changed ``DOCKER_HOST`` to two new variables for hostnames (``DOCKER_HOSTNAMES``) and ports (``DOCKER_PORTS``). This allows for multiple docker integrations to be configured.
- ``AUTH_LOGOUT_REDIRECT_URL`` must now be a valid Url
- Increased minimum length of ``AUTH_OIDC_CLIENT_ID`` to 1
- Increased minimum length of ``AUTH_OIDC_CLIENT_SECRET`` to 1
- Removed ``AUTH_OIDC_TIMEOUT``
- Removed ``AUTH_LDAP_ADMIN_GROUP``, ``AUTH_LDAP_OWNER_GROUP``, ``AUTH_OIDC_ADMIN_GROUP`` and ``AUTH_OIDC_OWNER_GROUP`` -> groups are now managed without manual env binding
- ``CI`` will now also trigger an env validation skip like ``SKIP_ENV_VALIDATION``
- Mounts
- Removed ``/app/data/configs`` -> JSON configs have been removed in favour of relation databases
- Removed ``/app/public/icons`` -> Images can not be uploaded via the [media management](/docs/management/media/) in the UI
- Moved ``/data`` to ``/appdata`` and restructured contents (not backwards compatible!) -> Create a backup before migration of the entire directory to copy data to new Homarr
- Widgets:
- Calendar:
- Removed option ``Use Sonarr v4 API``
- Removed option ``Use Sonarr v5 API``
- Removed option ``Font Size``
- Removed option ``Hide week days``
- Download speed: We have removed this widget in favour of the brand new download widget which will also display this data.
- Dash. widget: We have removed this widget in favour of the System Health Widget. It will also display all data and some more than the old widget.
- Database:
- Changed schema of the database to a completely new schema. They are not backwards compatible. Please export the data from old Homarr in the UI and import it in ``1.0``
- Removed all usage of JSON files to store data. Import JSON files in Homarr ``1.0`` to import your dashboards.
- Removed ``schemaVersion`` from JSON and use the drizzle migrations to keep track of schema versions and take care of migrations.
- Web Server:
- Added an internal Nginx proxy to forward requests to two servers inside the container for technical reasons.
This could impact edge cases with iframes, cookies and custom setups.
- Dependencies
- We now depend on [Redis](https://redis.io/) as a real time messaging bus
- Development (relevant for contributors):
- Migrated to [pnpm](https://pnpm.io/)
- Migrated to a mono-repository
- All source code has been migrated to the [homarr-labs GitHub organization](https://github.com/homarr-labs)
- Platform specific breaking changes:
- TrueNAS
- The TrueCharts app chart is permanently deprecated and no longer maintained / supported. Please migrate to Electric Eel or a different Kubernetes platform.
- Unraid
- The Homarr app must be reinstalled. The existing directories on your disk are not compatible with Homarr 1.0. Export your old data in < `` 1.0`` and install using different file system locations.
- Kubernetes
- The official Helm chart has moved from https://github.com/oben01/charts to https://github.com/homarr-labs/charts
@@ -1,39 +0,0 @@
---
authors:
- meierschlumpf
---
# Open Beta 1.0
We are proud to announce the open beta of Homarr 1.0. This is a major milestone for us and we are excited to share it with you.
The open beta allows us to polish the last rough edges and gather feedback from you.
We are looking forward to your feedback and hope you enjoy the new features.
Let us know throgh discord or a [github issues](https://github.com/homarr-labs/homarr/issues/new/choose) if you encounter any issues.
<!-- truncate -->
## How to use the beta with docker
To use the beta with docker you can use the following docker-compose.yml configuration:
```yml title="docker-compose.yml"
#---------------------------------------------------------------------#
# Homarr - A simple, yet powerful dashboard for your server. #
#---------------------------------------------------------------------#
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:beta
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Optional, only if you want docker integration
- ./homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
ports:
- '7575:7575'
```
Then, run `docker compose up -d` in the same directory. This will start the Homarr container in the background.
Please note that the mounts have changed and it's not backwards compatible with versions before 1.0.0-beta.1.
You can find a list of all breaking changes [here](/blog/2024/09/23/version-1.0)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

@@ -1,55 +0,0 @@
---
authors:
- meierschlumpf
---
# Migrate from 0.15.10+ to 1.0.0
In this guide, we will show you how to migrate from Homarr 0.15.10+ to 1.0.0.
If you are still on a version before 0.15.10, please update to 0.15.10 where we introduced the migration export page.
<!-- truncate -->
## Export your data
As 1.0 is a complete rewrite of Homarr and therefor not compatible with the old docker mounts, we need to export your data first.
For this you can navigate to the `Migrate to 1.0` page which you can find under `Management` > `Tools` > `Migrate to 1.0`.
Here you can select which things you want to export and download the zip file.
It will also show you a secret key which you will need to import the secret data like user password hashes, salts and integration secrets.
![Export page](./img/old-homarr-export-data.png)
## Create a parallel installation
We highly recommend to create a parallel installation of Homarr 1.0.0.
So if something with for example the import does not quite work, the data in the old installation is still available.
To do this you can follow the appropriate [installation guide](https://homarr.dev/docs/category/installation-1) for your system.
Please note that if you are using docker you need to specify a diffrent external port for the new installation as the old one had the same port.
So in your compose file the ports would be `7576:7575` instead of `7575:7575`.
## Import your data
Once the installation is completed you can access the new installation. During the onboarding you'll need to select `Import from Homarr before 1.0`.
![Onboarding initial step](./img/onboarding-step-1.png)
After that you can upload the zip file you downloaded in the first step.
![Onboarding import dropzone](./img/old-homarr-import-dropzone.png)
After that you'll get a list with all your boards that can be imported. You can configure how it should be imported and can select which screensizes it should import.
![Onboarding import list](./img/old-homarr-import-choose-imported-data.png)
Once you have selected everything you can click on `Confirm import and continue` which will open the encryption key input dialog where you can input the secret key you got during the export.
![Onboarding import key input](./img/old-homarr-import-decryption-token.png)
After that you can continue the onboarding and you should see all your boards and data in the new installation.
See [After the installation](https://homarr.dev/docs/getting-started/after-the-installation) for more information.
## Remove the old installation
After you are happy with the new installation and everything is working as expected you can remove the old installation.
Please make sure to backup the data before you remove the old installation.
Also once the port 7575 is free again you can change the port mapping of the new installation to `7575:7575` if you want to.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 113 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

@@ -1,67 +0,0 @@
---
authors:
- meierschlumpf
---
# How to use Argus with Homarr
In `v1.32.0` we added the endpoint `/api/info` which returns the current version of Homarr and can therefore be used in Argus to watch for updates.
This guide will show you how to set up a user with apiKey to access the endpoint without providing admin access through it.
<!-- truncate -->
![Argus](./img/argus.png)
Currently an apiKey has the same permissions as the user who created it, however you can only create an apiKey with admin permissions.
This means we have to do some extra steps to create a user with only the permissions we need for Argus.
## Create a group
In a first step we have to create a group which will allow us to restrict the permissions of the user we will create later.
1. Go to `Management` > `Users` > `Groups`
2. Click on `Create group`
3. Enter a name for the group, e.g. `Argus`
4. Click on `Create group`
5. Click on the newly created group to edit it
6. In the `Permissions` tab, select the admin permission and save the changes
## Create a user
Now we can create a user which will be used by Argus to access the `/api/info` endpoint.
1. Go to `Management` > `Users` > `Manage`
2. Click on `Create new user`
3. Enter a username, e.g. `argus`, click next
4. Enter a password for the user, click next
5. Add previously created group `Argus` to the user, click next
6. Click on next to confirm the user creation
## Create an apiKey
Now we want to create therefore we have to log in with the user we just created.
1. Log out of Homarr
2. Log in with the user we just created
3. Go to `Management` > `Tools` > `API Keys`
4. Click on `Create API Key`
5. Copy the generated API key and save it somewhere, you will not be able to see it again
6. Logout of Homarr
## Reduce permissions of the user
Now we can reduce the permissions of the user to only allow access to general authenticated, but not permission restricted endpoints.
1. Log in with your admin user
2. Go to `Management` > `Users` > `Groups`
3. Click on the `Argus` group
4. In the `Permissions` tab, remove all permissions
5. Save the changes
## Configure Argus
Now you can configure Argus to use the user and apiKey we created.
![Argus configuration](./img/argus-configuration.png)
Replace the `<secret>` with the apiKey you created and the deployed version url with the url of your Homarr instance.
-37
View File
@@ -1,37 +0,0 @@
manuel-rw:
name: Manuel
page: true
url: https://github.com/manuel-rw
image_url: https://avatars.githubusercontent.com/u/30572287?v=4
socials:
github: manuel-rw
description: >
Junior .NET developer from Switzerland. 🌌 .NET, Next.js, Node.js, Angular
ajnart:
name: Ajnart
page: true
url: https://github.com/ajnart
image_url: https://avatars.githubusercontent.com/u/49837342?v=4
socials:
github: ajnart
meierschlumpf:
name: Meierschlumpf
page: true
url: https://github.com/Meierschlumpf
image_url: https://avatars.githubusercontent.com/u/63781622?v=4
socials:
github: Meierschlumpf
tagashi:
name: Tagashi
page: true
url: https://github.com/tagaishi
image_url: https://avatars.githubusercontent.com/u/26098587?v=4
socials:
github: tagaishi
walkx:
name: Walkx
page: true
url: https://github.com/walkxcode
image_url: https://avatars.githubusercontent.com/u/71191962?v=4
socials:
github: walkxcode
-9
View File
@@ -1,9 +0,0 @@
{
"label": "Advanced",
"collapsed": true,
"position": 4,
"link": {
"type": "generated-index",
"title": "Advanced Concepts or features"
}
}
@@ -1,4 +0,0 @@
{
"collapsed": true,
"label": "Command line interface"
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

@@ -1,17 +0,0 @@
# Fix usernames
:::info
This guide requires that you understand [how to access the CLI](../).
:::
If you somehow get into a situation where you have users with usernames that contain uppercase characters and you are no longer able to log in, you can use the following command to fix the usernames.
```bash
homarr fix-usernames
```
This will convert all credential usernames to lowercase and update the database accordingly.
![](./img/screenshot-cli.png)
Binary file not shown.

Before

Width:  |  Height:  |  Size: 195 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 348 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 414 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

@@ -1,27 +0,0 @@
# Command line interface
The Homarr image ships with a built-in recovery tool. This can be useful, if you do not have access to Homarr or if something is not working.
Please note that the CLI is an *emergency tool*, not an API tool.
:::caution
Using the recovery CLi tool can cause problems when requests are being sent to Homarr while the tool is running. \
You should also create a backup of the database, in case you break something.
:::
## Execute CLI with Docker
1. Execute ``docker ps | grep homarr`` on the root system with Docker to find the container ID of your Homarr container.
2. Run ``docker exec -it <container-id> /bin/bash homarr <your-command-goes-here>``. \
Replace ``<container-id>`` with your container ID from step 1. \
Replace ``<your-command-goes-here>`` with the command you want to execute (see sub-pages).
## Execute CLI with QNAP
1. Open Container Station in the QNAP Web Interface ![](img/334116069-e7ec4726-3df7-4dc6-a3e0-b745e7eef17f.png)
2. Select Containers in the menu bar on the left ![](img/334116205-aa09ce40-0701-4f7d-b9f9-b431b9d207c5.png)
3. Select your Homarr Container ![](img/334116303-714b5e07-b9de-4ec0-a2bc-def7ee38750f.png)
4. Click "Execute" in the top right of the Window. ![](img/334116411-df1482f9-3aa9-4686-b77f-e0dca09e60b2.png)
5. Select /bin/bash and click Execute ![](img/334116518-e1ddb515-99c7-4159-81bf-76e889d1e808.png)
6. Run the Homarr command and press enter (eg. homarr reset-owner-password) ![](img/334116642-08c4f204-5cd0-4e4e-a785-0142e1b279ca.png)
@@ -1,60 +0,0 @@
# Integrations
:::info
This guide requires that you understand [how to access the CLI](../).
:::
Using these commands, you can manage the integrations from the CLI:
```bash
Group of commands to manage integrations
Usage:
homarr integrations [command]
Available Commands:
list List all integrations (id and name)
delete Delete an integration by id or name
Flags:
-h, --help help for integrations
-v, --version version for homarr-cli
Use "homarr integrations [command] --help" for more information about a command.
```
## List Integrations
- Requires a database connection
- Lists all configured integrations
```bash
List all integrations (id and name)
Usage:
homarr integrations list [flags]
Flags:
-h, --help help for integrations list
-v, --version version for homarr-cli
```
## Delete Integration
- Requires a database connection
- Requires one parameter: ``id`` or ``name``
- Deletes an integration permanently from the database
```bash
Delete an integration by id or name
Usage:
homarr integrations delete [flags]
Flags:
-i, --id string ID of the integration
-n, --name string Name of the integration
-h, --help help for integrations delete
-v, --version version for homarr-cli
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.8 KiB

@@ -1,19 +0,0 @@
# Password Recovery
:::info
This guide requires that you understand [how to access the CLI](../).
:::
Using this command, you can forcefully reset the password of a user.
It will be set to a random value and the hash for the user will be updated.
All sessions for that user will be terminated and the user must re-login.
![](./img/screenshot-cli.png)
Using the ``--username`` parameter, you can specify who you want to reset the password for.
Executing the command will create a new random password, update the database and display the new password.
All sessions for this user will be terminated and they must re-login.
![](./img/screenshot-cli-result.png)
@@ -1,79 +0,0 @@
# Users
:::info
This guide requires that you understand [how to access the CLI](../).
:::
Using these commands, you can manage the users from the CLI:
```bash
Group of commands to manage users
Usage:
homarr users [command]
Available Commands:
list List all users (id, username, email)
delete Delete a user by id or username
update-password Update the password for a user (credentials provider only)
Flags:
-h, --help help for users
-v, --version version for homarr-cli
Use "homarr users [command] --help" for more information about a command.
```
## List Users
- Requires a database connection
```bash
ID Username Email
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
```
## Delete User
- Requires a database connection
- Requires one parameter: ``id`` or ``username``
```bash
Delete a user by id or username
Usage:
homarr users delete [flags]
Flags:
-i, --id string ID of the user
-u, --username string Name of the user
-h, --help help for users delete
-v, --version version for homarr-cli
```
## Update Password
- Updates the password of an user
- Requires database connection
- Requires either a username or id
- Requires a password (which will be encrypted by Homarr)
```bash
Update the password for a user (credentials provider only)
Usage:
homarr users update-password [flags]
Flags:
-i, --id string ID of the user
-u, --username string Name of the user
-p, --password New password
-h, --help help for users update-password
-v, --version version for homarr-cli
```
Binary file not shown.

Before

Width:  |  Height:  |  Size: 757 KiB

@@ -1,9 +0,0 @@
{
"label": "Developer guides",
"position": 6,
"collapsed": true,
"link": {
"type": "generated-index"
}
}
@@ -1,68 +0,0 @@
---
title: Getting started
tags:
- Developer
- Technical documentation
- Code
- Programming
sidebar_position: 1
---
## Setting up your development environment
This guide will help you set up your development environment to start contributing to homarr.
### Prerequisites
- **Node.js (lts)**: You can download it from the [official website](https://nodejs.org/).
- **pnpm (latest)**: You can install it by running `npm install -g pnpm`.
- **Git**: You can download it from the [official website](https://git-scm.com/).
- **Docker or Docker Desktop**: You can download it from the [official website](https://www.docker.com/).
- **A GitHub account**: You can create one on the [official website](https://github.com/).
### Setting up the project
1. Fork the repository by clicking on the "Fork" button on the top right corner of the repository page.
![Fork button](./img/fork.png)
2. Clone the repository to your local machine with `git clone`. You can find the url to use by clicking on the "Code" button on the top right corner of your forks repository page.
![Clone button](./img/clone.png)
3. Change directory to the project folder with `cd homarr`.
4. Install the dependencies with `pnpm install`.
5. Start redis by running `pnpm run docker:dev`. This will run a docker-compose file with a redis service.
6. Copy the `.env.example` file to `.env` and replace `DB_URL` with the full path you want to use for the sqlite database file. For example `DB_URL='C:\\Dev\\homarr\\packages\\db\\db.sqlite'`
7. Run the migrations to create the sqlite db file with `pnpm run db:migration:sqlite:run`.
8. Start the development server with `pnpm dev` and wait for a message that says `✓ Ready in 10.7s`
9. Open your browser and navigate to [http://localhost:3000](http://localhost:3000). (Loading the page might take up to 2 minutes the first time)
### Useful npm scripts
#### During development
- `pnpm dev`: Start the development server.
- `pnpm cli`: Run cli commands.
- `pnpm db:migration:sqlite:run`: Run the migrations to create or update the sqlite db file.
- `pnpm db:migration:sqlite:generate`: Generate a new migration file for the sqlite db. Also works with `mysql`.
- `pnpm db:studio`: Open a visual studio for the database.
- `pnpm package:new`: Create a new package in the monorepo.
#### Checking code quality
- `pnpm lint`: Run the linter to check for code quality issues.
- `pnpm format:fix`: Run the formatter to fix code style issues.
- `pnpm test`: Run the tests. You can also use `pnpm test:ui` to get a UI for the tests.
- `pnpm typecheck`: Run the typescript type checker.
#### Building the project
- `pnpm build`: Build the project for production.
- `docker build -t homarr .`: Build a docker image for the project.
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:latest`: Run the created docker image.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

@@ -1,135 +0,0 @@
---
title: Kubernetes
tags:
- Developer
- Technical documentation
- Code
- Programming
sidebar_position: 1
---
This guide provides step-by-step instructions for setting up a Kubernetes cluster using kind, configuring multiple nodes, and installing the Metrics Server.
## Prerequisites
Ensure you have the following installed:
- [Docker](https://docs.docker.com/get-started/get-docker/) (required for running `kind` clusters).
- [Kind](https://kind.sigs.k8s.io/docs/user/quick-start/) (Kubernetes in Docker).
- [Kubectl](https://kubernetes.io/docs/tasks/tools/) (Kubernetes command-line tool).
Additionally, ensure that Kubernetes tools are enabled in your environment by setting the following variable in your `.env` file:
```bash
# Enable Kubernetes tool
ENABLE_KUBERNETES=true
```
### 1. Creating a Kubernetes Cluster with Multiple Nodes
We will create a Kubernetes cluster using `kind` with one control plane node and two worker nodes.
#### Define the Cluster Configuration
Create a configuration file named `kind-config.yaml` with the following content:
```bash
cat > kind-config.yaml <<EOF
# three node (two workers) cluster config
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
kubeadmConfigPatches:
- |
kind: KubeletConfiguration
apiVersion: kubelet.config.k8s.io/v1beta1
kubeReserved:
cpu: "250m"
memory: "256Mi"
systemReserved:
cpu: "500m"
memory: "512Mi"
evictionHard:
memory.available: "200Mi"
- role: worker
- role: worker
EOF
```
#### Create the Cluster
Run the following command to create the Kubernetes cluster:
```bash
kind create cluster --name k8s-playground --config kind-config.yaml
```
This will provision a cluster named `k8s-playground` with the specified node configuration.
### 2. Installing the Metrics Server
The Metrics Server is required for gathering resource utilization metrics like CPU and memory usage. It is essential for features such as Horizontal Pod Autoscaling.
#### Deploy the Metrics Server
Run the following command to install the Metrics Server:
```bash
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/download/v0.7.2/components.yaml
```
#### Disable TLS Verification (For Local Development)
In local environments, Kubernetes nodes might not have valid certificates. To disable TLS verification, patch the deployment:
```bash
kubectl patch -n kube-system deployment metrics-server --type=json \
-p '[{"op":"add","path":"/spec/template/spec/containers/0/args/-","value":"--kubelet-insecure-tls"}]'
```
This allows the Metrics Server to communicate with kubelets that use self-signed certificates.
### 3. Verifying the Setup
After completing the setup, verify that the cluster is running correctly:
#### Check the Cluster Nodes
```bash
kubectl get nodes
```
Expected output:
```bash
NAME STATUS ROLES AGE VERSION
k8s-playground-control-plane Ready control-plane Xs vX.Y.Z
k8s-playground-worker Ready worker Xs vX.Y.Z
k8s-playground-worker2 Ready worker Xs vX.Y.Z
```
#### Check Metrics Server Status
```bash
kubectl get deployment -n kube-system metrics-server
```
Expected output:
```bash
NAME READY UP-TO-DATE AVAILABLE AGE
metrics-server 1/1 1 1 Xs
```
#### Get Node Resource Metrics
```bash
kubectl top nodes
```
This command should return CPU and memory usage statistics for each node.
## Conclusion
You have successfully set up a multi-node Kubernetes cluster using kind and installed the Metrics Server for monitoring resource usage. This setup is useful for local development and testing Kubernetes workloads before deploying them to a production environment.
@@ -1,114 +0,0 @@
---
title: Environment variables
tags:
- Configuration
- Docker
- Advanced
- Env
- Environment variables
- Variables
- Database
- Redis
- Secrets
---
Homarr offers a few environment variables, which can be used to configure the container.
:::info
With docker you can add the `_FILE` suffix to any environment variable, which will read the value from a file.
This is especially useful for [docker secrets](https://docs.docker.com/engine/swarm/secrets/#use-secrets-in-compose).
:::
## General
:::warning
Using the `PUID` and `PGID` will require you to set the correct permissions on the mounted volumes and if used the docker socket. See more in the [Running as a different user](/docs/advanced/running-as-different-user) documentation.
:::
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| ``PUID`` | User ID to run the container as | Any valid user ID | ``0`` |
| ``PGID`` | Group ID to run the container as | Any valid group ID | ``0`` |
| ``LOG_LEVEL`` | Log level to use | ``debug`` / ``info`` / ``warn`` / ``error`` | ``info`` |
| ``NO_EXTERNAL_CONNECTION`` | Disables some requests that need internet connection | `true` or `false` | `false` |
| ``ENABLE_DNS_CACHING`` | Enables dns caching. Enabled by default, but if you experience issues with IPv6 or static IPs, see [#4006](https://github.com/homarr-labs/homarr/issues/4006) or disable this flag | `true` or `false` | `true` |
## Authentication
See [Single Sign-On](/docs/advanced/single-sign-on) for more informations.
## Security
The `SECRET_ENCRYPTION_KEY` is required. If none is specified before starting the container, a random key will be shown in the error message and the container will exit.
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| ``SECRET_ENCRYPTION_KEY`` | Secret used to encrypt secrets in database. | 64 character hex string | - |
:::info
A random secret can be generated by using the following command: `openssl rand -hex 32`
:::
## Docker
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| ``DOCKER_HOSTNAMES`` | Comma seperated list of hostnames to connect to | For example `localhost,docker.example.com` | - |
| ``DOCKER_PORTS`` | Comma seperated list of ports to connect to | For example `2375,2376` | - |
| ``DOCKER_SOCKET_PATHS`` | Comma seperated list of paths to sockets | For example `/var/run/docker.sock,/run/user/1000/podman/podman.sock` | - |
## Database
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| ``DB_DRIVER`` | Database driver to use. Currently `better-sqlite3` is used for sqlite, `mysql2` for mysql and `node-postgres` for postgresql | ``better-sqlite3`` / ``mysql2`` / ``node-postgres`` | ``better-sqlite3`` |
| ``DB_DIALECT`` | Database dialect to use. | ``sqlite`` / ``mysql`` / ``postgresql`` | ``sqlite`` |
| ``DB_URL`` | Database URL to connect to. | Any valid database URL | ``/appdata/db/db.sqlite`` |
| ``DB_HOST`` | Database host to connect to. | Any valid database host | - |
| ``DB_PORT`` | Database port to connect to. | Any valid database port | - |
| ``DB_NAME`` | Database name to connect to. | Any valid database name | - |
| ``DB_USER`` | Database user to connect with. | Any valid database user | - |
| ``DB_PASSWORD`` | Database password to connect with. | Any valid database password | - |
You can either use the url or host, port, name and credentials combined. The URL will be prioritized over the other values.
## Redis
By default Redis is running within the installation. (for example in Docker).
However for example for K8s it can be useful to use an external Redis instance.
:::note
External redis is currently not supported with Proxmox Community Scripts
:::
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| `REDIS_IS_EXTERNAL` | Whether Redis is running externally. | `true` / `false` | `false` |
| `REDIS_HOST` | Hostname of the Redis instance. | Any valid hostname | - |
| `REDIS_PORT` | Port of the Redis instance. | Any valid port | `6379` |
| `REDIS_USERNAME` | Username to connect to the Redis instance. | Any valid username | - |
| `REDIS_PASSWORD` | Password to connect to the Redis instance. | Any valid password | - |
| `REDIS_DATABASE_INDEX` | Select which database of your redis instance should be used. | Any numeric index | - |
| `REDIS_TLS_CA` | CA certificate for Redis TLS connections. If a certificate is specified the connection will use TLS. | Any valid CA certificate | - |
## Proxy
| Environment Variable | Description | Possible values | Default |
| ------------------------ | ----------- | --------------- | ------- |
| ``HTTP_PROXY`` | HTTP proxy to use | Any valid HTTP proxy URL | - |
| ``HTTPS_PROXY`` | HTTPS proxy to use | Any valid HTTPS proxy URL | - |
| ``NO_PROXY`` | Comma separated list of hosts that should be excluded from proxying | Any valid hostnames | - |
## Advanced deployments
:::warning
The advanced deployments environment variables should only be used if you know what you are doing.
:::
| Environment Variable | Description |
| ------------------------ | ----------- |
| ``DB_MIGRATIONS_DISABLED`` | Disable db migrations. For example for helm charts |
Binary file not shown.

Before

Width:  |  Height:  |  Size: 289 KiB

-34
View File
@@ -1,34 +0,0 @@
---
title: Icons
tags:
- Configuration
- Customization
- Icons
- Icon picker
- Icon repositories
---
## Icon picker
Icons in Homarr are automatically requested from multiple sources:
- [Dashboard Icons](https://dashboardicons.com/) - Our recommended source with over 1888+ curated, high-quality icons
- [selfh.st icons](https://github.com/selfhst/icons)
- [Simple icons](https://github.com/simple-icons/simple-icons)
- [Tabler icons](https://tabler-icons.io/)
- [Papirus icons](https://github.com/PapirusDevelopmentTeam/papirus-icon-theme)
- [Homelab Svg assets](https://github.com/loganmarchione/homelab-svg-assets)
- **Local icons**: automatically fetched from the [medias feature](/docs/management/media/)
Using these icon sources, Homarr provides a total collection of over 11,000 icons at your fingertips.
The icon picker is a fast searcher that helps you to find your desired icon simply by entering a search term.
### Finding Missing Icons
If you can't find the icon you're looking for in Homarr's built-in picker, we strongly recommend checking [Dashboard Icons](https://dashboardicons.com/). It offers a modern, user-friendly interface and a curated collection of high-quality icons specifically designed for dashboards and app directories.
![Icon picker](./img/icon-picker.gif)
Icons that are high quality and printable ([SVG](https://wikipedia.org/wiki/Scalable_Vector_Graphics)) are marked with a red badge "SVG" at the top right.
### Using external icons
If you don't find the icon you're looking for on Dashboard Icons or wish to use a different source, you can simply enter a URL that points to an icon.
It is important that the URL directly points to the file without any advertisements or elements around it.
@@ -1,27 +0,0 @@
---
title: Keyboard Shortcuts
tags:
- Advanced
---
Homarr has the following keyboard shortcuts:
| Shortcut | Description |
| -------- | ----------- |
| `MOD` + `K` | Opens the search bar |
| `MOD` + `J` | Toggles Dark Mode |
| `MOD` + `E` | Toggles Edit Mode |
:::tip
Here `MOD` refers to the modifier key, which is `Ctrl` on Windows and `Cmd` on macOS.
:::
:::note
The focus of your browser must be set on Homarr. If you click outside of Homarr, you might need to click once somewhere in Homarr to send all keystrokes again to Homarr.
If the shortcuts are not working, ensure that you have selected the correct keyboard layout.
:::
-163
View File
@@ -1,163 +0,0 @@
---
title: Proxies and Certificates
tags:
- Configuration
- Proxy
- Advanced
- Traefik
- Caddy
- Security
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
## Allowing self-signed certificates
Some users may come across a barrier, where they're unable to receive a 200 response from the Ping widget for some apps, while using self-signed certificates or a local certificate authory.
:::note What's going on?
Homarr is trying to communicate to your apps via the integrations.
It usually doesn't matter if Homarr is running on ``http`` or ``https``.
Your apps have a self-signed certificate - Homarr will recognize that the certificate was signed by an unknown authority and requests will be blocked.
:::
To allow self-signed certificates, you can configure them on the certificates management page. You can find more informations on the dedicated page: [Certificates](/docs/management/certificates/)
## Securing Homarr with Traefik
Copying the configuration straight from the docker-compose file won't work if you are running Homarr behind Traefik, such as a Portainer setup, or docker-swarm. In that case, you should use the following slightly modified configuration:
```yaml
version: '3'
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:latest
restart: unless-stopped
volumes:
- ./homarr/appdata:/appdata
environment:
- BASE_URL=your.internal.dns.address.here.com
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
networks:
- proxy
labels:
traefik.enable: true
traefik.http.routers.homarr.rule: Host(`your.internal.dns.address.here.com`)
traefik.http.routers.homarr.entrypoints: websecure
traefik.http.routers.homarr-secure.app: homarr
traefik.http.apps.homarr.loadbalancer.server.port: 7575
networks:
proxy:
external: true
```
<br/>
A sample Traefik docker-compose.yml using Cloudflare for certificate generation that works with the configuration above would be:
```yaml
version: '3'
apps:
traefik:
image: traefik:latest
container_name: traefik
restart: unless-stopped
security_opt:
- no-new-privileges:true
networks:
- proxy
ports:
- 80:80
- 443:443
environment:
- CF_API_EMAIL=yourcfemail@here.com
- CF_DNS_API_TOKEN=long-token-from-cf
command:
- "--log.level=DEBUG"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--providers.docker.endpoint=unix:///var/run/docker.sock"
- "--entrypoints.web.address=:80"
- "--entrypoints.web.http.redirections.entryPoint.to=websecure"
- "--entrypoints.web.http.redirections.entryPoint.scheme=https"
- "--entrypoints.web.http.redirections.entrypoint.permanent=true"
- "--entrypoints.websecure.address=:443"
- "--entrypoints.websecure.http.tls.certResolver=cloudflare"
- "--certificatesresolvers.cloudflare.acme.storage=acme.json"
- "--certificatesResolvers.cloudflare.acme.email=yourcfemail@here.com"
- "--certificatesResolvers.cloudflare.acme.dnsChallenge=true"
- "--certificatesResolvers.cloudflare.acme.dnschallenge.provider=cloudflare"
- "--certificatesResolvers.cloudflare.acme.dnschallenge.resolvers=1.1.1.1:53,1.0.0.1:53"
- "--serversTransport.insecureSkipVerify=true" # Or proxmox gives an error 500 due to its own self-signed cert
volumes:
- /etc/localtime:/etc/localtime:ro
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./data/acme.json:/acme.json
networks:
proxy:
external: true
```
:::tip
Of particular note here is that both configurations explicitly define which network they are using, in this case "proxy", but it can be named anything. It just has to be the same across all apps for which Traefik is serving as a proxy. These are marked as external because the proxy network was manually created by running: `docker network create proxy` but this might be unnecessary depending on HOW exactly you are running Traefik. For example, if running [Traefik with Portainer](https://docs.portainer.io/advanced/reverse-proxy/traefik#deploying-in-a-docker-standalone-scenario), you can follow their official docs on how to set up Traefik and Portainer together, and you can just focus on the Homarr docker labels instead.
:::
## Securing Homarr with Caddy
If you are using Caddy as the reverse proxy for your setup, your `docker-compose.yml` should look something like this:
```yaml
services:
# <-- [Homarr installation]
caddy:
container_name: caddy
image: caddy:2
restart: unless-stopped
ports:
- 80:80
- 443:443
- 443:443/udp
volumes:
- ./Caddyfile:/etc/caddy/Caddyfile
- caddy_data:/data
- caddy_config:/config
networks:
- proxy
volumes:
caddy_data:
caddy_config:
networks:
proxy:
external: true
```
:::important
Homarr needs to be on the same network so you will need to add the following property to your homarr install:
```yaml
homarr:
...
networks:
- proxy
```
:::
Next, create a file named `Caddyfile` at the same level as your `docker-compose.yml` file with the following content:
```
homarr.mydomain.com {
reverse_proxy homarr:7575
}
```
If you want more information about working with Caddy and Docker Compose, refer to the official documentation:
https://caddyserver.com/docs/running#docker-compose
@@ -1,93 +0,0 @@
---
title: Running as a different user
tags:
- Configuration
- Docker
- Advanced
- PGID
- PUID
---
By default the container is running with user `root` and group `root`.
You can change the user and group by using the `PUID` and `PGID` environment variables.
Important to note is, that you'll also need to change the permissions for the mounted directories accordingly.
:::info
When starting up an updated version of the container it will have about **10 seconds longer to start** as it has to change the permissions of the app directories
:::
## Without mounted Docker socket
To run your container as a different user, you can use the `PUID` and `PGID` environment variables:
```yml title="docker-compose.yml"
#---------------------------------------------------------------------#
# Homarr - A simple, yet powerful dashboard for your server. #
#---------------------------------------------------------------------#
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:latest
restart: unless-stopped
volumes:
- ./homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=1000
ports:
- '7575:7575'
```
After that you'll need to create the appdata directory and set the correct permissions:
```bash title="On host"
mkdir -p ./homarr/appdata
chown -R 1000:1000 ./homarr/appdata
```
## With mounted Docker socket
If you want to use the Docker integration, you'll need to set the correct permissions for the Docker socket as well, most of the times it will have the owner group set to docker group.
In any way, it is recommended to create this group and set it's permissions to it, if it doesn't exist yet:
```bash title="On host"
groupadd -g 999 docker
```
Then you can set the permissions for the Docker socket:
```bash title="On host"
chown root:docker /var/run/docker.sock
```
After that you can set the `PUID` and `PGID` environment variables in your `docker-compose.yml` file:
```yml title="docker-compose.yml"
#---------------------------------------------------------------------#
# Homarr - A simple, yet powerful dashboard for your server. #
#---------------------------------------------------------------------#
services:
homarr:
container_name: homarr
image: ghcr.io/homarr-labs/homarr:latest
restart: unless-stopped
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ./homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=999
ports:
- '7575:7575'
```
And set the permissions for the mounted directories:
```bash title="On host"
mkdir -p ./homarr/appdata
chown -R 1000:999 ./homarr/appdata
```
Important here is that the group ID is set to `999` as we created the `docker` group with this ID.
@@ -1,364 +0,0 @@
---
title: Single Sign On
tags:
- Management
- Users
- Docker
- SSO
- LDAP
- OIDC
- Active Directory
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
# Single Sign On
Homarr supports multiple authentication options, from internal userbase (credentials), to LDAP (with Active directory support), and OIDC.
### Auth configuration common variables
| Environment Variable | Description | Default Value |
|---------------------------|-------------|---------------|
| AUTH_PROVIDERS | Select Which provider to use between *credentials*, *ldap* and *oidc*. <br /> Multiple providers can be enabled with by separating them with `,`, (ex. `AUTH_PROVIDERS=credentials,oidc`, it is highly recommended to just enable one provider). | credentials |
| AUTH_LOGOUT_REDIRECT_URL | URL to redirect to after clicking logging out. | --- |
| AUTH_SESSION_EXPIRY_TIME | Time for the session to time out. Can be set as pure number, which will automatically be used in seconds, or followed by s, m, h or d for seconds, minutes, hours or days. (ex: "30m") | "30d" |
| AUTH_COOKIE_PREFIX | Prefix used for all authentication cookies (session, csrf, callback, pkce, state, nonce). Change this if you run another Auth.js/NextAuth app on the same hostname as Homarr (browsers scope cookies by host, not by port) to avoid cookie name collisions. Only letters, numbers, hyphens and underscores are allowed. | `homarr` |
<Tabs>
<TabItem value="credentials" label="Credentials Provider" default>
This is the default provider.
First user is created using the onboarding process and the rest can be created by this user (see [user management](/docs/management/users))
</TabItem>
<TabItem value="ldap" label="LDAP provider">
This provider authenticates against an LDAP server.
Any user in LDAP server that signs in gets created in Homarr database.
Roles are fetched from LDAP groups. Groups with the same name of Homarr will be used to synchronize them.
<details>
<summary>
Example Setup
</summary>
<div>
In this setup we are using [lldap](https://github.com/lldap/lldap). Install your server using docker or [as a service](https://github.com/lldap/lldap/blob/main/example_configs/lldap.service).
Minimal configuration requires 4 env variables, LDAP URI, base, user and password for querying data.
There's more variables, but all have defaults corresponding to lldap defaults. These might need to be changed if you have different LDAP provider.
```
docker run ...
AUTH_PROVIDERS="ldap"
AUTH_LDAP_URI="ldap://example.com:3890"
AUTH_LDAP_BASE="dc=example,dc=com" // Same as LLDAP_LDAP_BASE_DN
AUTH_LDAP_BIND_DN="uid=admin,ou=People,dc=example,dc=com"
AUTH_LDAP_BIND_PASSWORD="adminpass" // Same as LLDAP_LDAP_USER_PASS
```
```
#Docker compose
version: x
services:
homarr:
environment:
AUTH_PROVIDERS: ldap
AUTH_LDAP_URI: ldap://example.com:3890
AUTH_LDAP_BASE: dc=example,dc=com #Same as LLDAP_LDAP_BASE_DN
AUTH_LDAP_BIND_DN: uid=admin,ou=People,dc=example,dc=com
AUTH_LDAP_BIND_PASSWORD: adminpass #Same as LLDAP_LDAP_USER_PASS
```
In lldap, create a user and admin group, assign this user to the external admin group configured during onboarding. You can log in using this user and he will be in the group.
Here is another example for Active Directory:
```
AUTH_LDAP_URI="ldap://ldap.abc.xyz:389
AUTH_LDAP_BASE="DC=abc,DC=xyz"
AUTH_LDAP_BIND_DN="CN=Administrator,CN=Users,DC=abc,DC=xyz"
AUTH_LDAP_BIND_PASSWORD="YourAdministratorPassword"
AUTH_LDAP_USERNAME_ATTRIBUTE="sAMAccountName"
AUTH_LDAP_USER_MAIL_ATTRIBUTE="userPrincipalName"
AUTH_LDAP_GROUP_CLASS="group"
AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE="member"
AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE="dn"
AUTH_LDAP_SEARCH_SCOPE="sub"
AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG="(sAMAccountType=805306368)"
```
User mail attribute is set to userPrincipalName as it follows the right schema, but it is recommended to use real emails and the default 'mail' value.
</div>
</details>
### Configuration
| Environment Variable | Description | Default value |
|-------------------------------------------|-----------------------------------------------------------|---------------------|
| ``AUTH_LDAP_URI`` | URI of your LDAP server | --- |
| ``AUTH_LDAP_BASE`` | Base dn of your LDAP server | --- |
| ``AUTH_LDAP_BIND_DN`` | User used for finding users and groups | --- |
| ``AUTH_LDAP_BIND_PASSWORD`` | Password for bind user | --- |
| ``AUTH_LDAP_USERNAME_ATTRIBUTE`` | Attribute used for username | uid |
| ``AUTH_LDAP_USER_MAIL_ATTRIBUTE`` | Attribute used for mail field | mail |
| ``AUTH_LDAP_GROUP_CLASS`` | Class used for querying groups | groupOfUniqueNames |
| ``AUTH_LDAP_GROUP_MEMBER_ATTRIBUTE`` | Attribute used for querying group member | member |
| ``AUTH_LDAP_GROUP_MEMBER_USER_ATTRIBUTE`` | User attribute used for comparing with group member | dn |
| ``AUTH_LDAP_SEARCH_SCOPE`` | Serach scopes between base, one and sub | base |
| ``AUTH_LDAP_USERNAME_FILTER_EXTRA_ARG`` | Extra arguments for user search filter (& based) | --- |
| ``AUTH_LDAP_GROUP_FILTER_EXTRA_ARG`` | Extra arguments for user's groups search filter (& based) | --- |
</TabItem>
<TabItem value="oidc" label="OIDC provider">
This provider authenticates using OIDC protocol.
Users signed in using OIDC are created in Homarr.
Roles are fetched from group claims. This can also be changed to roles for example added to a azure app registration by using the `AUTH_OIDC_GROUPS_ATTRIBUTE`.
If you'd rather manage group memberships for OIDC users locally (instead of via the IdP), set `AUTH_OIDC_GROUPS_LOCAL_MANAGEMENT=true`. While enabled, Homarr stops syncing OIDC users' group memberships from the groups claim, and admins can add/remove OIDC users on a group's members page. If you turn this back to `false`, the next login of each user resumes the regular sync and reconciles their groups with the IdP's claim again, which may remove memberships that were added manually while local management was enabled.
<details>
<summary>
Example Setup
</summary>
<div>
In this example we will be using [Authelia](https://github.com/authelia/authelia).
You can use any setup, but the simplest is [local](https://github.com/authelia/authelia/blob/master/examples/compose/local/authelia/configuration.yml).
You also have to [enable OIDC in Authelia](https://www.authelia.com/configuration/identity-providers/open-id-connect/).
Create a client for homarr. To generate client secret you can [use authelia](https://www.authelia.com/integration/openid-connect/frequently-asked-questions/#how-do-i-generate-client-secrets). This is an example config:
```yaml
identity_providers:
oidc:
...
clients:
- id: homarr
secret: <secret_hash>
public: false
authorization_policy: one_factor
redirect_uris:
- https://example.com/api/auth/callback/oidc
- http://localhost:3000/api/auth/callback/oidc
scopes:
- openid
- groups
- profile
- email
userinfo_signing_algorithm: none
consent_mode: implicit # self hosted
```
In Homarr use following env variables.
```
AUTH_PROVIDERS="oidc"
AUTH_OIDC_ISSUER="https://auth.example.com"
AUTH_OIDC_CLIENT_SECRET="client_secret"
AUTH_OIDC_CLIENT_ID="homarr"
AUTH_OIDC_CLIENT_NAME="Authelia"
AUTH_OIDC_FORCE_USERINFO="true" --> from v4.39 of authelia and above this is required
```
For an azure app registration the setup could look like this:
```
AUTH_PROVIDERS="oidc"
AUTH_OIDC_ISSUER="https://login.microsoftonline.com/<teanant-id>/v2.0"
AUTH_OIDC_CLIENT_SECRET="<client-secret>"
AUTH_OIDC_CLIENT_ID="<client-id>"
AUTH_OIDC_CLIENT_NAME="Azure"
AUTH_OIDC_SCOPE_OVERWRITE="openid email profile" # Groups scope does not exist in azure
AUTH_OIDC_GROUPS_ATTRIBUTE="roles" # We use the roles of the app registration so that we don't need to use uuids as our groups
```
</div>
</details>
### Configuration
| Environment Variable | Description | Default value |
|-----------------------------|------------------------------------------------------------|---------------|
| ``AUTH_OIDC_ISSUER`` | Issuer URI of OIDC provider. This has generally to be **without trailing slash** except for **Authentik** | --- |
| ``AUTH_OIDC_CLIENT_ID`` | ID of OIDC client (application) | --- |
| ``AUTH_OIDC_CLIENT_SECRET`` | Secret of OIDC client (application) | --- |
| ``AUTH_OIDC_CLIENT_NAME`` | Display name of provider (in login screen) | OIDC |
| ``AUTH_OIDC_AUTO_LOGIN`` | Automatically redirect to OIDC login | false |
| ``AUTH_OIDC_SCOPE_OVERWRITE`` | Overwrite default scopes (openid, profile, email) | openid email profile groups |
| ``AUTH_OIDC_GROUPS_ATTRIBUTE`` | Attribute used for groups (roles) claim | groups |
| ``AUTH_OIDC_GROUPS_LOCAL_MANAGEMENT`` | Stop syncing group memberships of OIDC users from the groups claim and manage them locally via the group members page instead | false |
| ``AUTH_OIDC_NAME_ATTRIBUTE_OVERWRITE`` | Overwrite name attribute. By default it will use preferred_username if it does not contain a `@` and otherwise name. | --- |
| ``AUTH_OIDC_FORCE_USERINFO`` | Force userinfo endpoint to be used for user information. | false |
| ``AUTH_OIDC_ENABLE_DANGEROUS_ACCOUNT_LINKING`` | Enable account linking for OIDC provider. This will link the OIDC accounts by email. Be sure that you have verified emails to prevent stealing accounts. | false |
| ``AUTH_OIDC_TOKEN_ENDPOINT_AUTH_METHOD`` | Override method for the token endpoint authentication. Supported values are `client_secret_basic`, `client_secret_post`, `client_secret_jwt` and `none`. | client_secret_basic |
### Permission System
To give a user special permissions, first create a new group in homarr and assign the permission desired.
For example if the group on homarr is called `homarr-admins` a new group on the oidc provider, for example authentik needs to be created with the same name, that would be `homarr-admins`.
After assigning the group on the oidc provider to the user, and logging again into homarr, the user should automatically get placed in that group and inherit the permissions defined.
</TabItem>
</Tabs>
## Example setups
<Tabs>
<TabItem value="authentik" label="Authentik (OIDC) Example" default>
This example demonstrates how to use [Authentik](https://goauthentik.io/) as an OIDC provider for Homarr.
User and group management is handled within Authentik. Homarr synchronizes group memberships based on OIDC claims provided by Authentik. To grant administrative privileges, create a group in Authentik (e.g., `homarr-admins`) and add the relevant users. Then add the group with the same name in Homarr and assign the desired permissions to it.
<details>
<summary>
Example Setup
</summary>
<div>
**1. Configure Authentik:**
- Create an OIDC application in Authentik for Homarr.
- Set the redirect URIs to:
- `https://<your-homarr-domain>/api/auth/callback/oidc`
- `http://localhost:3000/api/auth/callback/oidc` (for local development)
- Record the client ID, client secret, and application slug.
- Create a group (e.g., `homarr-admins`) and assign users who require admin access.
**2. Example .env file:**
```env
OIDC_CLIENT_ID=identificationid #OIDC client ID
OIDC_CLIENT_SECRET=secretsecretsecret #OIDC client secret
OIDC_SLUG=homarr #Application slug in Authentik
AUTH_DOMAIN=auth.example.com #Authentik FQDN
ADMIN_GROUP=homarr-admins #Authentik group for Homarr admins
HOMARR_FQDN=homarr.example.com #Homarr FQDN
SECRET_ENCRYPTION_KEY=encryptencryptencrypt #Homarr encryption key
```
**3. Example Docker Compose configuration:**
```yaml {14-26}
services:
homarr:
image: ghcr.io/homarr-labs/homarr:latest
container_name: homarr
restart: unless-stopped
ports:
- '7575:7575'
volumes:
- ./homarr:/appdata
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- TZ=America/Los_Angeles
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- BASE_URL=https://${HOMARR_FQDN}
- NEXTAUTH_URL=https://${HOMARR_FQDN}
- AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback)
- AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
- AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
- AUTH_OIDC_ISSUER=https://${AUTH_DOMAIN}/application/o/${OIDC_SLUG}/
- AUTH_OIDC_URI=https://${AUTH_DOMAIN}/application/o/authorize
- AUTH_OIDC_CLIENT_NAME=authentik
- AUTH_OIDC_SCOPE_OVERWRITE=openid email profile groups
- AUTH_OIDC_GROUPS_ATTRIBUTE=groups
- AUTH_LOGOUT_REDIRECT_URL=https://${AUTH_DOMAIN}/application/o/${OIDC_SLUG}/end-session/
- AUTH_OIDC_AUTO_LOGIN=true #To sign in with Authentik automatically
networks:
- my-network
networks:
my-network:
external: true
```
**4. Additional Notes:**
- Ensure both Authentik and Homarr are accessible via the specified FQDNs.
- The `AUTH_OIDC_GROUPS_ATTRIBUTE` should correspond to the claim in Authentik that contains group names (typically `groups`).
- Your user will automatically be placed in groups that have the same name as those of authentik. So simply create them in Homarr and give them the permissions you want.
- For further information, refer to the [Authentik OIDC documentation](https://goauthentik.io/docs/providers/oauth2/).
</div>
</details>
Additional OIDC configuration options are described in the OIDC tab above.
</TabItem>
<TabItem value="google" label="Google (OIDC) Example" default>
This example demonstrates how to use [Google Auth Platform](https://console.cloud.google.com/auth/overview) as an OIDC provider for Homarr.
Unfortunately Google does not support synchronization of group membership. See https://issuetracker.google.com/issues/133774835?pli=1.
<details>
<summary>
Example Setup
</summary>
<div>
**1. Setup (Google):**
- Create a Project in [Google Cloud Console](https://console.cloud.google.com/) for Homarr and switch to that Project.
- Configure [Authorized Domains](https://console.cloud.google.com/auth/branding) and set it to `<your-homarr-domain>`.
- Create a new [OAuth Client](https://console.cloud.google.com/auth/clients):
- Select Application Type `Web`
- Set the redirect URI to `https://<your-homarr-domain>/api/auth/callback/oidc`
- Record the `Client-ID` and `Client Key` (secret).
**2. Example .env file (Homarr):**
```env
OIDC_CLIENT_ID=identificationid #Google Client-ID
OIDC_CLIENT_SECRET=secretsecretsecret #Google Client Key (secret)
HOMARR_FQDN=homarr.example.com #Homarr FQDN
SECRET_ENCRYPTION_KEY=encryptencryptencrypt #Homarr encryption key
```
**3. Example Docker Compose configuration (Homarr):**
```yaml {16-22}
services:
homarr:
image: ghcr.io/homarr-labs/homarr:latest
container_name: homarr
restart: unless-stopped
ports:
- '7575:7575'
volumes:
- ./homarr:/appdata
- /var/run/docker.sock:/var/run/docker.sock:ro
environment:
- TZ=Europe/Berlin
- SECRET_ENCRYPTION_KEY=${SECRET_ENCRYPTION_KEY}
- BASE_URL=https://${HOMARR_FQDN}
- NEXTAUTH_URL=https://${HOMARR_FQDN}
- AUTH_PROVIDERS=oidc #(optional: include ',credentials' to keep local accounts as fallback)
- AUTH_OIDC_CLIENT_ID=${OIDC_CLIENT_ID}
- AUTH_OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
- AUTH_OIDC_ISSUER=https://accounts.google.com
- AUTH_OIDC_CLIENT_NAME=Google
- AUTH_OIDC_SCOPE_OVERWRITE=openid email profile
- AUTH_OIDC_NAME_ATTRIBUTE_OVERWRITE=name
networks:
- my-network
networks:
my-network:
external: true
```
</div>
</details>
Additional OIDC configuration options are described in the OIDC tab above.
</TabItem>
</Tabs>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

-94
View File
@@ -1,94 +0,0 @@
# Styling
:::tip
This page is directed at more experienced users with knowledge about CSS and browsers.
We recommend you to [look into the board customizations instead](/docs/management/boards#appearance),
if you do not have experience with writing custom styles or CSS.
:::
:::warning
Our support specifically excludes custom CSS, and we will not help you to write CSS.
However, we may help you by adding new CSS classes if required.
:::
Homarr uses https://mantine.dev/ under the hood. You can change the look & feel of Homarr
using custom CSS, that extends or overwrites the styles from Mantine.
## Getting into CSS
If you don't have any experience with CSS,
we strongly recommend you to go through the courses here: https://www.w3schools.com/css/.
Due to the infinite scenarios and setups possible with custom CSS,
our support team will not provide any support with your own written CSS.
## Limitations and dangers
When using custom CSS, you can break the page or certain functionalities.
Although CSS can improve the design & feel of the page, it **<ins>cannot do any of the following</ins>**:
- Implement new features, widgets or integrations
- Securely hide elements you don't want users to interact / have permission to
- Completely revamp the design of the page, only smaller changes are possible
Here are some dangers of using custom CSS:
- Updates may contain breaking changes in the structure, built-in styling or how styling is processed. Therefore,
custom CSS may break unexpectedly without any warning
- Custom CSS may make certain elements invisible or not possible to click / interact with
- Custom CSS could make readability and accessibility worse for impaired people
## How to inspect the page
When styling the page, you can use the ``Inspector`` to inspect elements on the page and try out styles.
This may vary depending on your browser and operating system, but the workflow usually goes like this:
- Open the Homarr page
- Press ``Ctrl`` + ``Shift`` + ``I`` at the same time.
Alternatively, right-click on the page and choose ``Inspect`` or ``Inspect element``.
- Open the tab ``Elements`` if it isn't open yet.
- Search the element you want to change in the DOM tree or use the element picker (usually at the top left)
to select it by clicking on the page.
- Experiment by changing the CSS code on the right side
When writing custom CSS, it is important to also remember or create a selector, which tells the browser
which element to apply the styles to. If you accidentally broke something or want to revert your changes in the inspector,
simply reload the page.
## Using Homarr's classes
Homarr's elements will already have a lot of classes and styles pre-applied.
You can reuse those classes to apply additional styles or overwrite them.
When overwriting, remember to add the ``!important`` flag to your CSS property to tell the browser to use our instruction instead.
Classes with random number suffixes, such as ``mantine-Card-x2fske``, should be avoided, since those are dynamic
CSS classes that will change with every build. This means, every time you update Homarr,
your styles will no longer apply to them
## Defining custom classes for widgets
If you want to apply the styles only for one widget, you can define custom class names only for that widget.
To do that, enter edit mode on your board, click the three dots of your widget, click ``Edit item`` and click ``Advanced options``.
Then, you can enter as many custom classes as you'd like:
![](./img/widget-custom-classes.png)
To save them, click `Save changes` on both modals and exit edit mode.
## Where to enter custom CSS
After you wrote your custom CSS, it is time to permanently save it, so you don't need to use the inspector anymore.
To do this, enter the board settings:
![](./img/enter-board-settings.png)
Scroll down a bit and click on custom CSS.
Here you can enter your CSS code, which will be applied on the respective board page.
![](./img/custom-css-setting.png)
## Using variables
You can also change the values of the theme variables, which are located here: https://mantine.dev/styles/css-variables-list/.
To do this, see the following example CSS:
```css
:root {
--mantine-primary-color-filled: #ffbb00;
}
```
-8
View File
@@ -1,8 +0,0 @@
{
"label": "Community",
"position": 5,
"collapsed": true,
"link": {
"type": "generated-index"
}
}
-25
View File
@@ -1,25 +0,0 @@
---
title: Donate
tags:
- Community
- Donation
- OpenCollective
---
# Donate
## Why to donate
Our team of 4 developers is working on Homarr in their free time.
Homarr has become a big part of our daily things we work on - and therefore we invest a lot of time into maintaining Homarr,
providing support and implementing new features.
We also incur monetary costs while developing Homarr for the tools that we need.
A few examples include:
- Renting for a Cloud VPS for our cloud services (status page, monitoring, email, analytics, [demo instance](https://demo.homarr.dev/), ...)
- Paying for (IDE-) licenses
Using a donation, you help us to cover these expenses and enable the development of Homarr.
Homarr is completely free to use. We'd highly appreciate if you consider donating, especially if you use Homarr in a commercial environment.
## Where to donate
We accept donations on our official [OpenCollective](https://opencollective.com/homarr).
You may also sponsor us directly by providing a useful service / product to us other means.
You can get into contact with us [here](/docs/community/get-in-touch).
-90
View File
@@ -1,90 +0,0 @@
---
title: Frequently Asked Questions
tags:
- Community
- Help
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
### Can I install Homarr on a Raspberry Pi?
Yes, Homarr is compatible with the architecture of the Raspberry Pi. Have a look in our <a href="/docs/category/installation-1">installation guide</a> on how to do so.
### I have a suggestion / idea for improvement or want to report a bug
You can report issues, suggestions, or ideas for improvements <a href="https://github.com/homarr-labs/homarr/issues/new/choose">here</a>.
### Can I use my own custom icons for apps?
Yes, check out our guide on <a href="/docs/advanced/customizations/icons">how to add your custom icons</a>.
### Some of my online icons are not working (anymore)
It seems the `cdn.jsdelivr.net` database of icon sometimes appear in the lists for DNS-Holes (PiHole, AdGuard Home...). <br />
So make sure to manually whitelist this address.
### Can I add my own widgets? Do I need programming skills?
We have decided, not to support custom widgets, until Homarr is in a stable and highly polished state.
Enabling users to write their own widgets is easy at the first glance, but there are some major issues with it:
- There are mainly two options for adding plugins or custom widgets to Homarr. The first option is, to allow and inject custom code in Homarr. Apps like Nextcloud can do this easily, because they use the Runtime to render all components of the application (In reality, the process is still a bit more complicated). In contrast, Homarr is using Next.js - a framework that needs to be compiled in production. That means, that each time you would modify a custom widget or plugin, the app would have to be restarted. There are options to avoid this, but they are quite flakey and bring disadvantages in our experience. The second option is, to write widgets declaratively instead of imperatively. This way, we would be able to render and modify widgets without any restarting at all. However, we'd have to write our own interpreter for said declarative schema. This is totally possible, but requires a lot of planning and architecture design to function properly. The required work to implement either option is therefore quite substantial.
- Custom widgets would need to be able to request data, so they work properly. We use tRPC for this. Many APIs use different formats and we'd have to convert and read those.
- Using custom widgets, one could easily create harmful widgets, leak your personal data (potentially including your tokens) and trick your users. A proper implementation (eg. official plugin store, where we can ban harmful widgets from) would resolve this problem to a certain extent, but again requires additional work and time to be put in.
If you still want to add a widget, please consider to contribute it directly to Homarr. For that, basic programming skills are required. Our [Developer Guides](/docs/advanced/development/getting-started) explain this even more detailed.
### Is it secure to expose Homarr to the web?
Yes, since v0.14.0, we are confident that Homarr is secure enough to be exposed to the web.
Make sure to enable the "allow anonymous access" [option in the settings](/docs/management/boards#access-control), if you want to allow people without an account to be able to see your dashboard (not edit)
### How do I open the console / log?
There are two different sources of information:
- console: This is your client (browser). It can tell us, if there is an issue on the client (crash, bug, ...).
- log: This is your server. It will tell us, if there are issues with connections for the integrations, crashes and errors.
Both variants *can* contain personal data. It's recommended, that you don't post them publicly or remove personal data from it.
<Tabs>
<TabItem value="apple" label="Read console" default>
> Note: This will not work on most mobile browsers.
Open your browser and ensure, that Homarr is your current tab.
Press ``CTRL`` + ``SHIFT`` + ``I`` on your keyboard. If this shortcut doesn't work, please use one of the alternatives: https://developer.chrome.com/docs/devtools/open/.
Click on ``Console`` in the new window, that opened. There, you should see white, orange and sometimes red messages. You can use the Windows Snip & Sketch tool (or your respective tool on Linux / MacOS) to screenshot those messages.
> Please never execute any commands in the console. Scammers are using the console to let you execute harmful commands. If you want to resolve an issue in Homarr, **you'll never have to execute any commands here**
</TabItem>
<TabItem value="orange" label="Read log">
This depends on your installation method. If you use Unraid, you can simply click on the App and on ``Log``. If you have a bare Docker install, use ``docker container logs homarr``. If you used a different name than ``homarr`` for your container, you need to replace said argument. Here is some additional information about the command: https://geekflare.com/check-docker-logs/.
</TabItem>
</Tabs>
### How do I post logs?
Please check [the section above](#how-do-i-open-the-console--log), on how to obtain logs. Logs should always be posted to https://pastebin.com/ or https://rentry.co/.
### Can I use Homarr at my company?
Yes, you can! But please consider a donation, if our work has been useful to you.
### I think I found a bug. What can I do?
If you think, that you found a bug, please create an issue <a href="https://github.com/homarr-labs/homarr/issues/new/choose">here</a>.
### Why can't I use my custom icons?
You need to restart the Homarr Docker container after adding icons.
### Why can't homarr see/ping containers running locally behind GluetunVPN?
This is because GluetunVPN, and many other docker VPN services, secure their VPN connections with strict firewalls. These firewalls often block access to local containers, even on the same docker network. The workaround for <a href="https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/firewall.md">GluetunVPN</a> is to add "- FIREWALL_OUTBOUND_SUBNETS=192.168.1.0/24" into the environmental variables of the docker compose file. If you are using a firewall on your system, you will need to add a rule that allows requests from ip's in the range of 192.168.xxx.xxx . If you are using UFW the command would be "sudo ufw allow from 192.168.0.0/16".
Tip: If you are running your torrent client behind a VPN, and running Sonarr (or something similar) normally, make sure to open your torrent client's port in your firewall. If you don't, Sonarr will not be able to see it. Furthermore, use your machines IP (192.168.x.x) rather then 127.0.0.1 or localhost.
### Can I get in touch with you?
Yes, go <a href="/docs/community/get-in-touch">here</a> to get with us in touch.
<hr/>
:::tip
Haven't found the solution to your problem / question? We are eager to help you on [our Discord](/docs/community/get-in-touch#discord) or in a [GitHub Issue](https://github.com/homarr-labs/homarr/issues/new/choose).
:::
Loaded 100 of 1316 files, more files were not shown because too many files have changed in this diff. Show more