Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9699255180 | ||
|
|
2049c6ade0 | ||
|
|
e21a0bb6da | ||
|
|
61f22c8e64 | ||
|
|
6cca757493 | ||
|
|
1102ad8342 | ||
|
|
7c00c18a42 | ||
|
|
ea3dac752f | ||
|
|
f994d665d2 | ||
|
|
3358b6337f | ||
|
|
61d3fd5f08 | ||
|
|
3aac106156 | ||
|
|
9d857377c1 | ||
|
|
923905c529 | ||
|
|
a4a903d7c3 | ||
|
|
925b0fb801 |
No files matched your search
@@ -37,4 +37,4 @@ Orient from the current checkout before editing. Treat package manifests, export
|
||||
- Cron jobs: `packages/cron-jobs/src/jobs/`
|
||||
- App routes: `apps/nextjs/src/app/[locale]/`
|
||||
|
||||
When a code change affects users, invoke `documentation-sync`. When exposing tRPC through MCP, invoke `mcp-integration`.
|
||||
Invoke `documentation-sync` when hidden capabilities or information not evident to an advanced user change, or existing guidance becomes inaccurate; follow the Documentation Sync criteria in `AGENTS.md`. When exposing tRPC through MCP, invoke `mcp-integration`.
|
||||
@@ -32,24 +32,23 @@ Import only from an exported package entrypoint. Do not deep-import `@homarr/com
|
||||
|
||||
## Root exports
|
||||
|
||||
| Area | Public exports | Purpose |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------- |
|
||||
| Objects | `objectKeys`, `objectEntries`, `hashObjectBase64` | Typed key/entry iteration and stable query-key hashing |
|
||||
| Strings | `capitalize`, `isNullOrWhitespace`, `bestMatch`, `normalizeImageName`, `getImageMatchRank` | Text normalization and matching |
|
||||
| Cookies | `parseCookies`, `setClientCookie` | Cookie parsing and browser cookie serialization |
|
||||
| Arrays | `splitToNChunks`, `splitToChunksWithNItems` | Split by number of groups or maximum group size |
|
||||
| Dates | `formatDuration`, `toValidDate`, `isDateWithin` | Duration formatting, safe date coercion, relative-window checks |
|
||||
| Timing | `Stopwatch` | Elapsed-time measurement and formatting |
|
||||
| React hooks | `useTimeAgo`, `useIntegrationConnected` | Relative time and integration freshness state |
|
||||
| URLs | `removeTrailingSlash`, `extractBaseUrlFromHeaders`, `getPortFromUrl`, `isAbsoluteUrl`, `SAFE_NEW_TAB_REL`, `getSafeApplicationUrl`, `getSafeAppHref` | URL normalization, safe navigation, ports, and new-tab policy |
|
||||
| Numbers and bytes | `formatNumber`, `randomInt`, `formatBytes`, `formatBytesPair`, `formatByteRate`, `metricToImperial`, `imperialToMetric` | Compact numbers, byte displays, rates, and unit conversion |
|
||||
| Legacy bytes | `humanFileSize` | Deprecated; use the `formatBytes*` helpers in new code |
|
||||
| Byte types | `ByteUnitSystem`, `FormatBytesOptions` | Options for byte formatting |
|
||||
| Errors | `extractErrorMessage`, `FlattenError` | Unknown-error messages and flattenable domain errors |
|
||||
| Theme | `getMantineColor` | Resolve a Mantine color and shade |
|
||||
| Functions | `isFunction` | Unknown-value function guard |
|
||||
| Grid | `GridAlgorithmItem`, `generateResponsiveGridFor` | Responsive nested-section grid placement |
|
||||
| IDs | `createId` | CUID2 ID creation |
|
||||
| Area | Public exports | Purpose |
|
||||
| ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| Objects | `objectKeys`, `objectEntries`, `isRecord`, `hashObjectBase64` | Typed key/entry iteration, record guards, and stable query-key hashing |
|
||||
| Strings | `capitalize`, `isNullOrWhitespace`, `bestMatch`, `normalizeImageName`, `getImageMatchRank` | Text normalization and matching |
|
||||
| Cookies | `parseCookies`, `setClientCookie` | Cookie parsing and browser cookie serialization |
|
||||
| Arrays | `splitToNChunks`, `splitToChunksWithNItems` | Split by number of groups or maximum group size |
|
||||
| Dates | `formatDuration`, `toValidDate`, `isDateWithin` | Duration formatting, safe date coercion, relative-window checks |
|
||||
| Timing | `Stopwatch` | Elapsed-time measurement and formatting |
|
||||
| React hooks | `useTimeAgo`, `useIntegrationConnected` | Relative time and integration freshness state |
|
||||
| URLs | `removeTrailingSlash`, `extractBaseUrlFromHeaders`, `getPortFromUrl`, `isAbsoluteUrl`, `SAFE_NEW_TAB_REL`, `getSafeApplicationUrl`, `getSafeAppHref` | URL normalization, safe navigation, ports, and new-tab policy |
|
||||
| Numbers and bytes | `formatNumber`, `formatBytes`, `formatBytesPair`, `formatByteRate`, `formatBitRate`, `defaultByteUnitSystem`, `metricToImperial` | Compact numbers, byte displays, byte/bit rates, and unit conversion |
|
||||
| Byte types | `ByteUnitSystem`, `FormatBytesOptions`, `FormatBitRateOptions` | Options for byte and bit-rate formatting |
|
||||
| Errors | `extractErrorMessage`, `FlattenError` | Unknown-error messages and flattenable domain errors |
|
||||
| Theme | `getMantineColor` | Resolve a Mantine color and shade |
|
||||
| Functions | `isFunction` | Unknown-value function guard |
|
||||
| Grid | `GridAlgorithmItem`, `generateResponsiveGridFor` | Responsive nested-section grid placement |
|
||||
| IDs | `createId` | CUID2 ID creation |
|
||||
|
||||
The root deliberately does not re-export `types`, `server`, `client`, or `env`; use their named entrypoints.
|
||||
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
---
|
||||
name: documentation-sync
|
||||
description: Keep Homarr's Fumadocs documentation aligned with user-facing code. Use when adding or changing integrations, widgets, APIs, environment variables, CLI commands, authentication, permissions, cron jobs, settings, or UI behavior that users must understand.
|
||||
description: Write concise Homarr docs for advanced users, covering only hidden capabilities and information not evident from the UI. Use when that information changes or existing guidance becomes inaccurate; skip obvious controls and routine fixes.
|
||||
---
|
||||
|
||||
# Documentation Sync
|
||||
|
||||
Update `apps/docs/` in the same change as user-facing behavior. Inspect adjacent pages and the docs types before copying a pattern; the source and docs evolve together.
|
||||
Apply the audience and scope rules in `AGENTS.md` first. Before adding a passage, identify what an advanced user could not learn directly from the interface. If there is no such information, omit it.
|
||||
|
||||
## Map the change
|
||||
For hidden capabilities such as the advanced widget feature, explain discovery, activation, and non-obvious behavior. For visible standard controls such as Delete, omit narration of what the label already conveys. Use the shortest explanation that preserves necessary technical detail; remove redundant prose in the passage being edited.
|
||||
|
||||
When an update is warranted, inspect adjacent pages for structure and types, not as a verbosity target. The mappings below locate needed information; they do not require a page for every feature or code change.
|
||||
|
||||
## Locate a needed update
|
||||
|
||||
| Code change | Documentation target |
|
||||
| ----------------------------------- | -------------------------------------------------------------------- |
|
||||
@@ -40,12 +44,12 @@ For a widget:
|
||||
|
||||
- Add or update `apps/docs/docs/widgets/<slug>/index.ts` with the local `WidgetDefinition` pattern.
|
||||
- Add or update `index.mdx` with the established `WidgetHeader`, `WidgetConfig`, and `AddingWidget` components as applicable.
|
||||
- Document options, required integrations, permissions, empty states, and changed behavior that affect setup or use.
|
||||
- Explain only non-obvious option semantics, integration prerequisites, permission constraints, or behavior that the interface does not make clear.
|
||||
|
||||
## Completion criteria
|
||||
|
||||
1. Describe the shipped behavior, not an implementation plan.
|
||||
1. Every passage adds information an advanced user cannot reasonably infer from the interface. Remove obvious, repetitive, or unnecessary prose.
|
||||
2. Keep names, defaults, paths, screenshots, links, and prerequisites consistent with code.
|
||||
3. Update every affected page and remove superseded guidance.
|
||||
4. Run the narrowest useful docs validation. Use `pnpm turbo build --filter=@homarr/docs` when links, MDX, generated definitions, or navigation can fail; otherwise run the docs package formatter on touched files.
|
||||
5. Treat broken links and anchors as failures; run `pnpm --filter @homarr/docs validate:links` after the static build.
|
||||
5. Treat broken links and anchors as failures; Docusaurus checks them strictly.
|
||||
@@ -16,9 +16,10 @@ LOG_LEVEL='info'
|
||||
|
||||
# This is how you can use the sqlite driver:
|
||||
DB_DRIVER='better-sqlite3'
|
||||
# Safe local source-development path. SQLite files are ignored by Git.
|
||||
# Set an absolute writable SQLite path so migrations and the app use the same file.
|
||||
# Their working directories differ; do not use a relative path here.
|
||||
# Container images use /appdata/db/db.sqlite by default instead.
|
||||
DB_URL='./db.sqlite'
|
||||
DB_URL=
|
||||
|
||||
# Those are the two ways to use the mysql2 driver:
|
||||
# 1. Using the URL format:
|
||||
|
||||
@@ -97,17 +97,16 @@ jobs:
|
||||
|
||||
- name: Validate Custom Widget bundle budget
|
||||
run: |
|
||||
pnpm --filter nextjs build
|
||||
pnpm turbo run build --filter=@homarr/nextjs
|
||||
pnpm check:custom-widget-bundle
|
||||
|
||||
- name: Run unit tests
|
||||
run: pnpm test
|
||||
|
||||
container:
|
||||
name: Container and E2E
|
||||
name: Container build
|
||||
# Same-repository previews already build amd64; only build a fallback when no digest is available.
|
||||
needs: [fast-gate, preview-amd64]
|
||||
if: |
|
||||
!cancelled() && needs.fast-gate.result == 'success' &&
|
||||
needs.preview-amd64.result != 'failure' && needs.preview-amd64.outputs.digest == '' &&
|
||||
(
|
||||
github.event_name == 'merge_group' ||
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/release/v2') ||
|
||||
@@ -115,10 +114,9 @@ jobs:
|
||||
(github.event_name == 'workflow_dispatch' && (inputs.operation == 'validate' || inputs.operation == 'publish'))
|
||||
)
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 30
|
||||
timeout-minutes: 20
|
||||
permissions:
|
||||
contents: read
|
||||
packages: read
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
if: "!env.ACT"
|
||||
@@ -126,23 +124,10 @@ jobs:
|
||||
persist-credentials: false
|
||||
ref: ${{ github.event_name == 'workflow_dispatch' && inputs.ref || '' }}
|
||||
|
||||
- name: Setup
|
||||
uses: ./tooling/github/setup
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
if: "!env.ACT"
|
||||
if: needs.preview-amd64.outputs.digest == '' && !env.ACT
|
||||
uses: docker/setup-buildx-action@v4
|
||||
|
||||
- name: Reuse amd64 preview image
|
||||
if: needs.preview-amd64.outputs.digest != '' && !env.ACT
|
||||
env:
|
||||
DIGEST: ${{ needs.preview-amd64.outputs.digest }}
|
||||
run: |
|
||||
echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
docker pull "${PREVIEW_IMAGE}@${DIGEST}"
|
||||
docker tag "${PREVIEW_IMAGE}@${DIGEST}" homarr-ci
|
||||
docker tag "${PREVIEW_IMAGE}@${DIGEST}" homarr-e2e
|
||||
|
||||
- name: Build container once
|
||||
if: needs.preview-amd64.outputs.digest == '' && !env.ACT
|
||||
uses: docker/build-push-action@v7
|
||||
@@ -152,9 +137,7 @@ jobs:
|
||||
platforms: linux/amd64
|
||||
load: true
|
||||
push: false
|
||||
tags: |
|
||||
homarr-ci
|
||||
homarr-e2e
|
||||
tags: homarr-ci
|
||||
labels: |
|
||||
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
|
||||
org.opencontainers.image.revision=${{ github.sha }}
|
||||
@@ -182,37 +165,7 @@ jobs:
|
||||
fi
|
||||
done
|
||||
DOCKER_BUILDKIT=1 docker build --platform linux/amd64 \
|
||||
--tag homarr-ci --tag homarr-e2e "${secret_args[@]}" .
|
||||
|
||||
- name: Cache Playwright browsers
|
||||
if: "!env.ACT"
|
||||
id: playwright-cache
|
||||
uses: actions/cache@v6
|
||||
with:
|
||||
path: ~/.cache/ms-playwright
|
||||
key: playwright-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install Playwright Chromium
|
||||
if: steps.playwright-cache.outputs.cache-hit != 'true' || env.ACT
|
||||
run: pnpm exec playwright install --with-deps chromium
|
||||
|
||||
- name: Install Playwright system deps
|
||||
if: steps.playwright-cache.outputs.cache-hit == 'true'
|
||||
run: pnpm exec playwright install-deps chromium
|
||||
|
||||
- name: Run E2E tests
|
||||
env:
|
||||
NODE_ENV: development
|
||||
CI: "true"
|
||||
run: pnpm exec vitest e2e --retry 1 --maxWorkers 4
|
||||
|
||||
- name: Upload E2E artifacts
|
||||
if: failure() && !env.ACT
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: playwright-report
|
||||
path: e2e/test-results/
|
||||
retention-days: 7
|
||||
--tag homarr-ci "${secret_args[@]}" .
|
||||
|
||||
preview-amd64:
|
||||
name: Build amd64 preview image
|
||||
@@ -320,10 +273,10 @@ jobs:
|
||||
|
||||
publish-preview:
|
||||
name: Publish multi-platform preview image
|
||||
needs: [container, preview-amd64, preview-arm64]
|
||||
needs: [fast-gate, preview-amd64, preview-arm64]
|
||||
if: |
|
||||
!cancelled() &&
|
||||
needs.container.result == 'success' &&
|
||||
needs.fast-gate.result == 'success' &&
|
||||
needs.preview-amd64.result == 'success' &&
|
||||
needs.preview-arm64.result == 'success' &&
|
||||
(
|
||||
|
||||
@@ -16,10 +16,10 @@ permissions:
|
||||
jobs:
|
||||
create-and-merge-pr:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 2
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Discord notification
|
||||
if: ${{ github.event.inputs.send-notifications }}
|
||||
if: ${{ inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@0.4.0
|
||||
@@ -37,11 +37,22 @@ jobs:
|
||||
branch: next
|
||||
- name: Create pull request
|
||||
id: create-pull-request
|
||||
run: 'gh pr create --title "chore(release): release ${{ steps.semver.outputs.next }}-beta" --body "Detected change to be ``${{ steps.semver.outputs.bump }}``<br/>Bump version from ``${{ steps.semver.outputs.current }}`` to ``${{ steps.semver.outputs.next }}-beta``" --base beta --head next --label automerge'
|
||||
run: |
|
||||
pr_url="$(gh pr list --base beta --head next --state open --json url --jq '.[0].url // empty')"
|
||||
if [[ -z "$pr_url" ]]; then
|
||||
pr_url="$(gh pr create \
|
||||
--title "chore(release): release ${{ steps.semver.outputs.next }}-beta" \
|
||||
--body "Detected change to be ${{ steps.semver.outputs.bump }}<br/>Bump version from ${{ steps.semver.outputs.current }} to ${{ steps.semver.outputs.next }}-beta" \
|
||||
--base beta \
|
||||
--head next \
|
||||
--label automerge)"
|
||||
fi
|
||||
echo "url=$pr_url" >> "$GITHUB_OUTPUT"
|
||||
echo "pr_number=${pr_url##*/}" >> "$GITHUB_OUTPUT"
|
||||
env:
|
||||
GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
|
||||
- name: Discord notification
|
||||
if: ${{ github.event.inputs.send-notifications }}
|
||||
if: ${{ inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@0.4.0
|
||||
@@ -58,7 +69,7 @@ jobs:
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ steps.obtainApprovalToken.outputs.token }}
|
||||
run: |
|
||||
gh pr review --approve --body "Automatically approved by GitHub Action"
|
||||
gh pr review "${{ steps.create-pull-request.outputs.url }}" --approve --body "Automatically approved by GitHub Action"
|
||||
- name: Obtain token
|
||||
id: obtainMergeToken
|
||||
uses: actions/create-github-app-token@v3
|
||||
@@ -82,21 +93,21 @@ jobs:
|
||||
MERGE_REQUIRED_APPROVALS: 0 # do not require approvals
|
||||
|
||||
- name: Merged Discord notification
|
||||
if: ${{ steps.automerge.outputs.mergeResult == 'merged' && github.event.inputs.send-notifications }}
|
||||
if: ${{ steps.automerge.outputs.mergeResult == 'merged' && inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@0.4.0
|
||||
with:
|
||||
args: "Merged PR ${{ steps.create-pull-request.outputs.url }} for release ${{ steps.semver.outputs.next }}-beta"
|
||||
- name: Major Bump Discord notification
|
||||
if: ${{ steps.semver.outputs.bump == 'major' && github.event.inputs.send-notifications }}
|
||||
if: ${{ steps.semver.outputs.bump == 'major' && inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@0.4.0
|
||||
with:
|
||||
args: "The release PR must be manually merged because the next version is a major version: ${{ steps.create-pull-request.outputs.url }} for release ${{ steps.semver.outputs.next }}-beta"
|
||||
- name: Discord Fail Notification
|
||||
if: failure() && github.event.inputs.send-notifications
|
||||
if: ${{ failure() && inputs.send-notifications }}
|
||||
env:
|
||||
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
||||
uses: Ilshidur/action-discord@0.4.0
|
||||
|
||||
@@ -42,7 +42,7 @@ jobs:
|
||||
- name: Upload pages artifact
|
||||
uses: actions/upload-pages-artifact@v5
|
||||
with:
|
||||
path: "apps/docs/out"
|
||||
path: "apps/docs/build"
|
||||
|
||||
deploy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
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
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
- name: Commit updated contributors
|
||||
uses: EndBug/add-and-commit@v10
|
||||
with:
|
||||
add: "apps/docs/public"
|
||||
add: "apps/docs/static"
|
||||
default_author: github_actor
|
||||
message: "chore(docs): update contributors"
|
||||
push: true
|
||||
@@ -26,41 +26,13 @@ jobs:
|
||||
- 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/public/api/open-api-schema.json
|
||||
echo "OpenAPI spec updated ($(jq '.paths | length' /tmp/openapi.json) paths)"
|
||||
- name: Generate and validate OpenAPI spec
|
||||
run: pnpm scripts:update-openapi
|
||||
|
||||
- name: Commit updated spec
|
||||
uses: EndBug/add-and-commit@v10
|
||||
with:
|
||||
add: "apps/docs/public/api/"
|
||||
add: "apps/docs/static/api/"
|
||||
default_author: github_actor
|
||||
message: "chore(docs): update OpenAPI spec"
|
||||
push: true
|
||||
@@ -2,8 +2,36 @@ name: Workshop
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- ".github/workflows/workshop.yml"
|
||||
- "apps/workshop/**"
|
||||
- "apps/docs/**"
|
||||
- "packages/custom-widgets/**"
|
||||
- "packages/definitions/**"
|
||||
- "packages/workshop/**"
|
||||
- "tooling/typescript/**"
|
||||
- "patches/**"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "turbo.json"
|
||||
- ".npmrc"
|
||||
push:
|
||||
branches: [dev, v2, release/v2, main]
|
||||
paths:
|
||||
- ".github/workflows/workshop.yml"
|
||||
- "apps/workshop/**"
|
||||
- "apps/docs/**"
|
||||
- "packages/custom-widgets/**"
|
||||
- "packages/definitions/**"
|
||||
- "packages/workshop/**"
|
||||
- "tooling/typescript/**"
|
||||
- "patches/**"
|
||||
- "package.json"
|
||||
- "pnpm-lock.yaml"
|
||||
- "pnpm-workspace.yaml"
|
||||
- "turbo.json"
|
||||
- ".npmrc"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -15,21 +43,10 @@ concurrency:
|
||||
jobs:
|
||||
validate:
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 30
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- uses: actions/checkout@v7
|
||||
- uses: actions/setup-node@v6
|
||||
with:
|
||||
node-version: 24.18.0
|
||||
- uses: pnpm/action-setup@v6
|
||||
with:
|
||||
run_install: false
|
||||
- run: pnpm install --frozen-lockfile
|
||||
- run: pnpm --filter @homarr/workshop typecheck
|
||||
- run: pnpm --filter @homarr/docs typecheck
|
||||
- run: docker compose --env-file apps/workshop/.env.staging.example -f apps/workshop/docker-compose.staging.yml config --quiet
|
||||
- run: pnpm test:workshop
|
||||
- run: pnpm test:workshop-image
|
||||
|
||||
publish-amd64:
|
||||
if: github.event_name == 'push' && (github.ref_name == 'v2' || github.ref_name == 'release/v2' || github.ref_name == 'main')
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
"apps/docs/blog/2024/**",
|
||||
"apps/docs/blog/2025/**",
|
||||
"apps/docs/blog/authors.yml",
|
||||
"apps/docs/static/api/open-api-schema.json",
|
||||
"packages/custom-widgets/src/core/component-catalog.generated.json",
|
||||
"apps/docs/static/custom-widgets/component-catalog-v1.json"
|
||||
]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
homarr/
|
||||
├── apps/
|
||||
│ ├── nextjs/ # Main Next.js application (port 3000)
|
||||
│ ├── docs/ # Next.js + Fumadocs documentation site (@homarr/docs)
|
||||
│ ├── docs/ # Docusaurus 3 documentation site (@homarr/docs)
|
||||
│ ├── tasks/ # Cron-job initialization and scheduling runtime
|
||||
│ ├── websocket/ # Standalone tRPC WebSocket server (port 3001)
|
||||
│ └── workshop/ # Go/PocketBase Workshop service
|
||||
@@ -57,9 +57,15 @@ homarr/
|
||||
|
||||
## Documentation Sync
|
||||
|
||||
The documentation site lives at `apps/docs/` (Next.js + Fumadocs, `@homarr/docs`).
|
||||
The documentation site lives at `apps/docs/` (Docusaurus 3, `@homarr/docs`).
|
||||
|
||||
When modifying user-facing code, you MUST also update the corresponding documentation:
|
||||
Write for smart, curious, advanced users. Documentation should contain only information they cannot reasonably discover or understand directly from the interface: hidden capabilities, non-obvious behavior, prerequisites, constraints, configuration contracts, and migration requirements.
|
||||
|
||||
Keep docs concise. Every paragraph must add knowledge beyond visible labels and standard UI conventions. Explain how to discover and use a hidden advanced widget feature; omit explanations that the Delete button deletes an item in edit mode. Avoid UI walkthroughs, exhaustive control descriptions, and repetition. When editing a passage, remove obvious or redundant prose rather than preserving verbosity as a precedent.
|
||||
|
||||
Update docs only when a change introduces or alters that non-obvious information, or makes existing guidance inaccurate. Routine fixes and self-explanatory UI changes need no docs update. A new feature alone does not require a page; apply the same reader-value test.
|
||||
|
||||
When documentation is needed, use these locations:
|
||||
|
||||
- New integration → `apps/docs/docs/integrations/<slug>/index.mdx` + `index.ts`
|
||||
- New widget → `apps/docs/docs/widgets/<slug>/index.mdx` + `index.ts`
|
||||
@@ -75,7 +81,7 @@ When modifying user-facing code, you MUST also update the corresponding document
|
||||
- `pnpm dev:cli -- dev` — run the developer CLI without installing a global binary
|
||||
- `pnpm db:seed` — seed default database data explicitly
|
||||
- `pnpm docker:dev:up` — start the Redis development service in the background
|
||||
- `pnpm dev:docs` — Fumadocs site 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
|
||||
@@ -99,6 +105,6 @@ When modifying user-facing code, you MUST also update the corresponding document
|
||||
Portable skills live in `.agents/skills/`. Read the relevant `SKILL.md` before working in that domain; detailed references are loaded only when needed. Claude-compatible discovery is provided through `.claude/skills`.
|
||||
|
||||
- `codebase-context` — architecture, package boundaries, and shared utilities
|
||||
- `documentation-sync` — required user-facing documentation updates
|
||||
- `documentation-sync` — documentation for changes users need explained
|
||||
- `mcp-integration` — safe tRPC-to-MCP exposure
|
||||
- `homarr-custom-widget` — safe Custom JSX v2 authoring
|
||||
@@ -13,7 +13,6 @@
|
||||
# next.js
|
||||
/.next/
|
||||
/out/
|
||||
/.source/
|
||||
|
||||
# production
|
||||
/build
|
||||
@@ -56,4 +55,4 @@ static/data/configs
|
||||
|
||||
# CI Stuff
|
||||
screenshots
|
||||
test-results
|
||||
test-results
|
||||
@@ -1,9 +0,0 @@
|
||||
<!-- BEGIN:nextjs-agent-rules -->
|
||||
|
||||
# This is NOT the Next.js you know
|
||||
|
||||
This version has breaking changes — APIs, conventions, and file structure may all differ from your training data. Read the relevant guide in `node_modules/next/dist/docs/` (resolved from this file's directory; in monorepos the `next` package may not be visible from the repo root) before writing any code. Heed deprecation notices.
|
||||
|
||||
This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean.
|
||||
|
||||
<!-- END:nextjs-agent-rules -->
|
||||
@@ -1 +0,0 @@
|
||||
@AGENTS.md
|
||||
@@ -1,37 +0,0 @@
|
||||
# Homarr Documentation
|
||||
|
||||
## Register
|
||||
|
||||
product
|
||||
|
||||
## Users
|
||||
|
||||
People who run Homarr, administrators configuring self-hosted infrastructure, and contributors extending Homarr. They arrive with a concrete task such as installing Homarr, connecting a service, configuring a widget, managing users, or building a custom widget, and need an answer they can scan and apply quickly.
|
||||
|
||||
## Product Purpose
|
||||
|
||||
The documentation is the complete, authoritative operating guide for Homarr. It keeps setup steps, configuration contracts, screenshots, generated integration and widget metadata, API references, and Workshop tooling next to the application code. Success means a reader can find the right page quickly, understand the next action, copy reliable instructions, and verify the result without searching elsewhere.
|
||||
|
||||
## Brand Personality
|
||||
|
||||
Focused, dependable, and approachable. The writing is direct and practical. The interface should feel calm and familiar during long technical sessions while retaining Homarr's red identity.
|
||||
|
||||
## Anti-references
|
||||
|
||||
- Generic marketing layouts that replace Homarr's product identity with unrelated slogans or decorative conversion copy.
|
||||
- Decorative dashboard aesthetics that compete with reading, including glass effects, large radii, card grids, and gratuitous motion.
|
||||
- Generic generated-docs styling that obscures Homarr's identity or makes navigation feel detached from the main product.
|
||||
- Dense reference portals that expose structure without giving readers a clear path through a task.
|
||||
|
||||
## Design Principles
|
||||
|
||||
1. Put the reader's task first: search, navigation, page outline, and the answer must remain easy to reach.
|
||||
2. Preserve one source of truth: typed Homarr metadata and existing custom components stay connected to the monorepo.
|
||||
3. Prefer familiar documentation patterns: the interface should disappear while a reader scans, copies, and follows instructions.
|
||||
4. Make complete content feel manageable through strong hierarchy, progressive disclosure, and precise cross-links.
|
||||
5. Treat machine readers as users through canonical Markdown, structured metadata, and standard LLM discovery endpoints.
|
||||
6. Keep the root landing page recognizably Homarr: preserve its self-hosted dashboard promise and real product evidence while documentation routes remain task-first.
|
||||
|
||||
## Accessibility & Inclusion
|
||||
|
||||
Meet WCAG 2.2 AA for color contrast, keyboard operation, focus visibility, landmarks, headings, and interactive controls. Respect reduced-motion and system color-scheme preferences. Diagrams, screenshots, icons, and emoji must have meaningful text alternatives when they carry information.
|
||||
@@ -1,52 +1,112 @@
|
||||
# Homarr documentation (`@homarr/docs`)
|
||||
# Homarr Documentation (`@homarr/docs`)
|
||||
|
||||
The source for [homarr.dev](https://homarr.dev), built with Next.js and Fumadocs UI inside the Homarr monorepo.
|
||||
The official [homarr.dev](https://homarr.dev) documentation site, built with [Docusaurus 3](https://docusaurus.io/) and living inside the Homarr monorepo.
|
||||
|
||||
## Develop
|
||||
## Why it's in the monorepo
|
||||
|
||||
From the repository root:
|
||||
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
|
||||
```
|
||||
|
||||
The site runs on `http://127.0.0.1:3003`. To use a local Workshop API:
|
||||
# Or from within this directory
|
||||
pnpm dev
|
||||
|
||||
```bash
|
||||
# Point the docs at a local PocketBase instance
|
||||
WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs
|
||||
```
|
||||
|
||||
## Validate
|
||||
The standalone docs use `WORKSHOP_API_URL` for PocketBase and `HOMARR_WEBSITE_URL` for the public site origin. The old
|
||||
`WORKSHOP_URL` name is a deprecated one-release alias.
|
||||
|
||||
## Build
|
||||
|
||||
```bash
|
||||
pnpm --filter @homarr/docs typecheck
|
||||
pnpm --filter @homarr/docs build
|
||||
pnpm --filter @homarr/docs validate:links
|
||||
# Build docs only
|
||||
pnpm turbo build --filter=@homarr/docs
|
||||
|
||||
# Build everything (docs + main app + tasks + websocket)
|
||||
pnpm build
|
||||
```
|
||||
|
||||
The static export is written to `out/`. The build validates that every registered integration and widget has a docs
|
||||
page. The link check validates internal Markdown and MDX links against that export.
|
||||
## Lint & Format
|
||||
|
||||
## Write content
|
||||
Uses oxlint and oxfmt (same as the rest of the monorepo):
|
||||
|
||||
Documentation lives in `docs/`; project posts live in `blog/`. Navigation is controlled by the nearest `meta.json`.
|
||||
Integration and widget folders pair typed `index.ts` metadata with `index.mdx` content.
|
||||
```bash
|
||||
pnpm lint # oxlint
|
||||
pnpm format # oxfmt (check)
|
||||
pnpm format:fix # oxfmt (fix)
|
||||
```
|
||||
|
||||
Use standard Markdown and MDX. Shared components live in `src/components/`. Mermaid fences, tabs, callouts, zoomable
|
||||
images, and syntax-highlighted code are supported by the Fumadocs pipeline.
|
||||
## Typecheck
|
||||
|
||||
When a user-facing change affects setup or behavior, update the matching page in the same pull request. See the
|
||||
[documentation-sync skill](../../.agents/skills/documentation-sync/SKILL.md) for the code-to-content map.
|
||||
```bash
|
||||
pnpm typecheck
|
||||
```
|
||||
|
||||
## Published formats
|
||||
## Content Structure
|
||||
|
||||
- `/docs` — searchable documentation with typed navigation
|
||||
- `/api-reference` — interactive reference generated from the OpenAPI schema
|
||||
- `/llms.txt` — compact documentation and blog index for agents
|
||||
- `/llms-full.txt` — complete processed Markdown corpus
|
||||
- `/llms.mdx/docs/.../content.md` — raw Markdown for each docs page
|
||||
- `/llms.mdx/blog/.../content.md` — raw Markdown for each blog post
|
||||
- `/blog/rss.xml` — RSS feed for project posts
|
||||
```
|
||||
docs/
|
||||
├── getting-started/ # Installation guides, glossary, prerequisites
|
||||
├── management/ # Boards, apps, users, integrations, settings, tasks, API
|
||||
├── integrations/ # 56 integration guides (one folder each)
|
||||
├── widgets/ # 43 widget guides (one folder each)
|
||||
├── advanced/ # SSO, env vars, proxy, styling, CLI, development
|
||||
└── community/ # FAQ, donate, license, translations, get-in-touch
|
||||
```
|
||||
|
||||
Every docs page and blog post includes copy-Markdown and view-source actions. Search is generated at build time and
|
||||
runs locally in the browser; it does not depend on an external crawler.
|
||||
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 4 + Docusaurus Infima |
|
||||
| Icons | `@tabler/icons-react` |
|
||||
| Diagrams | Mermaid (`@docusaurus/theme-mermaid`) |
|
||||
| Search | Algolia DocSearch |
|
||||
| Analytics | PostHog |
|
||||
| Charts | @nivo/line |
|
||||
|
||||
## Contributing
|
||||
|
||||
When a Homarr change affects user-facing behavior, update the corresponding documentation in this app. See the
|
||||
[documentation-sync skill](../../.agents/skills/documentation-sync/SKILL.md) for the code-to-documentation mapping.
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
slug: documentation-migration
|
||||
title: Migration of Documentation
|
||||
date: 2022-06-22
|
||||
authors:
|
||||
- ajnart
|
||||
- manuel-rw
|
||||
@@ -13,7 +12,7 @@ The documentation has been re-written partly and includes now many animations, g
|
||||
|
||||
We are still figuring things out and highly depend on your feedback.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## Why we migrated
|
||||
|
||||
@@ -33,4 +32,4 @@ After we've reviewed your changes, we'll merge your PR and this documentation wi
|
||||
|
||||
## 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.
|
||||
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.
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
slug: translations
|
||||
title: Help us make Homarr multilingual
|
||||
date: 2022-08-28
|
||||
authors:
|
||||
- ajnart
|
||||
- manuel-rw
|
||||
@@ -14,8 +13,8 @@ We've been working hard to offer Homarr in many languages. The next update of Ho
|
||||
 <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).
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- 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! 😎
|
||||
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! 😎
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
title: "We present: Homarr 0.11 - the most complex Homarr version yet!"
|
||||
date: 2023-01-11
|
||||
authors:
|
||||
- ajnart
|
||||
- manuel-rw
|
||||
@@ -21,7 +20,7 @@ It contains many breaking changes and huge improvements to your favourite dashbo
|
||||
- Huge design and usability improvements to older components to Homarr
|
||||
- Better handeling of exceptions and unexpected issues
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## Complete implementation of highly customizable drag and drop library "Gridstack"
|
||||
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
title: "We present: Homarr 0.12 - The fastest homarr version ever!"
|
||||
date: 2023-04-16
|
||||
authors:
|
||||
- ajnart
|
||||
- manuel-rw
|
||||
@@ -16,12 +15,14 @@ This applies to all widgets, but in the case of the IFrame widget, it enables yo
|
||||
- Integrate monitoring tools like Grafana, Splunk or Elasticsearch
|
||||
- Integrate your services (for example Sonarr, Radarr and Overseerr) directly into Homarr
|
||||
|
||||

|
||||
|
||||
## 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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- 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* !!!
|
||||
@@ -71,4 +72,4 @@ 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
|
||||
**Full Changelog**: https://github.com/ajnart/homarr/compare/v0.11.5...v0.12.0
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
title: "Authentication in Homarr - 0.14 is here!"
|
||||
date: 2023-11-10
|
||||
authors:
|
||||
- ajnart
|
||||
- manuel-rw
|
||||
@@ -24,7 +23,7 @@ provide you a viable solution today.
|
||||
- 📝 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
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## Breaking changes
|
||||
|
||||
@@ -84,4 +83,4 @@ We are aware that this update has many breaking changes and may confuse some use
|
||||
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:
|
||||
|
||||

|
||||

|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
title: "Updated documentation with better organization & design"
|
||||
date: 2023-12-22
|
||||
authors:
|
||||
- manuel-rw
|
||||
tags: [homarr, documentation, design, docs]
|
||||
@@ -9,7 +8,7 @@ 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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
A few highlights include:
|
||||
|
||||
@@ -19,4 +18,4 @@ A few highlights include:
|
||||
- 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.
|
||||
Please [let us know](/docs/community/get-in-touch) is something is not working as expected.
|
||||
@@ -1,10 +1,9 @@
|
||||
---
|
||||
title: Homarr 1.0 - complete rewrite of all systems
|
||||
date: 2024-09-23
|
||||
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.
|
||||
|
||||
@@ -29,7 +28,7 @@ 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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## Breaking changes
|
||||
:::warning
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
---
|
||||
title: Open Beta 1.0
|
||||
date: 2024-12-17
|
||||
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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## How to use the beta with docker
|
||||
|
||||
@@ -36,4 +36,4 @@ services:
|
||||
|
||||
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)
|
||||
You can find a list of all breaking changes [here](/blog/2024/09/23/version-1.0)
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: Migrate from 0.15.10+ to 1.0.0
|
||||
date: 2025-01-19
|
||||
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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
## Preserve your old installation
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: How to use Argus with Homarr
|
||||
date: 2025-08-02
|
||||
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.
|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||

|
||||
|
||||
@@ -64,4 +64,4 @@ Now you can configure Argus to use the user and apiKey we created.
|
||||
|
||||

|
||||
|
||||
Replace the `<secret>` with the apiKey you created and the deployed version url with the url of your Homarr instance.
|
||||
Replace the `<secret>` with the apiKey you created and the deployed version url with the url of your Homarr instance.
|
||||
@@ -1,9 +1,9 @@
|
||||
---
|
||||
title: Homarr 2.0.0 - Workshop, Custom Widgets and a rebuilt board
|
||||
date: 2026-09-03
|
||||
authors:
|
||||
- ajnart
|
||||
tags: [homarr, update, version, assistant, custom widgets, dashboards, docker]
|
||||
description: Homarr 2.0 introduces Custom Widgets and Workshop, rebuilt board editing, Assistant tooling, responsive layouts, onboarding, and more.
|
||||
image: ./img/homarr-v2-dashboard.webp
|
||||
draft: false
|
||||
---
|
||||
|
||||
@@ -15,17 +15,13 @@ Many of you used the v2 demo when it was still rough, found bugs and came back t
|
||||
|
||||
We are also planning a small batch of **free, limited-edition Homarr swag** for Workshop contributors and a few randomly picked community members. It is not for sale and it is not for profit. No Homarr merch empire, sorry.
|
||||
|
||||
Homarr 2.0 is an upgrade, not a brand-new app wearing the same logo. Here is what actually changed.
|
||||
Homarr 2.0 builds on the dashboard you already use. Here is what changed.
|
||||
|
||||

|
||||
|
||||
{/* Historical excerpt boundary. */}
|
||||
<!-- truncate -->
|
||||
|
||||
:::warning Back up before upgrading
|
||||
|
||||
Create a [Homarr backup](/docs/management/backup) first. Do not test a prerelease image on your only production volume. Backups are boring. Restores are worse.
|
||||
|
||||
:::
|
||||
Update your Homarr image as usual. Homarr runs database migrations automatically when the updated container starts; no manual database migration or separate v2 upgrade procedure is needed. Workshop uses the production service by default, with no preview URL configuration required.
|
||||
|
||||
## Custom Widgets v2 and Workshop
|
||||
|
||||
@@ -148,9 +144,8 @@ Groups use a new Viewer, Editor and Admin matrix. The API, Assistant and MCP fol
|
||||
|
||||
Board startup work runs in parallel, heavy screens load when opened, and identical integration requests share work instead of doing it twice.
|
||||
|
||||
## Before upgrading
|
||||
## Compatibility notes
|
||||
|
||||
- Keep a backup and use the final release image, not a prerelease tag.
|
||||
- Legacy Custom JSX definitions enter a migration state. Homarr keeps encrypted credentials and an archived copy until the v2 definition validates.
|
||||
- Mobile layouts place rail content in the main flow instead of displaying rails.
|
||||
- Custom Widgets remain Beta.
|
||||
@@ -158,7 +153,7 @@ Board startup work runs in parallel, heavy screens load when opened, and identic
|
||||
|
||||
## Links
|
||||
|
||||
- Try the [Homarr 2.0 preview](https://app-v2.preview.homarr.dev).
|
||||
- Follow the [v2 release pull request](https://github.com/homarr-labs/homarr/pull/6545) and [public beta thread](https://github.com/homarr-labs/homarr/issues/6600).
|
||||
- Compare [v1.76.2 with the release/v2 branch](https://github.com/homarr-labs/homarr/compare/v1.76.2...release/v2).
|
||||
- Try the [live demo](https://demo.homarr.dev/).
|
||||
- See [installation and update instructions](/docs/getting-started/installation/docker).
|
||||
- Browse [Workshop](https://homarr.dev/workshop).
|
||||
- Read the guides for [Boards](/docs/management/boards), [Custom Widgets](/docs/management/custom-widgets), [Assistant](/docs/management/assistant), [MCP](/docs/management/mcp) and [Docker labels](/docs/integrations/docker-labels).
|
||||
@@ -5,7 +5,7 @@
|
||||
"tsx": true,
|
||||
"tailwind": {
|
||||
"config": "",
|
||||
"css": "src/app/global.css",
|
||||
"css": "src/css/custom.css",
|
||||
"baseColor": "mist",
|
||||
"cssVariables": true,
|
||||
"prefix": ""
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Advanced",
|
||||
"collapsed": true,
|
||||
"position": 5,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Advanced Concepts or features"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"collapsed": true,
|
||||
"label": "Command line interface"
|
||||
}
|
||||
@@ -90,7 +90,7 @@ homarr run dev
|
||||
homarr run --detach dev
|
||||
homarr run --pr 6441
|
||||
homarr run --pr 6441 --demo
|
||||
homarr --pr 6441 --env WORKSHOP_WEB_URL=https://app-v2.preview.homarr.dev/
|
||||
homarr --pr 6441 --env WORKSHOP_WEB_URL=https://workshop.example.com/workshop
|
||||
```
|
||||
|
||||
- `--pr <number>`: Pull and run a PR image from GHCR (shorthand: `homarr --pr <number>`).
|
||||
@@ -148,13 +148,18 @@ homarr images rm feature
|
||||
# List data volumes with owner PR/tag and in-use status
|
||||
homarr data
|
||||
|
||||
# Delete data volume (safely stops and removes owning container first)
|
||||
# Preview deleting a data volume and its owning container
|
||||
homarr data rm homarr_feature_data
|
||||
|
||||
# Permanently delete the data after reviewing the preview
|
||||
homarr data rm homarr_feature_data --force
|
||||
|
||||
# Remove stopped containers (prompts without --force)
|
||||
homarr prune --force
|
||||
```
|
||||
|
||||
Forced data deletion removes the derived owner container only when it mounts the exact selected volume. A same-named container that does not own that volume stops the operation.
|
||||
|
||||
### Instance Operations & Diagnostics
|
||||
|
||||
```bash
|
||||
|
||||
@@ -14,4 +14,4 @@ homarr fix-usernames
|
||||
|
||||
This will convert all credential usernames to lowercase and update the database accordingly.
|
||||
|
||||

|
||||

|
||||
@@ -4,6 +4,7 @@ The Homarr image includes a recovery CLI for operations that cannot be completed
|
||||
application API; use the [API](/docs/management/api) or [MCP endpoint](/docs/management/mcp) for automation.
|
||||
|
||||
Back up the database and stop Homarr before running a command that changes data.
|
||||
Failed commands print an error and return a non-zero exit code, so shell scripts can stop safely.
|
||||
|
||||
## Run the recovery CLI
|
||||
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"title": "Command line interface",
|
||||
"pages": ["index", "users", "integrations", "password-recovery", "fix-usernames", "development"]
|
||||
}
|
||||
@@ -10,10 +10,10 @@ 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.
|
||||
|
||||

|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||

|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"label": "Developer guides",
|
||||
"position": 6,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
@@ -31,9 +31,13 @@ pnpm install --frozen-lockfile
|
||||
### Run the Homarr application
|
||||
|
||||
1. Copy `.env.example` to `.env`.
|
||||
2. Set `DB_URL` to an absolute writable SQLite file path.
|
||||
3. Keep Redis and the optional local databases running in one terminal.
|
||||
4. Apply migrations and start Next.js in another terminal.
|
||||
2. Run `openssl rand -hex 32` twice. Set `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` to the two different generated
|
||||
values in `.env`; the example leaves both empty. Keep this file private and preserve `SECRET_ENCRYPTION_KEY`
|
||||
when reusing a database.
|
||||
3. Set `DB_URL` to an absolute writable SQLite file path. Migration and application commands run from different
|
||||
workspace directories, so a relative path can point them at different databases.
|
||||
4. Keep Redis and the optional local databases running in one terminal.
|
||||
5. Apply migrations and start Next.js in another terminal.
|
||||
|
||||
```sh
|
||||
cp .env.example .env
|
||||
@@ -57,8 +61,22 @@ Homarr becomes the instance administrator.
|
||||
Use `pnpm docker:dev:up` instead when you only need Redis in the background. Running the migration also seeds the
|
||||
default data; use `pnpm db:seed` to seed it explicitly later.
|
||||
|
||||
Workshop contributors can set up PocketBase and Fumadocs with the dedicated
|
||||
[Workshop development guide](/docs/advanced/development/workshop).
|
||||
`pnpm dev` starts only Next.js. When your work needs scheduled tasks or live subscriptions, run the relevant service
|
||||
in a separate terminal alongside it:
|
||||
|
||||
```sh
|
||||
pnpm --filter @homarr/tasks dev
|
||||
```
|
||||
|
||||
```sh
|
||||
pnpm --filter @homarr/websocket dev
|
||||
```
|
||||
|
||||
The WebSocket service listens on port 3001. Production startup embeds both services, so these extra commands are
|
||||
only needed for development.
|
||||
|
||||
Workshop contributors can set up PocketBase and Docusaurus with the dedicated
|
||||
[Workshop development guide](./workshop).
|
||||
|
||||
### Useful commands
|
||||
|
||||
@@ -69,7 +87,7 @@ Workshop contributors can set up PocketBase and Fumadocs with the dedicated
|
||||
- `pnpm dev:cli -- build --pr <number>` — build a pull request from a temporary checkout.
|
||||
- `pnpm dev:cli -- rebuild <name>` — rebuild an image from its recorded checkout or pull request.
|
||||
- `pnpm dev:cli:install` — optionally install the developer CLI as a `homarr` binary.
|
||||
- `pnpm dev:docs` — Fumadocs on port 3003.
|
||||
- `pnpm dev:docs` — Docusaurus only on port 3003.
|
||||
- `pnpm docker:dev:up` — Redis development service in the background.
|
||||
- `pnpm cli` — Homarr operations CLI.
|
||||
- `pnpm db:migration:sqlite:run` — create or update a SQLite database.
|
||||
@@ -80,5 +98,27 @@ Workshop contributors can set up PocketBase and Fumadocs with the dedicated
|
||||
- `pnpm typecheck` — typecheck all workspaces.
|
||||
- `pnpm test` — unit and contract suites.
|
||||
- `pnpm build` — production monorepo build.
|
||||
- `docker build -t homarr .` — build a production Docker image.
|
||||
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:<name>` — run it.
|
||||
- `docker build -t homarr:local .` — build a production Docker image.
|
||||
- `docker run -p 7575:7575 -e SECRET_ENCRYPTION_KEY='your_64_character_hex_string' homarr:local` — run it.
|
||||
|
||||
## CI and focused validation
|
||||
|
||||
The main CI workflow runs lint, typechecking, affected workspace builds, workspace configuration checks, OpenAPI validation, and Custom Widget architecture and bundle checks. Unit and E2E suites do not run in CI. Preview images publish after the Fast gate and both architecture builds succeed; browser tests do not block publication. The container job builds an amd64 image when no preview image was built.
|
||||
|
||||
Workshop CI runs only when its workflow or Docker build inputs change. It validates Compose configuration and publishes production images on its configured release branches. Its Docker integration and image tests are manual; workspace typechecks run in the main Fast gate.
|
||||
|
||||
Choose the smallest relevant suite when changing behavior:
|
||||
|
||||
| Command | Scope | Requirements |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------- | --------------------------------------------------------------------- |
|
||||
| `pnpm test <file>` | Focused unit or contract tests | Workspace dependencies |
|
||||
| `pnpm test` | All unit and contract tests, without Docker integration suites | Workspace dependencies |
|
||||
| `pnpm test:coverage` | Unit and contract tests with coverage | Workspace dependencies |
|
||||
| `pnpm test:integration <file>` | Docker-backed service and database compatibility tests | Docker |
|
||||
| `pnpm test:e2e <file>` | Browser and container scenarios | Docker; Playwright Chromium and system dependencies for browser tests |
|
||||
| `pnpm test:docs-screenshots` | Regenerate Assistant documentation screenshots | Same browser prerequisites |
|
||||
| `pnpm test:workshop` / `pnpm test:workshop-image` | Workshop integration / production-image validation | Docker |
|
||||
|
||||
Omit `<file>` to run all tests in that command's scope. E2E and screenshot commands use a local image tagged `homarr-e2e`, or an image selected with `HOMARR_E2E_IMAGE`. The default commands run once without automatic retries; coverage is opt-in. The screenshot generator is excluded from both unit and E2E commands.
|
||||
|
||||
Keep behavioral coverage for authorization, migrations, persistence, and widget execution. Avoid tests that only search source code for particular component names, JSX, CSS, or documentation wording.
|
||||
@@ -1,4 +0,0 @@
|
||||
{
|
||||
"title": "Developer guides",
|
||||
"pages": ["getting-started", "widgets-and-integrations", "kubernetes", "workshop", "workshop-operator"]
|
||||
}
|
||||
@@ -4,13 +4,13 @@ sidebar_position: 4
|
||||
tags:
|
||||
- Workshop
|
||||
- Developer
|
||||
- Fumadocs
|
||||
- Docusaurus
|
||||
- PocketBase
|
||||
---
|
||||
|
||||
# Workshop development
|
||||
|
||||
See the [main development guide](/docs/advanced/development/getting-started) for repository prerequisites.
|
||||
See the [main development guide](./getting-started) for repository prerequisites.
|
||||
|
||||
Start PocketBase:
|
||||
|
||||
@@ -19,7 +19,7 @@ cp apps/workshop/.env.example apps/workshop/.env
|
||||
docker compose --env-file apps/workshop/.env -f apps/workshop/docker-compose.yml up --build workshop
|
||||
```
|
||||
|
||||
Start Fumadocs in another terminal:
|
||||
Start Docusaurus in another terminal:
|
||||
|
||||
```sh
|
||||
WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs
|
||||
|
||||
@@ -139,4 +139,4 @@ The advanced deployments environment variables should only be used if you know w
|
||||
| `DB_MIGRATIONS_DISABLED` | Disable db migrations. For example for helm charts. |
|
||||
|
||||
All public URL variables reject non-HTTP protocols, embedded credentials, query strings, and fragments, and normalize
|
||||
trailing slashes when Homarr or the documentation site starts.
|
||||
trailing slashes when Homarr or Docusaurus starts.
|
||||
@@ -1,60 +0,0 @@
|
||||
---
|
||||
title: Advanced configuration
|
||||
description: Configure deployment, authentication, networking, styling, automation, and development workflows.
|
||||
---
|
||||
|
||||
import {
|
||||
IconCode,
|
||||
IconIcons,
|
||||
IconKey,
|
||||
IconKeyboard,
|
||||
IconNetwork,
|
||||
IconPalette,
|
||||
IconTerminal2,
|
||||
IconUserCog,
|
||||
IconVariable,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
These guides cover changes that affect how Homarr is deployed, secured, operated, or extended.
|
||||
|
||||
## Deploy and secure
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconVariable />} title="Environment variables" href="/docs/advanced/environment-variables">
|
||||
Configure Homarr at deployment time.
|
||||
</Card>
|
||||
<Card icon={<IconKey />} title="Single sign-on" href="/docs/advanced/single-sign-on">
|
||||
Connect an external identity provider.
|
||||
</Card>
|
||||
<Card icon={<IconNetwork />} title="Proxies and certificates" href="/docs/advanced/proxy">
|
||||
Run Homarr behind a reverse proxy.
|
||||
</Card>
|
||||
<Card icon={<IconUserCog />} title="Run as a different user" href="/docs/advanced/running-as-different-user">
|
||||
Change the user and group used by the container.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Customize
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconPalette />} title="Custom styling" href="/docs/advanced/styling">
|
||||
Apply custom CSS to Homarr.
|
||||
</Card>
|
||||
<Card icon={<IconIcons />} title="Icons" href="/docs/advanced/icons">
|
||||
Configure icon sources and behavior.
|
||||
</Card>
|
||||
<Card icon={<IconKeyboard />} title="Keyboard shortcuts" href="/docs/advanced/keyboard-shortcuts">
|
||||
Navigate and operate Homarr with the keyboard.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Develop and automate
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconTerminal2 />} title="Command line interface" href="/docs/advanced/command-line">
|
||||
Use administrative commands from the terminal.
|
||||
</Card>
|
||||
<Card icon={<IconCode />} title="Developer guides" href="/docs/advanced/development/getting-started">
|
||||
Set up a development environment and contribute code.
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -53,20 +53,6 @@ Commands at a grid boundary or at the tile's minimum size are ignored and announ
|
||||
|
||||
On touch screens, press and hold a tile before moving it; a quick tap does not start a drag. Resize handles accept direct touch input. During a pointer or touch move or resize, `Esc` cancels the interaction and restores the layout from before it started.
|
||||
|
||||
## Board editing
|
||||
|
||||
When a tile is focused in edit mode:
|
||||
|
||||
| Shortcut | Description |
|
||||
| -------------------- | --------------------------------------------------------------------------- |
|
||||
| `Enter` or `Space` | Starts or stops keyboard editing |
|
||||
| Arrow keys | Moves the focused tile within its current canvas, rail, or Container |
|
||||
| `Shift` + Arrow keys | Resizes from the tile's lower-right corner: Left/Up shrink; Right/Down grow |
|
||||
| `Esc` | Stops keyboard editing without undoing its changes |
|
||||
|
||||
Keyboard moves and resizes apply immediately. To move an item between a canvas, rail, or Container, drag it there or use **Move / resize item** for precise numeric placement.
|
||||
Commands at a grid boundary or at the tile's minimum size are ignored and announced instead of moving or shrinking the tile.
|
||||
|
||||
:::tip
|
||||
|
||||
Here `MOD` refers to the modifier key, which is `Ctrl` on Windows and `Cmd` on macOS.
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
{
|
||||
"title": "Advanced",
|
||||
"defaultOpen": false,
|
||||
"pages": [
|
||||
"index",
|
||||
"---Deploy and secure---",
|
||||
"environment-variables",
|
||||
"single-sign-on",
|
||||
"proxy",
|
||||
"running-as-different-user",
|
||||
"---Customize---",
|
||||
"styling",
|
||||
"icons",
|
||||
"keyboard-shortcuts",
|
||||
"---Develop and automate---",
|
||||
"command-line",
|
||||
"development"
|
||||
]
|
||||
}
|
||||
@@ -9,14 +9,14 @@ tags:
|
||||
- Security
|
||||
---
|
||||
|
||||
import Tabs from "@/components/mdx/legacy-tabs";
|
||||
import { TabItem } from "@/components/mdx/legacy-tabs";
|
||||
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?]
|
||||
:::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`.
|
||||
|
||||
@@ -10,6 +10,9 @@ tags:
|
||||
- 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.
|
||||
@@ -244,7 +247,7 @@ Homarr supports multiple authentication options, from internal userbase (credent
|
||||
|
||||
Generate `SECRET_ENCRYPTION_KEY` with `openssl rand -hex 32`; do not copy an example key between installs.
|
||||
|
||||
```bash
|
||||
```env
|
||||
OIDC_CLIENT_ID=<REPLACE_WITH_OIDC_CLIENT_ID>
|
||||
OIDC_CLIENT_SECRET=<REPLACE_WITH_OIDC_CLIENT_SECRET>
|
||||
OIDC_SLUG=homarr #Application slug in Authentik
|
||||
@@ -323,7 +326,7 @@ Homarr supports multiple authentication options, from internal userbase (credent
|
||||
|
||||
Generate `SECRET_ENCRYPTION_KEY` with `openssl rand -hex 32`; do not copy an example key between installs.
|
||||
|
||||
```bash
|
||||
```env
|
||||
OIDC_CLIENT_ID=<REPLACE_WITH_GOOGLE_CLIENT_ID>
|
||||
OIDC_CLIENT_SECRET=<REPLACE_WITH_GOOGLE_CLIENT_SECRET>
|
||||
HOMARR_FQDN=homarr.example.com #Homarr FQDN
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"label": "Community",
|
||||
"position": 6,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index"
|
||||
}
|
||||
}
|
||||
@@ -1,31 +1,32 @@
|
||||
---
|
||||
title: Frequently Asked Questions
|
||||
description: Answers to common Homarr questions about installation, customization, connectivity, support, and commercial use.
|
||||
tags:
|
||||
- Community
|
||||
- Help
|
||||
---
|
||||
|
||||
### Can Homarr run on a Raspberry Pi?
|
||||
## Can Homarr run on a Raspberry Pi?
|
||||
|
||||
Yes, when the device uses a supported `linux/arm64` operating system. `linux/arm/v7` is not supported. See
|
||||
[Prerequisites](/docs/getting-started).
|
||||
|
||||
### Can I use custom app icons?
|
||||
## Can I use custom app icons?
|
||||
|
||||
Yes. Use a direct image URL, one of Homarr's icon sources, or upload an image. See [Icons](/docs/advanced/icons).
|
||||
|
||||
### Can I create widgets?
|
||||
## Can I create widgets?
|
||||
|
||||
Yes. [Custom Widgets](/docs/management/custom-widgets) use server-side API requests and safe JSX. They can be written in
|
||||
the workbench or created with an MCP-connected agent.
|
||||
|
||||
### Can Homarr be exposed to the internet?
|
||||
## Can Homarr be exposed to the internet?
|
||||
|
||||
Homarr supports authenticated and public deployments. Terminate HTTPS at a reverse proxy, keep Homarr updated, and grant
|
||||
public board access only when anonymous viewing is intended. See [Board access control](/docs/management/boards#access-control)
|
||||
and [Single sign-on](/docs/advanced/single-sign-on).
|
||||
|
||||
### Where are the logs?
|
||||
## Where are the logs?
|
||||
|
||||
Use **Management → Tools → Logs** for retained and live application logs. Container startup failures and older events are
|
||||
available through the deployment platform, for example `docker container logs homarr`.
|
||||
@@ -33,18 +34,18 @@ available through the deployment platform, for example `docker container logs ho
|
||||
Use the browser developer console only for client-side failures. Review logs before sharing them because URLs and other
|
||||
deployment details may be present.
|
||||
|
||||
### Why can Homarr not reach a service behind Gluetun?
|
||||
## Why can Homarr not reach a service behind Gluetun?
|
||||
|
||||
Gluetun's firewall blocks traffic that is not explicitly allowed. Configure its
|
||||
[`FIREWALL_OUTBOUND_SUBNETS`](https://github.com/qdm12/gluetun-wiki/blob/main/setup/options/firewall.md) for the relevant
|
||||
LAN or Docker subnet, and use an address reachable from the Homarr container.
|
||||
|
||||
### Where do I report a bug or request a feature?
|
||||
## Where do I report a bug or request a feature?
|
||||
|
||||
Use the [GitHub issue templates](https://github.com/homarr-labs/homarr/issues/new/choose). For community support, see
|
||||
[Get in touch](/docs/community/get-in-touch).
|
||||
|
||||
### Can Homarr be used commercially?
|
||||
## Can Homarr be used commercially?
|
||||
|
||||
Yes. Homarr is licensed under the [Apache License 2.0](/docs/community/license). Commercial users can support development
|
||||
through [OpenCollective](/docs/community/donate).
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
title: Community
|
||||
description: Get help, contribute to Homarr, and support the project.
|
||||
---
|
||||
|
||||
- [Frequently asked questions](/docs/community/faq): resolve common setup and operation issues.
|
||||
- [Get in touch](/docs/community/get-in-touch): choose the right support or discussion channel.
|
||||
- [Translations](/docs/community/translations): improve Homarr in your language.
|
||||
- [Donate](/docs/community/donate): support ongoing development.
|
||||
- [License](/docs/community/license): understand how Homarr is licensed.
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"title": "Community",
|
||||
"defaultOpen": false,
|
||||
"pages": ["index", "faq", "get-in-touch", "translations", "donate", "license"]
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Getting started",
|
||||
"position": 1,
|
||||
"collapsed": false,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Getting started"
|
||||
}
|
||||
}
|
||||
@@ -6,68 +6,11 @@ tags:
|
||||
- Configuration
|
||||
---
|
||||
|
||||
import {
|
||||
IconAdjustments,
|
||||
IconChecklist,
|
||||
IconLayoutDashboard,
|
||||
IconPlugConnected,
|
||||
IconSearch,
|
||||
IconSparkles,
|
||||
} from "@tabler/icons-react";
|
||||
On first launch, onboarding creates the administrator, connects optional services, and builds the first board. A
|
||||
compatible SQLite backup can also be restored from the welcome screen.
|
||||
|
||||
import onboardingWelcome from "./img/onboarding-v2-welcome.png";
|
||||
import onboardingBoard from "./img/onboarding-v2-board.png";
|
||||
import onboardingReview from "./img/onboarding-v2-review.png";
|
||||
|
||||
After Homarr starts, open its URL. An unfinished installation redirects to the onboarding screen at `/init`. Choose
|
||||
**Get started** for a new installation or **Restore backup** to import a compatible SQLite backup.
|
||||
|
||||
<Callout type="info" title="Persist /appdata before you continue">
|
||||
Onboarding writes the administrator and board configuration to the database. If onboarding returns after a restart,
|
||||
check that `/appdata` is writable and persisted. See the
|
||||
[Docker installation guide](/docs/getting-started/installation/docker).
|
||||
</Callout>
|
||||
|
||||
## Complete onboarding
|
||||
|
||||
Onboarding is split into six short sections. Integrations, Workshop, Assistant, and MCP are optional; skip them when you
|
||||
only need a working board.
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconAdjustments />} title="1. Essentials">
|
||||
Choose the language, theme, usual server address, and anonymous analytics preference.
|
||||
</Card>
|
||||
<Card icon={<IconSearch />} title="2. Discover">
|
||||
Review the database, Docker, Kubernetes, Assistant, and Workshop capabilities Homarr can reach.
|
||||
</Card>
|
||||
<Card icon={<IconPlugConnected />} title="3. Connect">
|
||||
Import detected services or add integrations manually. Unfinished integrations can be skipped.
|
||||
</Card>
|
||||
<Card icon={<IconLayoutDashboard />} title="4. Board">
|
||||
Set the board name, colors, corner radius, column count, and optional sidebars.
|
||||
</Card>
|
||||
<Card icon={<IconSparkles />} title="5. Extend">
|
||||
Optionally connect the Workshop, configure an Assistant provider, or review the MCP endpoint.
|
||||
</Card>
|
||||
<Card icon={<IconChecklist />} title="6. Review">
|
||||
Check the final summary, then build the board. Homarr opens the exact board it configured.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
The final screen links directly to the new board and the management area. Board layout, integrations, apps, and
|
||||
appearance can all be changed later.
|
||||
|
||||
<Cards>
|
||||
<Card title="Start or restore">
|
||||
<img src={onboardingWelcome.src} alt="Homarr onboarding welcome screen with Get started and Restore backup actions" />
|
||||
</Card>
|
||||
<Card title="Configure the board">
|
||||
<img src={onboardingBoard.src} alt="Board onboarding section for colors, columns, corner radius, and sidebars" />
|
||||
</Card>
|
||||
<Card title="Review before building">
|
||||
<img src={onboardingReview.src} alt="Onboarding review showing the board settings Homarr will create" />
|
||||
</Card>
|
||||
</Cards>
|
||||
If onboarding returns after a restart, check that `/appdata` is writable and persisted. See the
|
||||
[Docker installation guide](/docs/getting-started/installation/docker).
|
||||
|
||||
## Core concepts
|
||||
|
||||
@@ -76,7 +19,7 @@ appearance can all be changed later.
|
||||
A **board** is a dashboard page containing apps, widgets, and Containers. Boards can be public or restricted to users
|
||||
and groups. Each user can choose a home board.
|
||||
|
||||

|
||||

|
||||
|
||||
See [Boards](/docs/management/boards) for responsive layouts, access control, appearance, and home-board settings.
|
||||
|
||||
@@ -85,7 +28,7 @@ See [Boards](/docs/management/boards) for responsive layouts, access control, ap
|
||||
An **app** is a saved shortcut: a name, URL, icon, and optional status check. Add an App tile or a Bookmarks widget to
|
||||
show apps on a board.
|
||||
|
||||

|
||||

|
||||
|
||||
See [Apps](/docs/management/apps) or [Icons](/docs/advanced/icons).
|
||||
|
||||
@@ -94,26 +37,26 @@ See [Apps](/docs/management/apps) or [Icons](/docs/advanced/icons).
|
||||
An **integration** is a server-side connection from Homarr to a supported service such as Sonarr, Home Assistant, or
|
||||
Docker. Integrations provide data and actions to widgets. They can also be linked to apps.
|
||||
|
||||

|
||||

|
||||
|
||||
See [Managing integrations](/docs/management/integrations) and the
|
||||
[integration catalog](/docs/integrations).
|
||||
[integration catalog](/docs/category/integrations).
|
||||
|
||||
### Widgets
|
||||
|
||||
A **widget** is a board tile. Some widgets work on their own; others require one or more integrations. Configuration,
|
||||
supported integrations, and non-obvious limitations are documented on each widget page.
|
||||
|
||||

|
||||

|
||||
|
||||
See the [widget catalog](/docs/widgets).
|
||||
See the [widget catalog](/docs/category/widgets).
|
||||
|
||||
### Containers and rails
|
||||
|
||||
A **Container** groups board items and can be nested. A **rail** reserves a fixed area at the left or right of a
|
||||
responsive layout. Both are configured in board edit mode.
|
||||
|
||||

|
||||

|
||||
|
||||
See [Boards](/docs/management/boards#containers-and-rails).
|
||||
|
||||
@@ -122,7 +65,7 @@ See [Boards](/docs/management/boards#containers-and-rails).
|
||||
Users inherit permissions and default boards from their groups. Resource-specific access can further restrict boards
|
||||
and integrations.
|
||||
|
||||

|
||||

|
||||
|
||||
See [Users and groups](/docs/management/users) and [single sign-on](/docs/advanced/single-sign-on).
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
Before Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
Before Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 38 KiB |
|
Before Width: | Height: | Size: 527 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
Before Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 289 KiB |
|
Before Width: | Height: | Size: 368 KiB |
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Installation",
|
||||
"position": 1,
|
||||
"collapsed": true,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Getting started"
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,10 @@ see [Managing integrations](/docs/management/integrations#configuration).
|
||||
|
||||
### Update
|
||||
|
||||
Update the image and recreate the container with the same configuration. Homarr runs database migrations automatically
|
||||
at startup, including when moving from v1 to v2; no separate upgrade procedure is needed. Keep the `/appdata` mount and
|
||||
`SECRET_ENCRYPTION_KEY` unchanged. Workshop connects to the production service by default.
|
||||
|
||||
```sh
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
|
||||
@@ -1,84 +0,0 @@
|
||||
---
|
||||
title: Install Homarr
|
||||
description: Choose the installation method that matches your infrastructure.
|
||||
full: true
|
||||
---
|
||||
|
||||
import {
|
||||
IconApps,
|
||||
IconBox,
|
||||
IconBrandDocker,
|
||||
IconBrandGithub,
|
||||
IconCloud,
|
||||
IconContainer,
|
||||
IconDatabase,
|
||||
IconHexagons,
|
||||
IconHome,
|
||||
IconLayoutDashboard,
|
||||
IconServer2,
|
||||
IconTrain,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
Docker Compose is the best starting point for most self-hosters. Choose a platform-specific guide when Homarr will run inside an existing server manager or managed service.
|
||||
|
||||
<Callout type="idea" title="Not sure which guide to choose?">
|
||||
Start with **Docker Compose**. It is the recommended path, has the broadest community support, and makes updates and
|
||||
backups straightforward.
|
||||
</Callout>
|
||||
|
||||
## Recommended
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconBrandDocker />} title="Docker Compose" href="/docs/getting-started/installation/docker">
|
||||
The recommended installation for most Linux and Windows servers.
|
||||
</Card>
|
||||
<Card icon={<IconHexagons />} title="Kubernetes with Helm" href="/docs/getting-started/installation/helm">
|
||||
Deploy Homarr into an existing Kubernetes cluster.
|
||||
</Card>
|
||||
<Card icon={<IconBrandGithub />} title="Build from source" href="/docs/getting-started/installation/source">
|
||||
Build and run Homarr directly from the repository.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Self-hosting platforms
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconServer2 />} title="Unraid" href="/docs/getting-started/installation/unraid">
|
||||
Install Homarr from the Unraid Community Apps catalog.
|
||||
</Card>
|
||||
<Card icon={<IconDatabase />} title="Synology" href="/docs/getting-started/installation/synology">
|
||||
Run Homarr on a Synology NAS with Container Manager.
|
||||
</Card>
|
||||
<Card icon={<IconServer2 />} title="Proxmox" href="/docs/getting-started/installation/proxmox">
|
||||
Add Homarr to a Proxmox-based homelab.
|
||||
</Card>
|
||||
<Card icon={<IconHome />} title="Home Assistant Add-on" href="/docs/getting-started/installation/home-assistant">
|
||||
Install Homarr alongside your Home Assistant environment.
|
||||
</Card>
|
||||
<Card icon={<IconContainer />} title="Portainer" href="/docs/getting-started/installation/portainer">
|
||||
Deploy and manage Homarr through Portainer stacks.
|
||||
</Card>
|
||||
<Card icon={<IconDatabase />} title="QNAP" href="/docs/getting-started/installation/qnap">
|
||||
Run Homarr on a QNAP NAS.
|
||||
</Card>
|
||||
<Card icon={<IconApps />} title="Runtipi" href="/docs/getting-started/installation/runtipi">
|
||||
Add Homarr from the Runtipi app store.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Managed and app platforms
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconLayoutDashboard />} title="EasyPanel" href="/docs/getting-started/installation/easy-panel">
|
||||
Deploy Homarr from an Easypanel template.
|
||||
</Card>
|
||||
<Card icon={<IconTrain />} title="Railway" href="/docs/getting-started/installation/railway">
|
||||
Launch Homarr as a managed Railway service.
|
||||
</Card>
|
||||
<Card icon={<IconCloud />} title="PikaPods" href="/docs/getting-started/installation/pika-pods">
|
||||
Use a hosted Homarr instance without managing a server.
|
||||
</Card>
|
||||
<Card icon={<IconBox />} title="Saltbox" href="/docs/getting-started/installation/saltbox">
|
||||
Add Homarr to a Saltbox deployment.
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -1,24 +0,0 @@
|
||||
{
|
||||
"title": "Installation",
|
||||
"defaultOpen": false,
|
||||
"pages": [
|
||||
"index",
|
||||
"---Recommended---",
|
||||
"docker",
|
||||
"helm",
|
||||
"source",
|
||||
"---Self-hosting platforms---",
|
||||
"unraid",
|
||||
"synology",
|
||||
"proxmox",
|
||||
"home-assistant",
|
||||
"portainer",
|
||||
"qnap",
|
||||
"runtipi",
|
||||
"---Managed and app platforms---",
|
||||
"easy-panel",
|
||||
"railway",
|
||||
"pika-pods",
|
||||
"saltbox"
|
||||
]
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
Pika Pods is a hosting platform for open source apps. You can deploy Homarr on Pika Pods with just a few clicks:
|
||||
|
||||
[__](https://www.pikapods.com/pods?run=homarr-v1)
|
||||
[__](https://www.pikapods.com/pods?run=homarr)
|
||||
@@ -21,8 +21,8 @@ This method is only useful, when you want to develop on Homarr or extend it with
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Node.js](https://nodejs.org/en/download/)
|
||||
- [pnpm](https://pnpm.io/installation)
|
||||
- [Node.js](https://nodejs.org/en/download/) 24.18 or newer
|
||||
- [pnpm](https://pnpm.io/installation) at the version pinned in the repository's `package.json`
|
||||
- [Redis](https://redis.io/download)
|
||||
|
||||
## Steps
|
||||
@@ -38,9 +38,9 @@ This method is only useful, when you want to develop on Homarr or extend it with
|
||||
Install all dependencies using <code>pnpm install</code>
|
||||
</li>
|
||||
<li>
|
||||
Copy the `.env.example` file to `.env`. Its `DB_URL='./db.sqlite'` value is ready for local use and stores the
|
||||
database in the cloned repository. Replace it with an absolute writable path such as
|
||||
`DB_URL='/home/username/homarr/db.sqlite'` if you want to store the database elsewhere.
|
||||
Copy `.env.example` to `.env` and set `DB_URL` to an absolute writable path, such as
|
||||
`DB_URL='/home/username/homarr/db.sqlite'`. Migration and application commands run from different workspace
|
||||
directories, so a relative path can point them at different databases.
|
||||
</li>
|
||||
<li>
|
||||
Run `openssl rand -hex 32` twice and set `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` to the two different generated
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import Link from "@/components/mdx/link";
|
||||
import Link from "@docusaurus/Link";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
|
||||
# Unraid
|
||||
@@ -30,7 +30,7 @@ You can install Homarr directly from your Unraid Dashboard, no terminal required
|
||||
|
||||
Don't know whether you have the plugin installed or not? Search for this tab in the navigation:
|
||||
|
||||

|
||||

|
||||
:::
|
||||
|
||||
#### Installing
|
||||
@@ -41,7 +41,7 @@ After you've installed the Community Apps Plugin, you can install Homarr from th
|
||||
2. Search for "Homarr" and click on the result.
|
||||
3. Click on "Install" and adjust the settings to your liking.
|
||||
|
||||

|
||||

|
||||
|
||||
After you've installed Homarr, you can find it under the tab "Docker".
|
||||
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"title": "Getting started",
|
||||
"defaultOpen": false,
|
||||
"pages": ["index", "installation", "after-the-installation", "upgrade-v2", "glossary"]
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
---
|
||||
title: Upgrade from v1 to v2
|
||||
sidebar_position: 2
|
||||
tags:
|
||||
- Getting started
|
||||
- Upgrade
|
||||
- Migration
|
||||
- Backup
|
||||
---
|
||||
|
||||
Homarr v2 upgrades the existing v1 database in place. Keep the same data storage, database configuration, and
|
||||
`SECRET_ENCRYPTION_KEY`; only change the Homarr image or package version for the first start.
|
||||
|
||||
:::danger Back up before starting v2
|
||||
|
||||
In Homarr v1, go to **Management → Tools → Backup**, export a backup, and keep the downloaded file somewhere safe
|
||||
before starting v2. See [Backup and restore](/docs/management/backup) for details.
|
||||
|
||||
:::
|
||||
|
||||
## Upgrade
|
||||
|
||||
1. Pin the Homarr image to `ghcr.io/homarr-labs/homarr:v2.0.0` for the first v2 start.
|
||||
2. Keep the existing `/appdata` mount, database variables, Redis configuration, and `SECRET_ENCRYPTION_KEY` unchanged.
|
||||
3. Start one Homarr replica and follow its logs. Startup must reach `Migration complete`; Homarr aborts startup when a
|
||||
database migration fails.
|
||||
4. Open Homarr and sign in. Confirm **Management → About** reports v2 before starting additional replicas.
|
||||
5. After validation, keep the version pinned or return to your normal stable release policy.
|
||||
|
||||
For Docker Compose, the change is limited to the image tag before the usual update:
|
||||
|
||||
```yaml
|
||||
services:
|
||||
homarr:
|
||||
image: ghcr.io/homarr-labs/homarr:v2.0.0
|
||||
```
|
||||
|
||||
```sh
|
||||
docker compose pull
|
||||
docker compose up -d
|
||||
docker compose logs --follow homarr
|
||||
```
|
||||
|
||||
Do not add `-v` when stopping the Compose deployment; that can remove named volumes.
|
||||
|
||||
## What v2 migrates
|
||||
|
||||
The startup migration:
|
||||
|
||||
- creates the Custom Widget v2, Assistant, header preference, and branding storage;
|
||||
- adds Base/Mobile layout roles and left/right board gutters;
|
||||
- converts legacy Categories and dynamic sections into Containers and rails;
|
||||
- preserves legacy Custom Widget definitions, encrypted secrets, and board references for explicit migration.
|
||||
|
||||
Legacy Custom Widgets are not silently rewritten. In **Management → Custom Widgets**, entries marked
|
||||
**Migration required** provide a credential-free migration prompt. Review and test the resulting v2 definition before
|
||||
removing the archived v1 version. See [Custom Widgets: Import and Workshop](/docs/management/custom-widgets#import-and-workshop).
|
||||
|
||||
## Verify the upgraded instance
|
||||
|
||||
- Sign in with each enabled authentication method and verify administrator access.
|
||||
- Open every important board on desktop and mobile. Check Containers, former Categories, rails, item placement, and
|
||||
home-board assignments.
|
||||
- Test at least one read and one permitted action for each critical integration. Recheck integration and board access
|
||||
for representative Viewer, Editor, and Admin groups.
|
||||
- Check Docker or Podman endpoints, search engines, uploaded media, trusted certificates, scheduled tasks, WebSockets,
|
||||
and external Redis when used.
|
||||
- Review every legacy Custom Widget and migrate it only after its v2 preview and requests work.
|
||||
- Restart Homarr once more and confirm the logs contain no migration, database, Redis, authentication, or task errors.
|
||||
|
||||
## Roll back
|
||||
|
||||
Use the backup exported before the upgrade if you need to restore your v1 installation. Do not reuse a database that
|
||||
v2 has already migrated with v1.
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
title: Homarr documentation
|
||||
description: Install, configure, operate, and extend Homarr.
|
||||
---
|
||||
|
||||
import {
|
||||
IconApi,
|
||||
IconArrowUp,
|
||||
IconBuildingStore,
|
||||
IconChecklist,
|
||||
IconCode,
|
||||
IconComponents,
|
||||
IconDownload,
|
||||
IconLayoutDashboard,
|
||||
IconPlugConnected,
|
||||
IconSettings,
|
||||
IconUsers,
|
||||
IconVocabulary,
|
||||
} from "@tabler/icons-react";
|
||||
|
||||
Use these guides to get Homarr running, connect your services, build useful boards, and manage an installation over time.
|
||||
|
||||
## Install or upgrade
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconDownload />} title="Install Homarr" href="/docs/getting-started/installation">
|
||||
Choose the installation method for your system.
|
||||
</Card>
|
||||
<Card icon={<IconArrowUp />} title="Upgrade from v1" href="/docs/getting-started/upgrade-v2">
|
||||
Move an existing Homarr installation to v2.
|
||||
</Card>
|
||||
<Card icon={<IconChecklist />} title="Finish setup" href="/docs/getting-started/after-the-installation">
|
||||
Add apps, integrations, and widgets after installation.
|
||||
</Card>
|
||||
<Card icon={<IconVocabulary />} title="Learn the concepts" href="/docs/getting-started">
|
||||
Understand boards, apps, integrations, and widgets.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Configure Homarr
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconLayoutDashboard />} title="Boards and content" href="/docs/management">
|
||||
Configure boards, apps, users, settings, and administration.
|
||||
</Card>
|
||||
<Card icon={<IconPlugConnected />} title="Connect services" href="/docs/integrations">
|
||||
Find the setup guide for an integration.
|
||||
</Card>
|
||||
<Card icon={<IconComponents />} title="Choose widgets" href="/docs/widgets">
|
||||
Find the content and controls available for boards.
|
||||
</Card>
|
||||
<Card icon={<IconSettings />} title="Advanced configuration" href="/docs/advanced">
|
||||
Configure deployment, authentication, networking, and automation.
|
||||
</Card>
|
||||
</Cards>
|
||||
|
||||
## Extend and contribute
|
||||
|
||||
<Cards>
|
||||
<Card icon={<IconCode />} title="Custom Widgets" href="/docs/management/custom-widgets">
|
||||
Author and publish Custom JSX widgets.
|
||||
</Card>
|
||||
<Card icon={<IconBuildingStore />} title="Community Workshop" href="/docs/workshop">
|
||||
Use and operate the community extension registry.
|
||||
</Card>
|
||||
<Card icon={<IconApi />} title="API reference" href="/api-reference">
|
||||
Inspect Homarr's HTTP API.
|
||||
</Card>
|
||||
<Card icon={<IconUsers />} title="Get help and contribute" href="/docs/community">
|
||||
Find support and ways to contribute.
|
||||
</Card>
|
||||
</Cards>
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"label": "Integrations",
|
||||
"collapsed": true,
|
||||
"position": 3,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Integrations",
|
||||
"description": "Connect Homarr to supported services so widgets can display data and run actions. Choose an integration to see its setup requirements and compatible widgets."
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,7 @@ import { coolifyWidget } from "../../widgets/coolify";
|
||||
|
||||
<AddingIntegration />
|
||||
|
||||
:::info[URL configuration]
|
||||
:::info URL configuration
|
||||
Use the root URL of your Coolify instance, for example `https://coolify.example.com`. Homarr calls Coolify endpoints under `/api` and `/api/v1` automatically.
|
||||
:::
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import { IntegrationCapabilites } from "@site/src/components/integrations/widget
|
||||
import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { delugeIntegration } from ".";
|
||||
import { downloadsWidget } from "@site/docs/widgets/downloads";
|
||||
|
||||
|
||||
@@ -117,7 +117,7 @@ updating a Homarr resource still requires confirmation. If one endpoint is unava
|
||||
endpoints remain visible.
|
||||
|
||||
The `homarr.hide` label excludes a container. Other `homarr.*` labels can provide apps, integrations, groups, and widgets
|
||||
during onboarding; see [Docker label discovery](/docs/integrations/docker-labels).
|
||||
during onboarding; see [Docker label discovery](../docker-labels).
|
||||
|
||||
## Security
|
||||
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
---
|
||||
title: Integrations
|
||||
description: Connect Homarr to the applications and infrastructure you operate.
|
||||
---
|
||||
|
||||
import { DocsDirectory } from "@/components/docs/docs-directory";
|
||||
|
||||
An integration stores the connection and authentication details Homarr needs to communicate with another service. Widgets and management tools can then reuse that connection.
|
||||
|
||||
Each guide identifies the required URL and credentials, supported capabilities, and the widgets that use the integration.
|
||||
|
||||
<DocsDirectory section="integrations" />
|
||||
|
||||
## Before you connect a service
|
||||
|
||||
1. Confirm that Homarr can reach the service from its own network.
|
||||
2. Create the least-privileged account, token, or API key supported by the service.
|
||||
3. Add the integration in **Manage → Integrations**.
|
||||
4. Test the connection before adding dependent widgets.
|
||||
|
||||
See [Manage integrations](/docs/management/integrations) for the shared workflow.
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
title: "llama.cpp"
|
||||
description: "Connect Homarr to a llama.cpp llama-server to monitor your local LLM: health, loaded model, generation speed and request status."
|
||||
hide_title: true
|
||||
---
|
||||
|
||||
import { IntegrationHeader } from "@site/src/components/integrations/header";
|
||||
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
|
||||
import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { llamacppIntegration } from ".";
|
||||
import { llamacppWidget } from "@site/docs/widgets/llama-cpp";
|
||||
|
||||
<IntegrationHeader integration={llamacppIntegration} categories={["System Monitoring"]} />
|
||||
|
||||
The llama.cpp integration lets Homarr connect to a [llama-server](https://github.com/ggml-org/llama.cpp) instance so you can see the health of your local LLM, which model is loaded, and how fast it is generating — all from your dashboard.
|
||||
|
||||
### Widgets & Capabilities
|
||||
|
||||
<IntegrationCapabilites items={[{ widget: llamacppWidget }]} />
|
||||
|
||||
### Adding the integration
|
||||
|
||||
<AddingIntegration />
|
||||
|
||||
:::info URL configuration
|
||||
Use the root URL of your `llama-server`, for example `http://192.168.1.50:8080`. Homarr calls the `/health`, `/v1/models`, `/metrics` and `/slots` endpoints under that URL automatically.
|
||||
:::
|
||||
|
||||
:::tip Metrics
|
||||
Generation speed and token counters are read from the Prometheus endpoint at `/metrics`. Start `llama-server` with the `--metrics` flag so these values are available:
|
||||
|
||||
```shell
|
||||
llama-server --model /path/to/model.gguf --metrics
|
||||
```
|
||||
|
||||
Without `--metrics` the widget still shows health, model information, and active-request speed from `/slots`; metrics-backed counters and aggregate speed stay empty.
|
||||
:::
|
||||
|
||||
:::info Context and per-request speed
|
||||
Context (KV cache) usage and the in-flight request data are read from the `/slots` endpoint, which is available on every recent llama-server build and requires no extra flags. The per-request generation speed shown while a request is running is derived by tracking the request's decoded token count across polls, so it reflects the average speed of the request that is currently being generated.
|
||||
:::
|
||||
|
||||
### Secrets
|
||||
|
||||
llama-server does not require authentication by default. The integration only needs the URL of your server.
|
||||
|
||||
<IntegrationSecrets
|
||||
secrets={[
|
||||
{
|
||||
credentials: [],
|
||||
steps: [],
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@@ -0,0 +1,9 @@
|
||||
import { IntegrationDefinition } from "@site/src/types";
|
||||
|
||||
export const llamacppIntegration: IntegrationDefinition = {
|
||||
name: "llama.cpp",
|
||||
description:
|
||||
"Connect to a local llama.cpp llama-server to show model, throughput and request status on your dashboard.",
|
||||
iconUrl: "https://cdn.jsdelivr.net/gh/selfhst/icons/svg/llama-cpp.svg",
|
||||
path: "../../integrations/llama-cpp",
|
||||
};
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"title": "Integrations",
|
||||
"defaultOpen": false,
|
||||
"pages": ["index", "..."]
|
||||
}
|
||||
@@ -9,7 +9,7 @@ import { IntegrationCapabilites } from "@site/src/components/integrations/widget
|
||||
import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconCalendar } from "@tabler/icons-react";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { nextcloudIntegration } from ".";
|
||||
import { calendarWidget } from "@site/docs/widgets/calendar";
|
||||
import { notificationsWidget } from "@site/docs/widgets/notifications";
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
import { nzbgetIntegration } from ".";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { downloadsWidget } from "@site/docs/widgets/downloads";
|
||||
|
||||
<IntegrationHeader integration={nzbgetIntegration} categories={["Usenet client"]} />
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconHeartRateMonitor } from "@tabler/icons-react";
|
||||
import { openMediaVaultIntegration } from ".";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
|
||||
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ import { IntegrationHeader } from "@site/src/components/integrations/header";
|
||||
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
|
||||
import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { dnsHoleSummaryWidget } from "@site/docs/widgets/dns-hole-summary";
|
||||
import { dnsHoleControlsWidget } from "@site/docs/widgets/dns-hole-controls";
|
||||
import { piHoleIntegration } from ".";
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
import { qBittorentIntegration } from ".";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { downloadsWidget } from "@site/docs/widgets/downloads";
|
||||
|
||||
<IntegrationHeader integration={qBittorentIntegration} categories={["Torrent client"]} />
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
import { sabnzbdIntegration } from ".";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { downloadsWidget } from "@site/docs/widgets/downloads";
|
||||
|
||||
<IntegrationHeader integration={sabnzbdIntegration} categories={["Usenet client"]} />
|
||||
|
||||
@@ -12,7 +12,7 @@ import { synologyIntegration } from ".";
|
||||
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
|
||||
import { systemDisksWidget } from "@site/docs/widgets/system-disks";
|
||||
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
|
||||
<IntegrationHeader integration={synologyIntegration} categories={["NAS", "Hardware"]} />
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ import { IntegrationHeader } from "@site/src/components/integrations/header";
|
||||
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
|
||||
import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { technitiumDnsIntegration } from ".";
|
||||
import { dnsHoleSummaryWidget } from "@site/docs/widgets/dns-hole-summary";
|
||||
import { dnsHoleControlsWidget } from "@site/docs/widgets/dns-hole-controls";
|
||||
|
||||
@@ -21,11 +21,11 @@ import { traefikWidget } from "../../widgets/traefik";
|
||||
|
||||
<AddingIntegration />
|
||||
|
||||
:::info[URL configuration]
|
||||
:::info URL configuration
|
||||
Use the URL where Traefik exposes its dashboard/API, for example `http://traefik:8080` or `https://traefik.example.com`. Homarr calls Traefik endpoints under `/api` automatically.
|
||||
:::
|
||||
|
||||
:::warning[API requirement]
|
||||
:::warning API requirement
|
||||
Traefik must have the API enabled. For local or internal setups this is commonly exposed through `api.insecure=true`; for production setups, expose the `api@internal` service through an authenticated router.
|
||||
:::
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { AddingIntegration } from "@site/src/components/integrations/adding";
|
||||
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { IconDownload } from "@tabler/icons-react";
|
||||
import { transmissionIntegration } from ".";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
import { downloadsWidget } from "@site/docs/widgets/downloads";
|
||||
|
||||
<IntegrationHeader integration={transmissionIntegration} categories={["Torrent client"]} />
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
|
||||
import { truenasIntegration } from ".";
|
||||
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
|
||||
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
|
||||
import Alert from "@/components/mdx/admonition";
|
||||
import Alert from "@theme/Admonition";
|
||||
|
||||
<IntegrationHeader integration={truenasIntegration} categories={["NAS", "Hardware"]} />
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { umamiWidget } from "../../widgets/umami";
|
||||
|
||||
<AddingIntegration />
|
||||
|
||||
:::tip[URL configuration]
|
||||
:::tip URL configuration
|
||||
|
||||
- **Umami Cloud:** Use `https://api.umami.is/v1`
|
||||
- **Self-hosted:** Use `http://your-umami-host:3000/api`
|
||||
|
||||
@@ -23,13 +23,15 @@ The What's Up Docker integration lets Homarr connect to your [WUD](https://githu
|
||||
|
||||
<AddingIntegration />
|
||||
|
||||
:::info[URL configuration]
|
||||
Use the root URL of your WUD instance, for example `https://wud.example.com`. Homarr calls the `/api/app` and `/api/containers` endpoints under that URL automatically.
|
||||
:::info URL configuration
|
||||
Use the root URL of your WUD instance, for example `https://wud.example.com`. Homarr uses `/api/containers` under that URL for both connection testing and widget data.
|
||||
:::
|
||||
|
||||
### Secrets
|
||||
|
||||
WUD does not require authentication by default. If your instance is protected with [Basic Authentication](https://github.com/getwud/wud/blob/main/docs/configuration/authentications/basic/README.md), you can provide a username and password.
|
||||
WUD 9 requires authentication. Enter your WUD username and password in Homarr; the initial admin credentials configured with `WUD_AUTH_ADMIN_USER` and `WUD_AUTH_ADMIN_PASSWORD` work with Basic authentication. Older WUD versions without authentication can leave both fields empty.
|
||||
|
||||
Credentials are sent to the configured URL over HTTP or HTTPS. Use HTTPS outside a trusted internal network.
|
||||
|
||||
<IntegrationSecrets
|
||||
secrets={[
|
||||
@@ -40,7 +42,7 @@ WUD does not require authentication by default. If your instance is protected wi
|
||||
{
|
||||
credentials: ["username", "password"],
|
||||
steps: [
|
||||
"Open your WUD instance's configuration and configure a WUD_AUTH_BASIC_* user as described in the WUD documentation",
|
||||
"Use your WUD account credentials; older versions can use a configured WUD_AUTH_BASIC_* user",
|
||||
"Enter that username and password in Homarr — Basic authentication is handled automatically",
|
||||
],
|
||||
},
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"label": "Management",
|
||||
"collapsed": true,
|
||||
"position": 2,
|
||||
"link": {
|
||||
"type": "generated-index",
|
||||
"title": "Management pages"
|
||||
}
|
||||
}
|
||||