chore: reconcile v2 after stack rebase

This commit is contained in:
ajnart committed 2026-08-13 19:59:46 +02:00
1 parent 5dc4dbeaef
commit 0482c040ec
215 files changed
+12297 -17452

No files matched your search

-19
View File
@@ -1,19 +0,0 @@
# Workshop deployment with ACT
The Workshop workflow builds the same image used on the VPS and smoke-tests both Docusaurus and PocketBase. Registry login and pushes are skipped under ACT.
From the repository root:
```sh
pnpm ci:act:workshop
```
The wrapper selects `.github/workflows/deployment-workshop.yml`, derives the active Docker socket (including Docker Desktop and OrbStack contexts), and runs only the `deploy` job using a `workflow_dispatch` event.
To inspect the workflow without running it:
```sh
act workflow_dispatch --list --workflows .github/workflows/deployment-workshop.yml
```
No GitHub or registry secrets are required for the local run.
+4 -2
View File
@@ -34,8 +34,10 @@ permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number || inputs.pr_number || github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
# Every event for a PR shares one group so a close event cancels stale image
# publication and a newer synchronize run cannot be overwritten by an older run.
group: ${{ github.workflow }}-${{ github.event.pull_request.number || inputs.pr_number || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' || github.event_name == 'pull_request_target' || github.event_name == 'workflow_dispatch' || github.ref != 'refs/heads/main' }}
env:
FORCE_COLOR: 3
+56
View File
@@ -0,0 +1,56 @@
name: "[Deployment] Documentation"
on:
push:
branches: ["dev"]
paths:
- "apps/docs/**"
- "packages/definitions/src/docs/**"
- ".github/workflows/deployment-docs.yml"
workflow_dispatch:
permissions:
contents: read
pages: write
id-token: write
concurrency:
group: "pages"
cancel-in-progress: false
env:
SKIP_ENV_VALIDATION: true
TURBO_API: ${{ secrets.TURBO_API }}
TURBO_TEAM: ${{ secrets.TURBO_TEAM }}
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
TURBO_REMOTE_CACHE_SIGNATURE_KEY: ${{ secrets.TURBO_REMOTE_CACHE_SIGNATURE_KEY }}
jobs:
build:
runs-on: ubuntu-latest
timeout-minutes: 10
steps:
- uses: actions/checkout@v7
- name: Setup
uses: ./tooling/github/setup
- name: Build docs
run: pnpm turbo build --filter=@homarr/docs
env:
CI: "true"
- name: Setup Pages
uses: actions/configure-pages@v6
- name: Upload pages artifact
uses: actions/upload-pages-artifact@v5
with:
path: "apps/docs/build"
deploy:
runs-on: ubuntu-latest
needs: build
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v5
-47
View File
@@ -1,47 +0,0 @@
name: "[Deployment] Workshop"
on:
push:
branches: ["dev"]
paths:
- "apps/docs/**"
- "apps/workshop/**"
workflow_dispatch:
permissions:
contents: read
packages: write
concurrency:
group: workshop-deployment
cancel-in-progress: true
jobs:
deploy:
name: Build, test, and publish
runs-on: ubuntu-latest
timeout-minutes: 25
env:
LOCAL_IMAGE: homarr/workshop:ci
REGISTRY_IMAGE: ghcr.io/homarr-labs/workshop
steps:
- name: Check out repository
uses: actions/checkout@v7
- name: Build combined Workshop image
run: docker build --file apps/workshop/Dockerfile --tag "$LOCAL_IMAGE" .
- name: Smoke-test static docs and PocketBase
run: bash apps/workshop/scripts/smoke-test.sh "$LOCAL_IMAGE"
- name: Log in to GitHub Container Registry
if: ${{ env.ACT != 'true' }}
run: echo "${{ github.token }}" | docker login ghcr.io --username "${{ github.actor }}" --password-stdin
- name: Publish immutable and latest tags
if: ${{ env.ACT != 'true' }}
run: |
docker tag "$LOCAL_IMAGE" "$REGISTRY_IMAGE:sha-${GITHUB_SHA}"
docker tag "$LOCAL_IMAGE" "$REGISTRY_IMAGE:latest"
docker push "$REGISTRY_IMAGE:sha-${GITHUB_SHA}"
docker push "$REGISTRY_IMAGE:latest"
-2
View File
@@ -90,5 +90,3 @@ When modifying user-facing code, you MUST also update the corresponding document
- Run `pnpm dev:cli -- build <name>` from a Homarr checkout to build `homarr:<name>` with rebuild provenance.
- Run `pnpm dev:cli -- build --pr <number>` to build a PR locally from a temporary checkout.
- Run Go checks from `tools/homarr-dev` with `go test ./...` and `go vet ./...`.
- Use `dayjs` for date/time formatting or comparisons; do not hand-roll relative time or date math.
- Extract shared helpers/components when the same logic appears in multiple workshop/store files.
+2 -9
View File
@@ -1,10 +1,3 @@
{
"cSpell.words": [
"Homarr",
"Lidarr",
"Nextcloud",
"Radarr",
"Readarr",
"Sonarr"
]
}
"cSpell.words": ["Homarr", "Lidarr", "Nextcloud", "Radarr", "Readarr", "Sonarr"]
}
+16 -10
View File
@@ -21,8 +21,14 @@ pnpm dev:docs
# Or from within this directory
pnpm dev
# Point the docs at a local PocketBase instance
WORKSHOP_API_URL=http://127.0.0.1:8090 pnpm dev:docs
```
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
@@ -40,7 +46,7 @@ Uses oxlint and oxfmt (same as the rest of the monorepo):
```bash
pnpm lint # oxlint
pnpm format # oxfmt (check)
pnpm format -- --write # oxfmt (fix)
pnpm format:fix # oxfmt (fix)
```
## Typecheck
@@ -71,7 +77,7 @@ Each integration/widget doc follows a consistent pattern:
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';
import { IntegrationKind } from "@homarr/definitions";
```
This enables type-safe references to homarr domain concepts within documentation code.
@@ -90,15 +96,15 @@ pnpm verify:search
## Tech Stack
| Layer | Technology |
|---|---|
| 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 |
| Styling | Tailwind CSS 4 + Docusaurus Infima |
| Icons | `@tabler/icons-react` |
| Diagrams | Mermaid (`@docusaurus/theme-mermaid`) |
| Search | Algolia DocSearch |
| Analytics | PostHog |
| Charts | @nivo/line |
## Contributing
@@ -1,4 +1,4 @@
{
"collapsed": true,
"label": "Command line interface"
}
}
@@ -14,4 +14,4 @@ homarr fix-usernames
This will convert all credential usernames to lowercase and update the database accordingly.
![](./img/screenshot-cli.png)
![](./img/screenshot-cli.png)
@@ -1,7 +1,7 @@
# Command line interface
The Homarr image ships with a built-in recovery tool. This can be useful, if you do not have access to Homarr or if something is not working.
Please note that the CLI is an *emergency tool*, not an API tool.
Please note that the CLI is an _emergency tool_, not an API tool.
:::caution
@@ -12,10 +12,10 @@ You should also create a backup of the database, in case you break something.
## Execute CLI with Docker
1. Execute ``docker ps | grep homarr`` on the root system with Docker to find the container ID of your Homarr container.
2. Run ``docker exec -it <container-id> /bin/bash homarr <your-command-goes-here>``. \
Replace ``<container-id>`` with your container ID from step 1. \
Replace ``<your-command-goes-here>`` with the command you want to execute (see sub-pages).
1. Execute `docker ps | grep homarr` on the root system with Docker to find the container ID of your Homarr container.
2. Run `docker exec -it <container-id> /bin/bash homarr <your-command-goes-here>`. \
Replace `<container-id>` with your container ID from step 1. \
Replace `<your-command-goes-here>` with the command you want to execute (see sub-pages).
## Execute CLI with QNAP
@@ -7,6 +7,7 @@ This guide requires that you understand [how to access the CLI](../).
:::
Using these commands, you can manage the integrations from the CLI:
```bash
Group of commands to manage integrations
@@ -43,7 +44,7 @@ Flags:
## Delete Integration
- Requires a database connection
- Requires one parameter: ``id`` or ``name``
- Requires one parameter: `id` or `name`
- Deletes an integration permanently from the database
```bash
@@ -57,4 +58,4 @@ Flags:
-n, --name string Name of the integration
-h, --help help for integrations delete
-v, --version version for homarr-cli
```
```
@@ -12,8 +12,8 @@ All sessions for that user will be terminated and the user must re-login.
![](./img/screenshot-cli.png)
Using the ``--username`` parameter, you can specify who you want to reset the password for.
Using the `--username` parameter, you can specify who you want to reset the password for.
Executing the command will create a new random password, update the database and display the new password.
All sessions for this user will be terminated and they must re-login.
![](./img/screenshot-cli-result.png)
![](./img/screenshot-cli-result.png)
@@ -7,6 +7,7 @@ This guide requires that you understand [how to access the CLI](../).
:::
Using these commands, you can manage the users from the CLI:
```bash
Group of commands to manage users
@@ -42,7 +43,7 @@ yj52ek5cyb6du4bp4osbkjry admin xxxx@example.com
## Delete User
- Requires a database connection
- Requires one parameter: ``id`` or ``username``
- Requires one parameter: `id` or `username`
```bash
Delete a user by id or username
@@ -76,4 +77,4 @@ Flags:
-p, --password New password
-h, --help help for users update-password
-v, --version version for homarr-cli
```
```
@@ -1,9 +1,8 @@
{
"label": "Developer guides",
"position": 6,
"collapsed": true,
"link": {
"type": "generated-index"
}
"label": "Developer guides",
"position": 6,
"collapsed": true,
"link": {
"type": "generated-index"
}
}
@@ -12,12 +12,12 @@ sidebar_position: 1
### Prerequisites
- Node.js 24.18 or newer
- Corepack (the root `package.json` selects the supported pnpm version)
- Git
- Docker with Docker Compose
- Go 1.25+ for the developer Docker CLI
- GitHub CLI for pull-request image features
- **Node.js 24.18 or newer**: You can download it from the [official website](https://nodejs.org/).
- **Corepack**: Run `corepack enable` so the repository selects its pinned pnpm 11 version.
- **Git**: You can download it from the [official website](https://git-scm.com/).
- **Docker or Docker Desktop**: Required for the Redis service and the developer Docker CLI.
- **Go 1.25+**: Required only for the developer Docker CLI. You can download it from the [official website](https://go.dev/).
- **GitHub CLI**: Required only for pull-request image features. Install it from the [official website](https://cli.github.com/), then authenticate with `gh auth login`.
The versions in the root `package.json` are the supported baseline. Let Corepack select the repository version instead
of installing an unrelated global pnpm:
@@ -54,6 +54,8 @@ pnpm dev
The infrastructure command remains in the foreground. Open `http://127.0.0.1:3000`; the first user created through
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.
### Run PocketBase and documentation
@@ -103,17 +105,18 @@ pnpm dev:docs
### Useful commands
- `pnpm dev` — Next.js on port 3000.
- `pnpm dev:benchmark` — run the authenticated-board development benchmark.
- `pnpm dev:cli -- dev` — browse local images and remote pull-request images.
- `pnpm dev:benchmark` — authenticated-board benchmark; readiness-only `--smoke` runs are not performance claims.
- `pnpm dev:cli -- dev` — browse and run local images and remote pull-request images.
- `pnpm dev:cli -- build <name>` — build the current checkout as `homarr:<name>`.
- `pnpm dev:cli -- build --pr <number>` — build a pull request from a temporary checkout.
- `pnpm dev:cli:install` — install the developer CLI as a `homarr` binary.
- `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` — Docusaurus only on port 3003.
- `pnpm docker:dev:up` — start Redis in the background.
- `pnpm docker:workshop` — local PocketBase through Docker Compose.
- `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.
- `pnpm db:seed` — seed the default database data.
- `pnpm db:seed` — seed the default database data explicitly.
- `pnpm db:studio` — inspect the database.
- `pnpm format` / `pnpm format:fix` — check or apply oxfmt.
- `pnpm lint` / `pnpm lint:fix` — check or apply oxlint.
@@ -121,3 +124,5 @@ pnpm dev:docs
- `pnpm test` — unit and contract suites.
- `pnpm test:workshop` — disposable Workshop integration suite.
- `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.
@@ -132,4 +132,4 @@ This command should return CPU and memory usage statistics for each node.
## Conclusion
You have successfully set up a multi-node Kubernetes cluster using kind and installed the Metrics Server for monitoring resource usage. This setup is useful for local development and testing Kubernetes workloads before deploying them to a production environment.
You have successfully set up a multi-node Kubernetes cluster using kind and installed the Metrics Server for monitoring resource usage. This setup is useful for local development and testing Kubernetes workloads before deploying them to a production environment.
@@ -6,11 +6,11 @@ tags:
Homarr has the following keyboard shortcuts:
| Shortcut | Description |
| -------- | ----------- |
| Shortcut | Description |
| ----------- | -------------------- |
| `MOD` + `K` | Opens the search bar |
| `MOD` + `J` | Toggles Dark Mode |
| `MOD` + `E` | Toggles Edit Mode |
| `MOD` + `J` | Toggles Dark Mode |
| `MOD` + `E` | Toggles Edit Mode |
:::tip
+12 -8
View File
@@ -9,16 +9,17 @@ tags:
- Security
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
## Allowing self-signed certificates
Some users may come across a barrier, where they're unable to receive a 200 response from the Ping widget for some apps, while using self-signed certificates or a local certificate authory.
:::note What's going on?
Homarr is trying to communicate to your apps via the integrations.
It usually doesn't matter if Homarr is running on ``http`` or ``https``.
It usually doesn't matter if Homarr is running on `http` or `https`.
Your apps have a self-signed certificate - Homarr will recognize that the certificate was signed by an unknown authority and requests will be blocked.
:::
@@ -28,8 +29,9 @@ To allow self-signed certificates, you can configure them on the certificates ma
## Securing Homarr with Traefik
Copying the configuration straight from the docker-compose file won't work if you are running Homarr behind Traefik, such as a Portainer setup, or docker-swarm. In that case, you should use the following slightly modified configuration:
```yaml
version: '3'
version: "3"
services:
homarr:
container_name: homarr
@@ -53,11 +55,12 @@ networks:
external: true
```
<br/>
<br />
A sample Traefik docker-compose.yml using Cloudflare for certificate generation that works with the configuration above would be:
```yaml
version: '3'
version: "3"
apps:
traefik:
@@ -103,7 +106,6 @@ networks:
external: true
```
:::tip
Of particular note here is that both configurations explicitly define which network they are using, in this case "proxy", but it can be named anything. It just has to be the same across all apps for which Traefik is serving as a proxy. These are marked as external because the proxy network was manually created by running: `docker network create proxy` but this might be unnecessary depending on HOW exactly you are running Traefik. For example, if running [Traefik with Portainer](https://docs.portainer.io/advanced/reverse-proxy/traefik#deploying-in-a-docker-standalone-scenario), you can follow their official docs on how to set up Traefik and Portainer together, and you can just focus on the Homarr docker labels instead.
:::
@@ -114,7 +116,6 @@ If you are using Caddy as the reverse proxy for your setup, your `docker-compose
```yaml
services:
# <-- [Homarr installation]
caddy:
@@ -140,14 +141,17 @@ networks:
proxy:
external: true
```
:::important
Homarr needs to be on the same network so you will need to add the following property to your homarr install:
```yaml
homarr:
...
networks:
- proxy
```
:::
Next, create a file named `Caddyfile` at the same level as your `docker-compose.yml` file with the following content:
@@ -8,7 +8,7 @@ tags:
- PUID
---
By default the container is running with user `root` and group `root`.
By default the container is running with user `root` and group `root`.
You can change the user and group by using the `PUID` and `PGID` environment variables.
Important to note is, that you'll also need to change the permissions for the mounted directories accordingly.
@@ -32,11 +32,11 @@ services:
volumes:
- ./homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=1000
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=1000
ports:
- '7575:7575'
- "7575:7575"
```
After that you'll need to create the appdata directory and set the correct permissions:
@@ -76,11 +76,11 @@ services:
- /var/run/docker.sock:/var/run/docker.sock
- ./homarr/appdata:/appdata
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=999
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
- PUID=1000
- PGID=999
ports:
- '7575:7575'
- "7575:7575"
```
And set the permissions for the mounted directories:
@@ -90,4 +90,4 @@ mkdir -p ./homarr/appdata
chown -R 1000:999 ./homarr/appdata
```
Important here is that the group ID is set to `999` as we created the `docker` group with this ID.
Important here is that the group ID is set to `999` as we created the `docker` group with this ID.
@@ -10,20 +10,21 @@ tags:
- Active Directory
---
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
# Single Sign On
Homarr supports multiple authentication options, from internal userbase (credentials), to LDAP (with Active directory support), and OIDC.
### Auth configuration common variables
| Environment Variable | Description | Default Value |
|---------------------------|-------------|---------------|
| AUTH_PROVIDERS | Select Which provider to use between *credentials*, *ldap* and *oidc*. <br /> Multiple providers can be enabled with by separating them with `,`, (ex. `AUTH_PROVIDERS=credentials,oidc`, it is highly recommended to just enable one provider). | credentials |
| AUTH_LOGOUT_REDIRECT_URL | URL to redirect to after clicking logging out. | --- |
| AUTH_SESSION_EXPIRY_TIME | Time for the session to time out. Can be set as pure number, which will automatically be used in seconds, or followed by s, m, h or d for seconds, minutes, hours or days. (ex: "30m") | "30d" |
| AUTH_COOKIE_PREFIX | Prefix used for all authentication cookies (session, csrf, callback, pkce, state, nonce). Change this if you run another Auth.js/NextAuth app on the same hostname as Homarr (browsers scope cookies by host, not by port) to avoid cookie name collisions. Only letters, numbers, hyphens and underscores are allowed. | `homarr` |
| Environment Variable | Description | Default Value |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| AUTH_PROVIDERS | Select Which provider to use between _credentials_, _ldap_ and _oidc_. <br /> Multiple providers can be enabled with by separating them with `,`, (ex. `AUTH_PROVIDERS=credentials,oidc`, it is highly recommended to just enable one provider). | credentials |
| AUTH_LOGOUT_REDIRECT_URL | URL to redirect to after clicking logging out. | --- |
| AUTH_SESSION_EXPIRY_TIME | Time for the session to time out. Can be set as pure number, which will automatically be used in seconds, or followed by s, m, h or d for seconds, minutes, hours or days. (ex: "30m") | "30d" |
| AUTH_COOKIE_PREFIX | Prefix used for all authentication cookies (session, csrf, callback, pkce, state, nonce). Change this if you run another Auth.js/NextAuth app on the same hostname as Homarr (browsers scope cookies by host, not by port) to avoid cookie name collisions. Only letters, numbers, hyphens and underscores are allowed. | `homarr` |
<Tabs>
<TabItem value="credentials" label="Credentials Provider" default>
+19 -11
View File
@@ -19,12 +19,14 @@ Homarr uses https://mantine.dev/ under the hood. You can change the look & feel
using custom CSS, that extends or overwrites the styles from Mantine.
## Getting into CSS
If you don't have any experience with CSS,
we strongly recommend you to go through the courses here: https://www.w3schools.com/css/.
Due to the infinite scenarios and setups possible with custom CSS,
our support team will not provide any support with your own written CSS.
## Limitations and dangers
When using custom CSS, you can break the page or certain functionalities.
Although CSS can improve the design & feel of the page, it **<ins>cannot do any of the following</ins>**:
@@ -33,21 +35,23 @@ Although CSS can improve the design & feel of the page, it **<ins>cannot do any
- Completely revamp the design of the page, only smaller changes are possible
Here are some dangers of using custom CSS:
- Updates may contain breaking changes in the structure, built-in styling or how styling is processed. Therefore,
custom CSS may break unexpectedly without any warning
custom CSS may break unexpectedly without any warning
- Custom CSS may make certain elements invisible or not possible to click / interact with
- Custom CSS could make readability and accessibility worse for impaired people
## How to inspect the page
When styling the page, you can use the ``Inspector`` to inspect elements on the page and try out styles.
When styling the page, you can use the `Inspector` to inspect elements on the page and try out styles.
This may vary depending on your browser and operating system, but the workflow usually goes like this:
- Open the Homarr page
- Press ``Ctrl`` + ``Shift`` + ``I`` at the same time.
Alternatively, right-click on the page and choose ``Inspect`` or ``Inspect element``.
- Open the tab ``Elements`` if it isn't open yet.
- Press `Ctrl` + `Shift` + `I` at the same time.
Alternatively, right-click on the page and choose `Inspect` or `Inspect element`.
- Open the tab `Elements` if it isn't open yet.
- Search the element you want to change in the DOM tree or use the element picker (usually at the top left)
to select it by clicking on the page.
to select it by clicking on the page.
- Experiment by changing the CSS code on the right side
When writing custom CSS, it is important to also remember or create a selector, which tells the browser
@@ -55,17 +59,19 @@ which element to apply the styles to. If you accidentally broke something or wan
simply reload the page.
## Using Homarr's classes
Homarr's elements will already have a lot of classes and styles pre-applied.
You can reuse those classes to apply additional styles or overwrite them.
When overwriting, remember to add the ``!important`` flag to your CSS property to tell the browser to use our instruction instead.
When overwriting, remember to add the `!important` flag to your CSS property to tell the browser to use our instruction instead.
Classes with random number suffixes, such as ``mantine-Card-x2fske``, should be avoided, since those are dynamic
Classes with random number suffixes, such as `mantine-Card-x2fske`, should be avoided, since those are dynamic
CSS classes that will change with every build. This means, every time you update Homarr,
your styles will no longer apply to them
## Defining custom classes for widgets
If you want to apply the styles only for one widget, you can define custom class names only for that widget.
To do that, enter edit mode on your board, click the three dots of your widget, click ``Edit item`` and click ``Advanced options``.
To do that, enter edit mode on your board, click the three dots of your widget, click `Edit item` and click `Advanced options`.
Then, you can enter as many custom classes as you'd like:
![](./img/widget-custom-classes.png)
@@ -73,6 +79,7 @@ Then, you can enter as many custom classes as you'd like:
To save them, click `Save changes` on both modals and exit edit mode.
## Where to enter custom CSS
After you wrote your custom CSS, it is time to permanently save it, so you don't need to use the inspector anymore.
To do this, enter the board settings:
@@ -84,11 +91,12 @@ Here you can enter your CSS code, which will be applied on the respective board
![](./img/custom-css-setting.png)
## Using variables
You can also change the values of the theme variables, which are located here: https://mantine.dev/styles/css-variables-list/.
To do this, see the following example CSS:
```css
:root {
--mantine-primary-color-filled: #ffbb00;
--mantine-primary-color-filled: #ffbb00;
}
```
```
+5 -1
View File
@@ -7,12 +7,15 @@ tags:
---
# Donate
## Why to donate
Our team of 4 developers is working on Homarr in their free time.
Homarr has become a big part of our daily things we work on - and therefore we invest a lot of time into maintaining Homarr,
providing support and implementing new features.
We also incur monetary costs while developing Homarr for the tools that we need.
A few examples include:
- Renting for a Cloud VPS for our cloud services (status page, monitoring, email, analytics, [demo instance](https://demo.homarr.dev/), ...)
- Paying for (IDE-) licenses
@@ -20,6 +23,7 @@ Using a donation, you help us to cover these expenses and enable the development
Homarr is completely free to use. We'd highly appreciate if you consider donating, especially if you use Homarr in a commercial environment.
## Where to donate
We accept donations on our official [OpenCollective](https://opencollective.com/homarr).
You may also sponsor us directly by providing a useful service / product to us other means.
You can get into contact with us [here](/docs/community/get-in-touch).
You can get into contact with us [here](/docs/community/get-in-touch).
+2 -2
View File
@@ -9,16 +9,16 @@ tags:
We're happy to talk with you! Shoot us a message at the following places:
## E-Mail
We are open to discuss sponsorships, security vulnerabilities and other private requests through our email.
Please do not report any bugs / feature requests here - they will be ignored and deleted.
[homarr-labs@proton.me](mailto:homarr-labs@proton.me)
## Discord
We have a Discord Server, where we announce new releases, discuss features and bugs and show off our dashboards.
There are over 4'000 members and we're happy to answer your questions or concerns.
You're also open to discuss new / upcoming features and any offtopic selfhosting content.
[_![](https://discordapp.com/api/guilds/972958686051962910/widget.png?style=banner2)_](https://discord.gg/aCsmEV5RgA)
+1 -2
View File
@@ -7,6 +7,7 @@ tags:
Homarr is licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).
## TL;DR
| Action | Allowed |
| -------------- | ------- |
| Copy | ✅ |
@@ -24,8 +25,6 @@ Please consider [making a donation](/docs/community/donate) to Homarr, if this p
:::
## Full License
```txt
+14 -12
View File
@@ -5,30 +5,31 @@ tags:
- Translations
---
We want to make Homarr accessible for everyone.
But to do that, we need your help.
We are running a community program that enables everyone to translate Homarr into their language – no programming required.
We are using [Crowdin](https://crowdin.com/) to manage our translations.
We want to make Homarr accessible for everyone.
But to do that, we need your help.
We are running a community program that enables everyone to translate Homarr into their language – no programming required.
We are using [Crowdin](https://crowdin.com/) to manage our translations.
You can find the translations [here](https://translate.homarr.dev/).
## How to translate
### Using crowdin's online platform
Go to the [Crowdin translations](https://translate.homarr.dev/) and select a language you want to translate.
You can then enter the translation mode and start translating.
After you've submitted your translations, a Proofreader will review your changes.
After a translation has been approved, it will be merged to the language development branch.
We merge this one periodically to the development branch.
Go to the [Crowdin translations](https://translate.homarr.dev/) and select a language you want to translate.
You can then enter the translation mode and start translating.
After you've submitted your translations, a Proofreader will review your changes.
After a translation has been approved, it will be merged to the language development branch.
We merge this one periodically to the development branch.
After the next update of Homarr, all changes from the development branch will be merged, including the changes in the translations.
### Using live translate
You can also help translate homarr directly from the app!
For this you can simply change your language to "Crowdin (live translations)"
![](./img/crowdin-language-select.png)
Then you'll be prompted to connect to your Crowdin account and choose the language in which you want to transalte.
Then you'll be prompted to connect to your Crowdin account and choose the language in which you want to transalte.
You can then start translating directly from the app by selecting some text on the app.
If some text cannot be selected to be edited with the live translation tool, you can still translate it inside of the In-Context popup at the Home tab, it will be red if it's not translated yet.
@@ -47,7 +48,8 @@ Do you want to become a proofreader? [Let us know on our Discord](/docs/communit
:::
## Guidelines
1. Translate with context: Some translations can't be translated 1:1 - they need context. Ensure that your translations make sense in the context.
2. Keep things simple and original - no additional characters are needed.
3. Don't translate the same thing twice - if you see a translation that is already translated, don't translate it again unless you have a better translation.
5. Keep your translations as close to the original as possible.
4. Keep your translations as close to the original as possible.
@@ -54,11 +54,7 @@ You must choose a username and password (both can later be changed).
We enforce strict password requirements when you enter your password to protect your instance if you accidentally
expose it to the internet.
<img
src={imageStartFromScratchStepAdminUser}
alt={"Screenshot form to create admin user"}
width={300}
/>
<img src={imageStartFromScratchStepAdminUser} alt={"Screenshot form to create admin user"} width={300} />
If you selected external providers (such as LDAP or OIDC), you'll be prompted to create an admin group.
This group will be used to synchronize users from your provider to Homarr.
@@ -116,22 +112,14 @@ The onboarding can no longer be started again.
From here you can click on one of the provided links to continue your journey.
We recommend you to continue with the section [creating your first board on this page](#creating-your-first-board).
<img
src={imageStartFromScratchStepFinish}
alt={"Screenshot of the finish onboarding process with links"}
width={300}
/>
<img src={imageStartFromScratchStepFinish} alt={"Screenshot of the finish onboarding process with links"} width={300} />
### Importing a ZIP from version before 1.0.0
This is recommended when you used Homarr before and want to re-import your data.
It is important that you first migrate correctly using [the list of breaking changes for 1.0](/blog/2024/09/23/version-1.0).
<img
src={manageExportOldHomarr}
alt="Export from old Homarr"
style={{ maxWidth: 500 }}
/>
<img src={manageExportOldHomarr} alt="Export from old Homarr" style={{ maxWidth: 500 }} />
**How to export and import data**
@@ -197,38 +185,23 @@ Here you have the following options in the header:
When entering the edit mode, you'll get some additional buttons to work with:
<img
src={manageBoardHeaderEditMode}
alt={"Screenshot of buttons in the edit mode"}
width={200}
/>
<img src={manageBoardHeaderEditMode} alt={"Screenshot of buttons in the edit mode"} width={200} />
- **Add item**: Click this button to add new elements to your page.
- **Exit edit mode**: Click this btuton to save your changes and exit edit mode.
To continue, click the option "New Item":
<img
src={manageBoardHeaderAddItem}
alt={"Screenshot of the add item menu"}
width={200}
/>
<img src={manageBoardHeaderAddItem} alt={"Screenshot of the add item menu"} width={200} />
Next, you can choose what item you'd like to add.
We will discuss the other options in the following sections - for now choose "App" to continue.
<img
src={manageBoardHeaderChooseItem}
alt={"Screenshot of choosing the app item in the modal"}
width={300}
/>
<img src={manageBoardHeaderChooseItem} alt={"Screenshot of choosing the app item in the modal"} width={300} />
As soon as you chose the app, the modal will close and you'll get the following item on your board:
<img
src={manageBoardNoApp}
alt="Screenshot of the No app element on the board"
/>
<img src={manageBoardNoApp} alt="Screenshot of the No app element on the board" />
This is expected, because you haven't told Homarr what app it should show in this item.
To configure this, click on the small 3 dots at the top of the item in the edit mode and choose "Edit item" in the menu.
+2 -1
View File
@@ -1,8 +1,9 @@
# Glossary
In the glossary, you'll learn the different components and their names of Homarr.
| Term | Definition |
|-----------------|----------------------------------------------------------------------------------------------------------------|
| --------------- | -------------------------------------------------------------------------------------------------------------- |
| Apps | An piece of software that you or a third party hosts (eg. Google) |
| Integration | A connection to a service outside of Homarr |
| Dynamic section | Resizeable area where items on your board can be placed and grouped |
+7 -6
View File
@@ -8,13 +8,14 @@ tags:
- Unraid
---
import Link from '@docusaurus/Link';
import { IconArrowRight } from '@tabler/icons-react';
import Link from "@docusaurus/Link";
import { IconArrowRight } from "@tabler/icons-react";
Before you try to install Homarr, please review if your device meets the requirements.
Installing on an unsupported device may lead to unstable behaviour and no support will be provided.
## Hardware
- At least 500MB RAM
- At least 600MB of free disk space for the Docker image. SSD is preferred.
- Single or dual core CPU
@@ -24,8 +25,8 @@ Installing on an unsupported device may lead to unstable behaviour and no suppor
We build Homarr for a bunch of different architectures, including ARM. Please ensure that your device architecture is supported by Homarr. We won't be able to provide support for unusual or outdated architectures.
| Architecture | Supported |
|--------------|-----------------|
| Architecture | Supported |
| ------------ | ---------------- |
| linux/amd64 | ✅ Supported |
| linux/arm64 | ✅ Supported |
| linux/arm/v7 | ❌ Not supported |
@@ -34,10 +35,10 @@ We build Homarr for a bunch of different architectures, including ARM. Please en
<Link
data-attr="Go to installation"
className={'button button--secondary button--lg rounded-3xl dark:border-zinc-600 dark:bg-zinc-800'}
className={"button button--secondary button--lg rounded-3xl dark:border-zinc-600 dark:bg-zinc-800"}
to="/docs/category/installation-1"
>
<div className={'flex items-center gap-3'}>
<div className={"flex items-center gap-3"}>
<span className={"dark:text-gray-200"}>Go to Installation</span>
<IconArrowRight className={"dark:text-gray-200"} size={20} />
</div>
@@ -1,21 +1,23 @@
import { DockerInstallSnippet } from '@site/src/components/pages/installation/docker/dynamic-docker-install'
import { DockerInstallSnippet } from "@site/src/components/pages/installation/docker/dynamic-docker-install";
# Docker
Docker is our recommended installation method for beginners and professionals.
It is easy to use, ships with all dependencies inside a single container and is easy to use and maintain.
It requires at least some basic knowledge of [Docker](https://www.docker.com/).
We recommend [NetworkChuck's Docker Containers 101](https://www.youtube.com/watch?v=eGz9DS-aIeY) as a good start for complete beginners.
## Docker compose
### Prerequisites
- A Linux or Windows based system that meets the [hardware prerequisites](/docs/getting-started/#hardware) and [architecture prerequisites](/docs/getting-started/#architecture).
- [Docker](https://docs.docker.com/get-docker/)
- [Docker Compose](https://docs.docker.com/compose/install/) - *preinstalled on many systems nowadays*
- [Docker Compose](https://docs.docker.com/compose/install/) - _preinstalled on many systems nowadays_
### Installation
<DockerInstallSnippet data-visual-test="blackout"/>
<DockerInstallSnippet data-visual-test="blackout" />
Finally, run ``docker compose up -d`` in the same directory. This will start the Homarr container in the background.
:::caution
@@ -26,27 +28,26 @@ Docker compose creates a network by default. Some integrations may not work (spe
### Updating
To update, navigate to the directory with the ``docker-compose.yaml`` located.
To update, navigate to the directory with the `docker-compose.yaml` located.
- Stop Homarr using ``docker compose down``
- Pull the newest image of Homarr using ``docker compose pull``
- Start Homarr again using ``docker compose up -d`` (``-d`` for detached mode - start in background)
- Delete the old image using ``docker image prune`` (*Warning: this also removes you other unused images - not just Homarr*)
- Stop Homarr using `docker compose down`
- Pull the newest image of Homarr using `docker compose pull`
- Start Homarr again using `docker compose up -d` (`-d` for detached mode - start in background)
- Delete the old image using `docker image prune` (_Warning: this also removes you other unused images - not just Homarr_)
You can automate this process using [Watchtower](https://containrrr.dev/watchtower/).
### Uninstalling
To uninstall, navigate to the directory with the ``docker-compose.yaml`` located.
To uninstall, navigate to the directory with the `docker-compose.yaml` located.
- Stop Homarr using ``docker compose down``
- Delete the created directories & files on your root file system (check ``docker-compose.yaml`` file for your specific locations)
- Delete compose file using ``rm docker-compose.yaml``
- Prune unused Docker images using ``docker image prune`` (*Warning: this also removes you other unused images - not just Homarr*)
- Stop Homarr using `docker compose down`
- Delete the created directories & files on your root file system (check `docker-compose.yaml` file for your specific locations)
- Delete compose file using `rm docker-compose.yaml`
- Prune unused Docker images using `docker image prune` (_Warning: this also removes you other unused images - not just Homarr_)
- (Optional): Prune any network or volumes if you use any.
- (Optional): Remove Homarr from your reverse proxy, VPNs or tunnels if you use any.
## Docker standalone
:::caution
@@ -77,15 +78,16 @@ docker run \
:::note
Docker will mount the configuration files and icons to your host machine. Please make sure to replace ``<your-path>`` from the docker run command with your desired storage location. The path must be absolute.
Docker will mount the configuration files and icons to your host machine. Please make sure to replace `<your-path>` from the docker run command with your desired storage location. The path must be absolute.
:::
### Updating
To update Homarr, you must remove your container first. Make sure that you've mounted your data and that you have access to it, so your configuration doesn't get lost.
1. Run ``docker rm homarr`` to remove the container.
2. Pull the latest Homarr image ``docker pull ghcr.io/homarr-labs/homarr:latest``.
1. Run `docker rm homarr` to remove the container.
2. Pull the latest Homarr image `docker pull ghcr.io/homarr-labs/homarr:latest`.
3. Re-run the command you used to install Homarr.
This process can get tideous, if you update frequently. Thus, we recommend [using docker-compose](#docker-compose)
@@ -98,8 +100,8 @@ Want to update all your containers automatically? Checkout [Watchtower](https://
### Uninstalling
1. Obtain the container ID of your Homarr container using ``docker ps | grep homarr``.
2. Delete the container using ``docker rm <your-container-id>``
3. Prune unused Docker images using ``docker image prune`` (*Warning: this also removes you other unused images - not just Homarr*)
1. Obtain the container ID of your Homarr container using `docker ps | grep homarr`.
2. Delete the container using `docker rm <your-container-id>`
3. Prune unused Docker images using `docker image prune` (_Warning: this also removes you other unused images - not just Homarr_)
4. (Optional): Prune any network or volumes if you use any.
5. (Optional): Remove Homarr from your reverse proxy, VPNs or tunnels if you use any.
@@ -12,7 +12,7 @@ A Helm chart to deploy homarr for Kubernetes
## Source Code
* <https://github.com/homarr-labs/homarr>
- <https://github.com/homarr-labs/homarr>
## Requirements
@@ -76,38 +76,38 @@ To avoid including sensitive information in plain text within your version contr
Below is an exhaustive list of all secrets:
| FEATURE | SECRET NAME | SECRET KEYS | Required |
|-----------|-------------------------|-----------------------------------------|----------|
| OIDC | auth-oidc-secret | oidc-client-id<br>oidc-client-secret | No |
| LDAP | auth-ldap-secret | bind-password | No |
| DATABASE | db-secret | db-url | No |
| DATABASE | db-encryption | db-encryption-key | yes |
| FEATURE | SECRET NAME | SECRET KEYS | Required |
| -------- | ---------------- | ------------------------------------ | -------- |
| OIDC | auth-oidc-secret | oidc-client-id<br>oidc-client-secret | No |
| LDAP | auth-ldap-secret | bind-password | No |
| DATABASE | db-secret | db-url | No |
| DATABASE | db-encryption | db-encryption-key | yes |
### Database
You have multiple options for configuring the database:
| DRIVER TYPE | Persistence mode |
|----------------|---------------------------------|
| better-sqlite3 | Pod disk |
| better-sqlite3 | homarr-database PVC |
| mysql2 | External MySql database |
| node-postgres | External Postgresql database |
| DRIVER TYPE | Persistence mode |
| -------------- | ---------------------------- |
| better-sqlite3 | Pod disk |
| better-sqlite3 | homarr-database PVC |
| mysql2 | External MySql database |
| node-postgres | External Postgresql database |
#### Pod disk
No additional configuration is required. However, keep in mind that if the pod restarts, all data will be lost. This setup is not *recommended* for production use.
No additional configuration is required. However, keep in mind that if the pod restarts, all data will be lost. This setup is not _recommended_ for production use.
To create the necessary database secret, execute the following command:
<details>
<summary>Required Secrets</summary>
````yaml
```yaml
kubectl create secret generic db-encryption \
--from-literal=db-encryption-key='<SECRET_ENCRYPTION_KEY_SECRET_TO_CHANGE>' \
--namespace homarr
````
```
</details>
@@ -120,11 +120,11 @@ Associated secret to create :
<details>
<summary>DB Required Secrets</summary>
````yaml
```yaml
kubectl create secret generic db-encryption \
--from-literal=db-encryption-key='<SECRET_ENCRYPTION_KEY_SECRET_TO_CHANGE>' \
--namespace homarr
````
```
</details>
@@ -133,13 +133,13 @@ Bellow an example of the override value file :
<details>
<summary>values.yaml</summary>
````yaml
```yaml
persistence:
homarrDatabase:
enabled: true
storageClassName: "default"
size: "1Gi"
````
```
</details>
@@ -150,17 +150,18 @@ To create the necessary database secrets, execute the following command:
<details>
<summary>Required Secrets</summary>
````yaml
```yaml
kubectl create secret generic db-encryption \
--from-literal=db-encryption-key='<SECRET_ENCRYPTION_KEY_SECRET_TO_CHANGE>' \
--namespace homarr
````
```
````yaml
```yaml
kubectl create secret generic db-secret \
--from-literal=db-url='mysql://user:password@host:port/homarrdb' \
--namespace homarr
````
```
</details>
Below is an example of the override values file:
@@ -168,10 +169,11 @@ Below is an example of the override values file:
<details>
<summary>values.yaml</summary>
````yaml
```yaml
database:
type: mysql
````
```
</details>
#### External Postgresql database
@@ -181,17 +183,17 @@ To create the necessary database secrets, execute the following command:
<details>
<summary>Required Secrets</summary>
````yaml
```yaml
kubectl create secret generic db-encryption \
--from-literal=db-encryption-key='<SECRET_ENCRYPTION_KEY_SECRET_TO_CHANGE>' \
--namespace homarr
````
```
````yaml
```yaml
kubectl create secret generic db-secret \
--from-literal=db-url='postgresql://user:password@host:port/homarrdb' \
--namespace homarr
````
```
</details>
@@ -200,10 +202,11 @@ Below is an example of the override values file:
<details>
<summary>values.yaml</summary>
````yaml
```yaml
database:
type: postgresql
````
```
</details>
### Ingress
@@ -213,7 +216,7 @@ The ingress section in the values.yaml file allows you to configure how external
<details>
<summary>values.yaml</summary>
````yaml
```yaml
service:
enabled: true # Ensure the service is enabled for Ingress to route traffic
ingress:
@@ -231,7 +234,8 @@ ingress:
- "homarr.homelab.dev"
- "www.homarr.homelab.dev"
secretName: homelab-tls
````
```
</details>
### HTTPRoute (Gateway API)
@@ -242,9 +246,9 @@ This provides a more expressive and future-proof alternative to Ingress, with su
<details>
<summary>values.yaml</summary>
````yaml
```yaml
service:
enabled: true # must be enabled for HTTPRoute to forward traffic
enabled: true # must be enabled for HTTPRoute to forward traffic
httproute:
enabled: true
parentRefs:
@@ -268,7 +272,7 @@ httproute:
- parentRefs: the Gateway(s) this route attaches to. Gateways must already exist.
- hostnames: domain names this route applies to.
- rules: each rule can define matches (paths, headers, queries), optional filters, and backendRefs to services
- rules: each rule can define matches (paths, headers, queries), optional filters, and backendRefs to services
- TLS must be configured on the Gateway (not on HTTPRoute). For example, the Gateway can have a TLS listener for homarr.homelab.dev, and this route will automatically apply once matched.
### Certificates
@@ -285,7 +289,7 @@ Use inline certificates to generate a ConfigMap, mounted as individual files.
<details>
<summary>values.yaml</summary>
````yaml
```yaml
persistence:
homarrTrustedCerts:
enabled: true
@@ -299,7 +303,8 @@ persistence:
-----BEGIN CERTIFICATE-----
MIID...EFGH==
-----END CERTIFICATE-----
````
```
</details>
Behavior:
@@ -314,7 +319,7 @@ Use inline certificates to generate a Kubernetes Secret, mounted as files.
<details>
<summary>values.yaml</summary>
````yaml
```yaml
persistence:
homarrTrustedCerts:
enabled: true
@@ -328,7 +333,8 @@ persistence:
-----BEGIN CERTIFICATE-----
MIIC...XYZ==
-----END CERTIFICATE-----
````
```
</details>
Behavior:
@@ -343,16 +349,17 @@ Use an existing Kubernetes Secret, assuming its keys are filenames.
<details>
<summary>values.yaml</summary>
````yaml
```yaml
persistence:
homarrTrustedCerts:
enabled: true
type: existingSecret
existingSecretName: "existingSecretName"
existingSecretKeys:
- cert3.crt
- cert4.crt
````
- cert3.crt
- cert4.crt
```
</details>
Behavior:
@@ -483,4 +490,5 @@ All available values are listed on the [artifacthub](https://artifacthub.io/pack
| tolerations | list | `[]` | Node tolerations for pod scheduling |
---
Autogenerated from chart metadata using [helm-docs](https://github.com/norwoodj/helm-docs)
@@ -14,7 +14,7 @@ Homarr can be seamlessly integrated into your Home Assistant setup with this add
## Installation
1. **Add Repository**: Navigate to your Home Assistant Supervisor panel, and go to the Add-on Store. Add the following repository URL: `https://github.com/Wiggen94/ha-homarr-v1-server` or click this button
[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2FWiggen94%2Fha-homarr-v1-server)
[![Open your Home Assistant instance and show the add add-on repository dialog with a specific repository URL pre-filled.](https://my.home-assistant.io/badges/supervisor_add_addon_repository.svg)](https://my.home-assistant.io/redirect/supervisor_add_addon_repository/?repository_url=https%3A%2F%2Fgithub.com%2FWiggen94%2Fha-homarr-v1-server)
2. **Install the Add-on**: Search for "Homarr Server" in the Add-on Store and select it. Click on "Install" to start the installation process.
@@ -1,5 +1,7 @@
# Portainer
## Portainer Stacks
### Prerequisites
- [Portainer Stacks](https://www.portainer.io/blog/stacks-docker-compose-the-portainer-way)
@@ -23,15 +25,14 @@ services:
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
ports:
- '7575:7575'
- "7575:7575"
```
:::note
Portainer will mount the files to your host machine. Please make sure to replace ``<your-path>`` from the docker run command with your desired storage location. The path must be absolute.
Portainer will mount the files to your host machine. Please make sure to replace `<your-path>` from the docker run command with your desired storage location. The path must be absolute.
:::
Then, click on ``Deploy the stack`` and wait until the container has started.
Then, click on `Deploy the stack` and wait until the container has started.
:::tip
@@ -43,5 +44,5 @@ If you're unsure how to create a stack, checkout the [Portainer Documentation](h
To update Homarr using Docker Compose or Portainer Stacks, simply pull the latest image and restart the container.
1. Run ``docker pull ghcr.io/homarr-labs/homarr:latest`` to pull the latest image.
2. Re-run ``docker-compose up -d`` or re-deploy the stack in Portainer.
1. Run `docker pull ghcr.io/homarr-labs/homarr:latest` to pull the latest image.
2. Re-run `docker-compose up -d` or re-deploy the stack in Portainer.
@@ -31,7 +31,7 @@ After you've installed Homarr, you can find a new LXC "homarr".
# Updating
Updating is as simple as executing
Updating is as simple as executing
```bash
update
@@ -49,17 +49,19 @@ Some Homarr features require setting environment variables. When installing Homa
# Troubleshooting
If something does not work after an update, please first try rebooting the LXC or the homarr Service with
If something does not work after an update, please first try rebooting the LXC or the homarr Service with
```bash
systemctl restart homarr
```
# Getting help
- If you are looking for help with the script, updating the LXC or troubleshooting the installer, please get in contact with the support of the community scripts. They provide support on their [Discord](https://discord.gg/2wvnMDgdnU). If you found vulnerabilities, bugs or have a request for the script, [create a new issue here](https://github.com/community-scripts/ProxmoxVE/issues/new/choose).
- If you are looking to report a bug, vulnerability or request a new feature, use https://github.com/homarr-labs/homarr . You can ask for help on our Discord.
# How to find logs
Homarr runs under a system service called `homarr`, so getting the logs is a simple as using the following command inside the LXC (Container) Shell
```bash
@@ -4,6 +4,6 @@
QNAP installation guide has not updated to 1.0 yet. There guide is still for 0.15.10.
:::
When installing on QNAP, we recommend you to install Homarr using [Container Station]( https://www.qnap.com/en/software/container-station) or [this third-party image](https://www.myqnap.org/product/homarr/).
When installing on QNAP, we recommend you to install Homarr using [Container Station](https://www.qnap.com/en/software/container-station) or [this third-party image](https://www.myqnap.org/product/homarr/).
There is also a guide available, but note that it is written in Chinese: https://post.smzdm.com/p/awzm7op2/
@@ -1,4 +1,4 @@
# Runtipi
# Runtipi
Runtipi is a self-hosted orchestrator that makes it easy to manage and run multiple services on a single server. It is based on Docker and comes with a simple web interface to manage your services. Runtipi is designed to be easy to use, so you don't have to worry about manual configuration or networking.
@@ -11,6 +11,7 @@ https://runtipi.io
# Installation
Installing Homarr is pretty untuitive, the app is available in the default appstore :
1. Search for **"Homarr"** in the App-Store page and select it
2. Click on **"Install"**.
3. Choose the method you want to access Homarr, through any port or domain name then select **"Install"**
@@ -18,13 +19,15 @@ Installing Homarr is pretty untuitive, the app is available in the default appst
# Maintenance
After installation, all you need is available from the WebUI in **"My apps"** > **"Homarr"** :
- Start/Stop
- Update
- Backup
- Logs
- Start/Stop
- Update
- Backup
- Logs
If you like to tinker with your apps, you can also edit your app's docker-compose with a [user-config](https://runtipi.io/docs/guides/customize-app-config).
# Getting help
- If you are looking for help with anything in Runtipi. They provide support on their [Discord](https://discord.gg/Bu9qEPnHsc) and [forums](https://forums.runtipi.io/). If you found vulnerabilities or bugs, [create a new issue here](https://github.com/runtipi/runtipi-appstore/issues).
- If you are looking to report a bug, vulnerability or request a new feature for Homarr, use https://github.com/homarr-labs/homarr . You can ask for help on our Discord.
- If you are looking to report a bug, vulnerability or request a new feature for Homarr, use https://github.com/homarr-labs/homarr . You can ask for help on our Discord.
@@ -5,6 +5,7 @@ Saltbox installation command has not updated to 1.0 yet. There command still run
:::
You can also use this to install on Saltbox:
```bash
sb install sandbox-homarr
```
```
@@ -28,15 +28,29 @@ This method is only useful, when you want to develop on Homarr or extend it with
## Steps
<ol>
<li>Clone the Repository using <code>git clone https://github.com/homarr-labs/homarr.git</code></li>
<li>Enter the created directory using <code>cd homarr</code></li>
<li>Install all dependencies using <code>pnpm install</code></li>
<li>Copy the `.env.example` file to `.env` and replace `DB_URL` with the full path you want to use for the sqlite database file. For example `DB_URL='/home/username/homarr/db.sqlite`</li>
<li>Replace `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` both with a secure random string by using `openssl rand -hex 32`</li>
<li>
Clone the Repository using <code>git clone https://github.com/homarr-labs/homarr.git</code>
</li>
<li>
Enter the created directory using <code>cd homarr</code>
</li>
<li>
Install all dependencies using <code>pnpm install</code>
</li>
<li>
Copy the `.env.example` file to `.env` and replace `DB_URL` with the full path you want to use for the sqlite
database file. For example `DB_URL='/home/username/homarr/db.sqlite`
</li>
<li>
Replace `AUTH_SECRET` and `SECRET_ENCRYPTION_KEY` both with a secure random string by using `openssl rand -hex 32`
</li>
<li>Replace `CRON_JOB_API_KEY` with a secure random string by using `openssl rand -base64 32`</li>
<li>Run `pnpm run db:migration:sqlite:run` and wait that it completes</li>
<li>Build the source using `pnpm build`</li>
<li>Copy better-sqlite3.node files with `mkdir build` and `cp ./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node`</li>
<li>
Copy better-sqlite3.node files with `mkdir build` and `cp
./node_modules/better-sqlite3/build/Release/better_sqlite3.node ./build/better_sqlite3.node`
</li>
<li>Start a redis server using `redis-server`</li>
<li>Run the server using `pnpm start`</li>
<li>Open `http://localhost:3000` in your browser</li>
@@ -1,5 +1,5 @@
import Link from '@docusaurus/Link';
import { IconDownload } from '@tabler/icons-react';
import Link from "@docusaurus/Link";
import { IconDownload } from "@tabler/icons-react";
# Unraid
@@ -14,17 +14,17 @@ You can install Homarr directly from your Unraid Dashboard, no terminal required
<Link
data-attr="Install Unraid Community Apps"
className={'button button--secondary button--lg rounded-3xl dark:border-zinc-600 dark:bg-zinc-800'}
className={"button button--secondary button--lg rounded-3xl dark:border-zinc-600 dark:bg-zinc-800"}
to="https://forums.unraid.net/topic/38582-plug-in-community-applications/"
>
<div className={'flex items-center gap-3'}>
<div className={"flex items-center gap-3"}>
<span className={"dark:text-gray-200"}>Install community applications plugin</span>
<IconDownload className={"dark:text-gray-200"} size={20} />
</div>
</Link>
<br/>
<br/>
<br />
<br />
:::tip
@@ -46,4 +46,3 @@ After you've installed the Community Apps Plugin, you can install Homarr from th
After you've installed Homarr, you can find it under the tab "Docker".
The official support thread is located [here](https://forums.unraid.net/topic/123478-support-smartphonelover-homarr/), but we prefer to communicate over GitHub and Discord instead.
@@ -1,37 +1,44 @@
---
title: 'AdGuard Home'
title: "AdGuard Home"
description: "AdGuard Home is a network-wide software for blocking ads and trackers, providing a safer and faster internet experience."
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 { 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 { IconAd, IconDeviceGamepad } from "@tabler/icons-react";
import { adguardHomeIntegration } from '.';
import { dnsHoleSummaryWidget } from '@site/docs/widgets/dns-hole-summary';
import { dnsHoleControlsWidget } from '@site/docs/widgets/dns-hole-controls';
import { adguardHomeIntegration } from ".";
import { dnsHoleSummaryWidget } from "@site/docs/widgets/dns-hole-summary";
import { dnsHoleControlsWidget } from "@site/docs/widgets/dns-hole-controls";
<IntegrationHeader
integration={adguardHomeIntegration}
categories={['DNS Hole']}
/>
<IntegrationHeader integration={adguardHomeIntegration} categories={["DNS Hole"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: dnsHoleSummaryWidget,
},{
widget: dnsHoleControlsWidget
}]}
items={[
{
widget: dnsHoleSummaryWidget,
},
{
widget: dnsHoleControlsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
+28 -23
View File
@@ -1,40 +1,45 @@
---
title: 'Anchor'
title: "Anchor"
description: "Anchor is a self-hosted note-taking application."
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 { anchorIntegration } from '.';
import { anchorNoteWidget } from '@site/docs/widgets/anchor-note';
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 { anchorIntegration } from ".";
import { anchorNoteWidget } from "@site/docs/widgets/anchor-note";
<IntegrationHeader
integration={anchorIntegration}
categories={['Notes']}
/>
<IntegrationHeader integration={anchorIntegration} categories={["Notes"]} />
The Anchor integration lets Homarr connect to your Anchor instance so you can display and edit selected notes directly from your dashboard.
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: anchorNoteWidget
}]}
items={[
{
widget: anchorNoteWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
'Open your Anchor instance.',
'Generate or copy an API key from Anchor settings.',
'Paste that key into the API Key secret field in Homarr.'
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open your Anchor instance.",
"Generate or copy an API key from Anchor settings.",
"Paste that key into the API Key secret field in Homarr.",
],
},
]}
/>
+28 -23
View File
@@ -1,38 +1,43 @@
---
title: 'Aria2'
title: "Aria2"
description: "Lightweight multiprotocol & multi-source command-line download utility. It supports HTTP/HTTPS, FTP, SFTP, BitTorrent and Metalink"
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 { aria2Integration } from '.';
import { downloadsWidget } from '@site/docs/widgets/downloads';
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 { aria2Integration } from ".";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={aria2Integration}
categories={['Download', 'Multiprotocol', 'Multi-source']}
/>
<IntegrationHeader integration={aria2Integration} categories={["Download", "Multiprotocol", "Multi-source"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: downloadsWidget,
}]}
items={[
{
widget: downloadsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[
{
credentials: ['apiKey'],
steps: []
},
{
credentials: [],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
{
credentials: [],
steps: [],
},
]}
/>
@@ -1,41 +1,40 @@
---
title: 'Audiobookshelf'
title: "Audiobookshelf"
description: "Audiobookshelf is a self-hosted audiobook and podcast server that lets you manage and stream your audio library."
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 { audiobookshelfIntegration } from '.';
import { audioStatsWidget } from '@site/docs/widgets/audio-stats';
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 { audiobookshelfIntegration } from ".";
import { audioStatsWidget } from "@site/docs/widgets/audio-stats";
<IntegrationHeader
integration={audiobookshelfIntegration}
categories={['Media']}
/>
<IntegrationHeader integration={audiobookshelfIntegration} categories={["Media"]} />
Audiobookshelf provides library statistics including audiobook and podcast counts, listening time, and active sessions.
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: audioStatsWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: audioStatsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
'Open your Audiobookshelf instance',
'Go to Settings → Users',
'Click on your user account',
'Copy the API token from the user details',
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open your Audiobookshelf instance",
"Go to Settings → Users",
"Click on your user account",
"Copy the API token from the user details",
],
},
]}
/>
+28 -24
View File
@@ -1,31 +1,30 @@
---
title: 'Bazarr'
title: "Bazarr"
description: "Bazarr is a companion application to Sonarr and Radarr that manages and downloads subtitles."
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 { bazarrIntegration } from '.';
import { bazarrWidget } from '@site/docs/widgets/bazarr';
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 { bazarrIntegration } from ".";
import { bazarrWidget } from "@site/docs/widgets/bazarr";
<IntegrationHeader
integration={bazarrIntegration}
categories={['Subtitles', 'Media']}
/>
<IntegrationHeader integration={bazarrIntegration} categories={["Subtitles", "Media"]} />
Bazarr complements Sonarr and Radarr by managing subtitle downloads. The Homarr integration uses your Bazarr API key to fetch missing subtitle counts and health badges.
### Screenshots
import apiKeySettings from './img/api-key-settings.png';
import widgetOverview from '@site/docs/widgets/bazarr/img/widget-overview.png';
import apiKeySettings from "./img/api-key-settings.png";
import widgetOverview from "@site/docs/widgets/bazarr/img/widget-overview.png";
<div className="flex flex-col gap-4">
<div>
<p>API key location in Bazarr (<strong>Settings → General → Security</strong>):</p>
<p>
API key location in Bazarr (<strong>Settings → General → Security</strong>):
</p>
<img src={apiKeySettings} alt="bazarr-api-key-settings" width={128 * 4} />
</div>
<div>
@@ -35,20 +34,25 @@ import widgetOverview from '@site/docs/widgets/bazarr/img/widget-overview.png';
</div>
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: bazarrWidget }]}
/>
<IntegrationCapabilites items={[{ widget: bazarrWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
You can find your Bazarr API key under **Settings → General → Security**.
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
"Open Bazarr and go to Settings → General → Security.",
"Copy the API key and paste it into Homarr when creating the integration.",
],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open Bazarr and go to Settings → General → Security.",
"Copy the API key and paste it into Homarr when creating the integration.",
],
},
]}
/>
+32 -28
View File
@@ -1,25 +1,22 @@
---
title: 'Beszel'
title: "Beszel"
description: "Beszel is a lightweight server monitoring platform with Docker stats, historical data, and alert functions."
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 { beszelIntegration } from '.';
import { beszelSystemStatsWidget } from '@site/docs/widgets/beszel-system-stats';
import { beszelSystemGridWidget } from '@site/docs/widgets/beszel-system-grid';
import { beszelSystemTableWidget } from '@site/docs/widgets/beszel-system-table';
import { beszelAlertsWidget } from '@site/docs/widgets/beszel-alerts';
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 { beszelIntegration } from ".";
import { beszelSystemStatsWidget } from "@site/docs/widgets/beszel-system-stats";
import { beszelSystemGridWidget } from "@site/docs/widgets/beszel-system-grid";
import { beszelSystemTableWidget } from "@site/docs/widgets/beszel-system-table";
import { beszelAlertsWidget } from "@site/docs/widgets/beszel-alerts";
import beszelDashboard from './img/beszel-dashboard.png';
import beszelDashboard from "./img/beszel-dashboard.png";
<IntegrationHeader
integration={beszelIntegration}
categories={['System Monitoring']}
/>
<IntegrationHeader integration={beszelIntegration} categories={["System Monitoring"]} />
Beszel monitors your servers in real time via lightweight agents, collecting CPU, memory, disk, network, GPU, temperature, and Docker container metrics. It stores historical data and supports configurable alerts.
@@ -28,26 +25,33 @@ Beszel monitors your servers in real time via lightweight agents, collecting CPU
<img src={beszelDashboard} alt="Beszel dashboard overview showing all four widgets" />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: beszelSystemStatsWidget },
{ widget: beszelSystemGridWidget },
{ widget: beszelSystemTableWidget },
{ widget: beszelAlertsWidget },
]}
items={[
{ widget: beszelSystemStatsWidget },
{ widget: beszelSystemGridWidget },
{ widget: beszelSystemTableWidget },
{ widget: beszelAlertsWidget },
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [
'Open your Beszel hub instance (default port 8090)',
'Use the same credentials you use to log in to the Beszel web UI',
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [
"Open your Beszel hub instance (default port 8090)",
"Use the same credentials you use to log in to the Beszel web UI",
],
},
]}
/>
:::tip
Beszel uses PocketBase under the hood. The default admin credentials are set during the initial Beszel setup.
+37 -30
View File
@@ -1,29 +1,24 @@
---
title: 'Coolify'
description: 'Self-hosted PaaS and deployment platform'
title: "Coolify"
description: "Self-hosted PaaS and deployment platform"
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 { coolifyIntegration } from '.';
import { coolifyWidget } from '../../widgets/coolify';
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 { coolifyIntegration } from ".";
import { coolifyWidget } from "../../widgets/coolify";
<IntegrationHeader
integration={coolifyIntegration}
categories={['System monitoring', 'Deployment']}
/>
<IntegrationHeader integration={coolifyIntegration} categories={["System monitoring", "Deployment"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: coolifyWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: coolifyWidget }]} />
### Adding the integration
<AddingIntegration />
:::info URL configuration
@@ -31,16 +26,28 @@ Use the root URL of your Coolify instance, for example `https://coolify.example.
:::
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
'Open your Coolify instance and make sure you are in the team you want Homarr to monitor.',
(<span>Enable API access under <strong>Settings &gt; Advanced</strong> if it is disabled.</span>),
(<span>Go to <strong>Security &gt; API Tokens</strong>.</span>),
'Enter a name, e.g. "Homarr".',
(<span>Select the <code>read</code> permission. The Coolify widget only reads version, server, project, application, and service data.</span>),
'Click "Create".',
'Copy the generated token immediately. Coolify only shows it once.',
'Paste the token into the API Key field in Homarr.'
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open your Coolify instance and make sure you are in the team you want Homarr to monitor.",
<span>
Enable API access under <strong>Settings &gt; Advanced</strong> if it is disabled.
</span>,
<span>
Go to <strong>Security &gt; API Tokens</strong>.
</span>,
'Enter a name, e.g. "Homarr".',
<span>
Select the <code>read</code> permission. The Coolify widget only reads version, server, project, application,
and service data.
</span>,
'Click "Create".',
"Copy the generated token immediately. Coolify only shows it once.",
"Paste the token into the API Key field in Homarr.",
],
},
]}
/>
+20 -19
View File
@@ -1,32 +1,33 @@
---
title: 'Dash.'
title: "Dash."
description: "Dash. is a system performance and resource monitoring tool"
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 { 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 { IconHeartRateMonitor } from "@tabler/icons-react";
import { dashDotIntegration } from '.';
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { dashDotIntegration } from ".";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
<IntegrationHeader
integration={dashDotIntegration}
categories={['System monitoring']}
/>
<IntegrationHeader integration={dashDotIntegration} categories={["System monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: healthMonitoringWidget
}, {
widget: systemResourcesWidget
}]}
items={[
{
widget: healthMonitoringWidget,
},
{
widget: systemResourcesWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
<AddingIntegration />
+25 -20
View File
@@ -1,36 +1,41 @@
---
title: 'Deluge'
title: "Deluge"
description: "Deluge is a lightweight, Free Software, cross-platform BitTorrent client."
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 { 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 { IconDownload } from "@tabler/icons-react";
import Alert from '@theme/Admonition';
import { delugeIntegration } from '.';
import { downloadsWidget } from '@site/docs/widgets/downloads';
import Alert from "@theme/Admonition";
import { delugeIntegration } from ".";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={delugeIntegration}
categories={['Torrent client']}
/>
<IntegrationHeader integration={delugeIntegration} categories={["Torrent client"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: downloadsWidget
}]}
items={[
{
widget: downloadsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['password'],
steps: [],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["password"],
steps: [],
},
]}
/>
+29 -17
View File
@@ -1,32 +1,31 @@
---
title: 'Docker'
title: "Docker"
description: "Docker is a platform where you can run your applications in containers, allowing for easy deployment and management of applications."
hide_title: true
---
import { IntegrationHeader } from '@site/src/components/integrations/header';
import { IntegrationCapabilites } from '@site/src/components/integrations/widgets';
import {IntegrationSecrets} from '@site/src/components/integrations/secrets';
import { IntegrationHeader } from "@site/src/components/integrations/header";
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
import { IconBrandDocker, IconTool } from "@tabler/icons-react";
import { dockerIntegration } from '.';
import { dockerContainersWidget } from '@site/docs/widgets/docker-containers';
import { dockerIntegration } from ".";
import { dockerContainersWidget } from "@site/docs/widgets/docker-containers";
<IntegrationHeader
integration={dockerIntegration}
categories={['Containers']}
/>
<IntegrationHeader integration={dockerIntegration} categories={["Containers"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
items={[
{
widget: dockerContainersWidget,
note: "This widget can only be used with administrator privileges"
}]}
note: "This widget can only be used with administrator privileges",
},
]}
/>
## Enabling the Docker integration
This integration must first be enabled.
If you directly run on the host system and you have docker installed, it will be enabled by default.
Otherwise, you'll need to mount the [docker socket](https://docs.docker.com/engine/security/protect-access/) to the Homarr container,
@@ -49,7 +48,7 @@ services:
environment:
- SECRET_ENCRYPTION_KEY=your_64_character_hex_string # <--- can be generated with `openssl rand -hex 32`
ports:
- '7575:7575'
- "7575:7575"
```
With docker run, add this parameter: `-v /var/run/docker.sock:/var/run/docker.sock`.
@@ -124,8 +123,10 @@ services:
```
### Managing your Docker containers within Homarr
Homarr allows you to interact with Docker containers running on your system.
Each container row has an action menu with the following options:
- **View logs** - opens a dedicated logs page with a live terminal
- **Start** - start a stopped container
- **Stop** - stop a running container
@@ -166,11 +167,13 @@ Currently Homarr supports one label for configuration of the containers:
- **homarr.hide:** If set to any value, the container will be hidden from the Docker Containers widget and tools page.
### Security
Mounting docker sockets can be risky, as they permit full control over your docker service.
As an example, a thread actor could abuse Homarr use the socket to start, stop or delete containers on your system.
Therefore we recommend the usage of a socket proxy, which can prohibit certain actions.
A few examples include:
- https://github.com/linuxserver/docker-socket-proxy
- https://github.com/Tecnativa/docker-socket-proxy
@@ -178,36 +181,44 @@ See documentation of the respective proxies on how to configure them.
Homarr may behave in unexpected ways when you use proxies.
#### Permissions
Homarr needs the following permissions from the Docker API:
- Containers/Start
- Containers/Stop
- Containers/Restart
- Containers/Remove
For socket proxies, you will need these permissions:
- `CONTAINERS=1`
- `POST=1`
**Caution:** `POST` access is security critical as it provides extensive capabilities to modify your docker environment. Please leave it disabled if you're concerned about this.
As a workaround, you can use [LSIO's socket proxy](https://github.com/linuxserver/docker-socket-proxy) and set the following:
- ALLOW_START=1
- ALLOW_STOP=1
- ALLOW_RESTARTS=1
These will work even with `POST=0`.
These will work even with `POST=0`.
You lose the ability to remove containers, but start, stop and restarts should work just fine.
#### Connecting to Docker via Socket Proxies
To connect to Docker via a socket proxy, you'll need to add these two environment variables in the compose file:
- `DOCKER_HOSTNAMES=<name of the socket proxy container>`
- `DOCKER_PORTS=<socket proxy port, usually 2375>`
Refer: https://homarr.dev/docs/advanced/environment-variables/
You will also need to add Homarr to the network of your socket proxy. You can do it like this:
1. Add the network to your compose file (with appropriate changes):
```yaml
networks:
socket-proxy:
@@ -216,6 +227,7 @@ networks:
```
2. Add the network to the homarr service in the compose file:
```yaml
networks:
- socket-proxy
+21 -23
View File
@@ -1,37 +1,35 @@
---
title: 'Emby'
title: "Emby"
description: "Emby is a media server platform that allows you to organize, manage, and stream your personal media collection."
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 { 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 { IconVideo, IconTicket } from "@tabler/icons-react";
import { embyIntegration } from '.';
import { mediaServerWidget } from '@site/docs/widgets/media-server';
import { mediaReleasesWidget } from '@site/docs/widgets/media-releases';
import { embyIntegration } from ".";
import { mediaServerWidget } from "@site/docs/widgets/media-server";
import { mediaReleasesWidget } from "@site/docs/widgets/media-releases";
<IntegrationHeader
integration={embyIntegration}
categories={['Media server']}
/>
<IntegrationHeader integration={embyIntegration} categories={["Media server"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: mediaServerWidget },
{ widget: mediaReleasesWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: mediaServerWidget }, { widget: mediaReleasesWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+28 -22
View File
@@ -1,37 +1,43 @@
---
title: 'Glances'
title: "Glances"
description: "Glances is a cross-platform system monitoring tool."
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 { glancesIntegration } from '.';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
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 { glancesIntegration } from ".";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
<IntegrationHeader
integration={glancesIntegration}
categories={['System Monitoring']}
/>
<IntegrationHeader integration={glancesIntegration} categories={["System Monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: systemResourcesWidget
}, {
widget: healthMonitoringWidget
}]}
items={[
{
widget: systemResourcesWidget,
},
{
widget: healthMonitoringWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: [],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: [],
steps: [],
},
]}
/>
+31 -25
View File
@@ -1,20 +1,17 @@
---
title: 'Gluetun'
description: 'Connect Gluetun to Homarr as a VPN integration.'
title: "Gluetun"
description: "Connect Gluetun to Homarr as a VPN integration."
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 { gluetunIntegration } from '.';
import { vpnWidget } from '@site/docs/widgets/vpn';
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 { gluetunIntegration } from ".";
import { vpnWidget } from "@site/docs/widgets/vpn";
<IntegrationHeader
integration={gluetunIntegration}
categories={['VPN', 'Network']}
/>
<IntegrationHeader integration={gluetunIntegration} categories={["VPN", "Network"]} />
[Gluetun](https://github.com/qdm12/gluetun) exposes a control server that Homarr can query to report the VPN tunnel
status, DNS status, public IP address, and active provider details in the VPN widget.
@@ -22,9 +19,11 @@ status, DNS status, public IP address, and active provider details in the VPN wi
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: vpnWidget,
}]}
items={[
{
widget: vpnWidget,
},
]}
/>
### Setting up the Gluetun control server
@@ -40,13 +39,20 @@ Refer to the [Gluetun control server documentation](https://github.com/qdm12/glu
Gluetun's control server can be left unprotected or secured with either an API key or HTTP Basic authentication.
Choose the option that matches how your Gluetun instance integration is set up.
<IntegrationSecrets secrets={[{
credentials: [],
steps: [],
},{
credentials: ['username', 'password'],
steps: [],
},{
credentials: ['apiKey'],
steps: [],
},,]} />
<IntegrationSecrets
secrets={[
{
credentials: [],
steps: [],
},
{
credentials: ["username", "password"],
steps: [],
},
{
credentials: ["apiKey"],
steps: [],
},
,
]}
/>
+24 -18
View File
@@ -1,33 +1,39 @@
---
title: 'Gotify'
title: "Gotify"
description: "Gotify is a simple, self-hosted server for sending and receiving messages in real time."
hide_title: true
---
import { notificationsWidget } from '@site/docs/widgets/notifications';
import { AddingIntegration } from '@site/src/components/integrations/adding';
import { IntegrationHeader } from '@site/src/components/integrations/header';
import { IntegrationSecrets } from '@site/src/components/integrations/secrets';
import { IntegrationCapabilites } from '@site/src/components/integrations/widgets';
import { gotifyIntegration } from '.';
import { notificationsWidget } from "@site/docs/widgets/notifications";
import { AddingIntegration } from "@site/src/components/integrations/adding";
import { IntegrationHeader } from "@site/src/components/integrations/header";
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
import { gotifyIntegration } from ".";
<IntegrationHeader
integration={gotifyIntegration}
categories={['Notifications', 'Messaging']}
/>
<IntegrationHeader integration={gotifyIntegration} categories={["Notifications", "Messaging"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: notificationsWidget
}]}
items={[
{
widget: notificationsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
@@ -1,45 +1,51 @@
---
title: 'Home Assistant'
title: "Home Assistant"
description: "Home Assistant is an open-source home automation platform that focuses on privacy and local control, allowing you to automate and control your smart home devices."
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 { 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 { IconBinaryTree } from "@tabler/icons-react";
import { homeAssistantIntegration } from '.';
import { smartHomeEntityStateWidget } from '@site/docs/widgets/smart-home-entity-state';
import { smartHomeExecuteAutomationWidget } from '@site/docs/widgets/smart-home-execute-automation';
import { homeAssistantIntegration } from ".";
import { smartHomeEntityStateWidget } from "@site/docs/widgets/smart-home-entity-state";
import { smartHomeExecuteAutomationWidget } from "@site/docs/widgets/smart-home-execute-automation";
<IntegrationHeader
integration={homeAssistantIntegration}
categories={['Smart Home', 'Automation']}
/>
<IntegrationHeader integration={homeAssistantIntegration} categories={["Smart Home", "Automation"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: smartHomeEntityStateWidget
}, {
widget: smartHomeExecuteAutomationWidget,
}]}
items={[
{
widget: smartHomeEntityStateWidget,
},
{
widget: smartHomeExecuteAutomationWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Click on your profile in the bottom left corner of Home Assistant.",
"Switch to the Security tab.",
"Scroll down to the Long-lived access tokens section.",
"Click on the Create Token button.",
"Enter a name for the token (e.g., 'Homarr Integration') and click Create.",
"Copy the generated token and paste it into the Homarr integration settings.",
]
}]} />
],
},
]}
/>
+25 -19
View File
@@ -1,38 +1,44 @@
---
title: 'iCal'
title: "iCal"
description: "iCal is a standard for calendar data exchange, allowing users to share and manage calendar events across different platforms."
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 { 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 { IconZoomQuestion, IconChartBar, IconSearch } from "@tabler/icons-react";
import { icalIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { icalIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
<IntegrationHeader
integration={icalIntegration}
categories={['Calendar']}
/>
<IntegrationHeader integration={icalIntegration} categories={["Calendar"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: calendarWidget
}]}
items={[
{
widget: calendarWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['url'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["url"],
steps: [],
},
]}
/>
## Using the iCal integration
The iCal integration allows you to add external calendars to Homarr. Any calendar that provides a public iCal URL can be integrated, such as Google Calendar, Apple Calendar, or Outlook.
The iCal integration allows you to add external calendars to Homarr. Any calendar that provides a public iCal URL can be integrated, such as Google Calendar, Apple Calendar, or Outlook.
+15 -22
View File
@@ -1,36 +1,29 @@
---
title: 'Immich'
title: "Immich"
description: "Self-hosted photo and video management solution"
hide_title: true
---
import { immichAlbumCarouselWidget } from '../../widgets/immich-album-carousel';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 { immichIntegration } from '.';
import { immichServerStatsWidget } from '../../widgets/immich-server-stats';
import { immichAlbumCarouselWidget } from "../../widgets/immich-album-carousel";
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 { immichIntegration } from ".";
import { immichServerStatsWidget } from "../../widgets/immich-server-stats";
<IntegrationHeader
integration={immichIntegration}
categories={['Photo server']}
/>
<IntegrationHeader integration={immichIntegration} categories={["Photo server"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: immichAlbumCarouselWidget },
{ widget: immichServerStatsWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: immichAlbumCarouselWidget }, { widget: immichServerStatsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
@@ -59,6 +52,6 @@ import { immichServerStatsWidget } from '../../widgets/immich-server-stats';
</span>
),
'Create the integration in Homarr and copy the API key to there'
]
'Create the integration in Homarr and copy the API key to there'
]
}]} />
+25 -26
View File
@@ -1,40 +1,39 @@
---
title: 'Jellyfin'
title: "Jellyfin"
description: "Jellyfin is a free and open-source media server software that allows you to organize, manage, and share your media files."
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 { 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 { IconVideo, IconTicket } from "@tabler/icons-react";
import { jellyfinIntegration } from '.';
import { mediaServerWidget } from '@site/docs/widgets/media-server';
import { mediaReleasesWidget } from '@site/docs/widgets/media-releases';
import { jellyfinIntegration } from ".";
import { mediaServerWidget } from "@site/docs/widgets/media-server";
import { mediaReleasesWidget } from "@site/docs/widgets/media-releases";
<IntegrationHeader
integration={jellyfinIntegration}
categories={['Media server']}
/>
<IntegrationHeader integration={jellyfinIntegration} categories={["Media server"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: mediaServerWidget },
{ widget: mediaReleasesWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: mediaServerWidget }, { widget: mediaReleasesWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
},{
credentials: ['username', 'password'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
@@ -1,45 +1,52 @@
---
title: 'Jellyseerr'
title: "Jellyseerr"
description: "Jellyseerr is a self-hosted media request management system that integrates with Jellyfin and other media servers."
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 { 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 { IconZoomQuestion, IconChartBar, IconSearch } from "@tabler/icons-react";
import { jellyseerrIntegration } from '.';
import { mediaRequestListWidget } from '@site/docs/widgets/media-request-list';
import { mediaRequestStatsWidget } from '@site/docs/widgets/media-request-stats';
import { jellyseerrIntegration } from ".";
import { mediaRequestListWidget } from "@site/docs/widgets/media-request-list";
import { mediaRequestStatsWidget } from "@site/docs/widgets/media-request-stats";
<IntegrationHeader
integration={jellyseerrIntegration}
categories={['Media requests']}
/>
<IntegrationHeader integration={jellyseerrIntegration} categories={["Media requests"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: mediaRequestListWidget,
},{
widget: mediaRequestStatsWidget,
}, {
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search"
}
}]}
items={[
{
widget: mediaRequestListWidget,
},
{
widget: mediaRequestStatsWidget,
},
{
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search",
},
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
@@ -1,20 +1,16 @@
---
title: 'Kubernetes'
title: "Kubernetes"
description: "Kubernetes is a powerful container orchestration platform that automates the deployment, scaling, and management of containerized applications."
hide_title: true
---
import { IntegrationHeader } from '@site/src/components/integrations/header';
import { IntegrationCapabilites } from '@site/src/components/integrations/widgets';
import {IntegrationSecrets} from '@site/src/components/integrations/secrets';
import { IntegrationHeader } from "@site/src/components/integrations/header";
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
import { IconBrandDocker, IconTool } from "@tabler/icons-react";
import { kubernetesIntegration } from '.';
import { kubernetesIntegration } from ".";
<IntegrationHeader
integration={kubernetesIntegration}
categories={['Containers']}
/>
<IntegrationHeader integration={kubernetesIntegration} categories={["Containers"]} />
Homarr provides a user-friendly Kubernetes dashboard that offers an overview of your cluster’s resources in a clear and structured interface. It allows users to view key Kubernetes objects, including `Pods`, `Services`, `Ingresses`, `Nodes`, `ConfigMaps`, `Secrets`, `Namespaces`, and `Volumes`, as well as basic metrics when the Kubernetes Metrics Server is enabled.
@@ -47,7 +43,7 @@ Enabling RBAC in the Helm chart creates the necessary Kubernetes Role-Based Acce
- Service Account: A dedicated service account for Homarr.
- Role & RoleBinding: Grants permissions within a specific namespace to list, watch, and get pods, services, secrets, configmaps, and more.
- ClusterRole & ClusterRoleBinding: Extends the same permissions cluster-wide for additional flexibility.
:::
:::
### Homarr Dashboard Overview
+24 -19
View File
@@ -1,35 +1,40 @@
---
title: 'Lidarr'
title: "Lidarr"
description: "Lidarr is a music management tool that automates the process of downloading, sorting, and renaming music."
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 { 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 { IconCalendar } from "@tabler/icons-react";
import { lidarrIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { lidarrIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
<IntegrationHeader
integration={lidarrIntegration}
categories={['Media manager', "Servarr"]}
/>
<IntegrationHeader integration={lidarrIntegration} categories={["Media manager", "Servarr"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: calendarWidget
}]}
items={[
{
widget: calendarWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
@@ -1,5 +1,5 @@
---
title: 'Navidrome'
title: "Navidrome"
description: "Navidrome is a self-hosted music server and streamer compatible with the Subsonic API."
hide_title: true
---
@@ -21,13 +21,19 @@ Navidrome provides music library statistics including artist, album, and song co
<IntegrationCapabilites items={[{ widget: audioStatsWidget }, { widget: mediaServerWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [
'Use the same credentials you use to log in to Navidrome',
'The user must have access to the Subsonic API (enabled by default)',
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [
"Use the same credentials you use to log in to Navidrome",
"The user must have access to the Subsonic API (enabled by default)",
],
},
]}
/>
+29 -26
View File
@@ -1,40 +1,43 @@
---
title: 'Nextcloud'
title: "Nextcloud"
description: "Nextcloud is a self-hosted productivity platform that provides file storage, collaboration tools, and more."
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 { 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 { IconCalendar } from "@tabler/icons-react";
import Alert from '@theme/Admonition';
import { nextcloudIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { notificationsWidget } from '@site/docs/widgets/notifications';
import Alert from "@theme/Admonition";
import { nextcloudIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
import { notificationsWidget } from "@site/docs/widgets/notifications";
<IntegrationHeader
integration={nextcloudIntegration}
categories={['Calendar', 'Notifications']}
/>
<IntegrationHeader integration={nextcloudIntegration} categories={["Calendar", "Notifications"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: calendarWidget },
{ widget: notificationsWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: calendarWidget }, { widget: notificationsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [],
header: <Alert type="info">
Users who use 2FA will have to use Nextcloud's App Password tool to grant Homarr access, as 2FA breaks the traditional process. For more information, see [Nextcloud's Documentation](https://docs.nextcloud.com/server/stable/admin_manual/configuration_user/authentication.html#app-passwords)
</Alert>,
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
header: (
<Alert type="info">
Users who use 2FA will have to use Nextcloud's App Password tool to grant Homarr access, as 2FA breaks the
traditional process. For more information, see [Nextcloud's
Documentation](https://docs.nextcloud.com/server/stable/admin_manual/configuration_user/authentication.html#app-passwords)
</Alert>
),
},
]}
/>
+28 -21
View File
@@ -1,37 +1,44 @@
---
title: 'Ntfy'
title: "Ntfy"
description: "Ntfy is a simple, open-source notification service that allows you to send and receive notifications across devices."
hide_title: true
---
import { notificationsWidget } from '@site/docs/widgets/notifications';
import { AddingIntegration } from '@site/src/components/integrations/adding';
import { IntegrationHeader } from '@site/src/components/integrations/header';
import { IntegrationSecrets } from '@site/src/components/integrations/secrets';
import { IntegrationCapabilites } from '@site/src/components/integrations/widgets';
import { notificationsWidget } from "@site/docs/widgets/notifications";
import { AddingIntegration } from "@site/src/components/integrations/adding";
import { IntegrationHeader } from "@site/src/components/integrations/header";
import { IntegrationSecrets } from "@site/src/components/integrations/secrets";
import { IntegrationCapabilites } from "@site/src/components/integrations/widgets";
import { IconMessage } from "@tabler/icons-react";
import { ntfyIntegration } from '.';
import { ntfyIntegration } from ".";
<IntegrationHeader
integration={ntfyIntegration}
categories={['Notifications', 'Messaging']}
/>
<IntegrationHeader integration={ntfyIntegration} categories={["Notifications", "Messaging"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: notificationsWidget
}]}
items={[
{
widget: notificationsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['topic'],
steps: []
}, {
credentials: ['topic', 'apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["topic"],
steps: [],
},
{
credentials: ["topic", "apiKey"],
steps: [],
},
]}
/>
+25 -20
View File
@@ -1,36 +1,41 @@
---
title: 'NZBGet'
title: "NZBGet"
description: "NZBGet is a lightweight and efficient Usenet downloader."
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 { 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 { IconDownload } from "@tabler/icons-react";
import { nzbgetIntegration } from '.';
import Alert from '@theme/Admonition';
import { downloadsWidget } from '@site/docs/widgets/downloads';
import { nzbgetIntegration } from ".";
import Alert from "@theme/Admonition";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={nzbgetIntegration}
categories={['Usenet client']}
/>
<IntegrationHeader integration={nzbgetIntegration} categories={["Usenet client"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: downloadsWidget,
}]}
items={[
{
widget: downloadsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
@@ -1,42 +1,52 @@
---
title: 'Open Media Vault'
title: "Open Media Vault"
description: "Open Media Vault is a free network-attached storage server based on the Debian operating system."
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 { 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 { IconHeartRateMonitor } from "@tabler/icons-react";
import { openMediaVaultIntegration } from '.';
import Alert from '@theme/Admonition'
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { openMediaVaultIntegration } from ".";
import Alert from "@theme/Admonition";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
<IntegrationHeader
integration={openMediaVaultIntegration}
categories={['System monitoring']}
/>
<IntegrationHeader integration={openMediaVaultIntegration} categories={["System monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: healthMonitoringWidget,
note: "To use this widget, you must have the OpenMediaVault plugin openmediavault-cputemp installed.",
}, {
widget: systemResourcesWidget
}]}
items={[
{
widget: healthMonitoringWidget,
note: "To use this widget, you must have the OpenMediaVault plugin openmediavault-cputemp installed.",
},
{
widget: systemResourcesWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [],
body: <Alert type="caution">
The user used here must have administrative permissions or Homarr won't be able to read the system performance and resource data.
</Alert>
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
body: (
<Alert type="caution">
The user used here must have administrative permissions or Homarr won't be able to read the system performance
and resource data.
</Alert>
),
},
]}
/>
+47 -37
View File
@@ -1,65 +1,75 @@
---
title: 'OPNsense'
title: "OPNsense"
description: "OPNsense is an open-source, easy-to-use, and easy-to-build firewall and routing platform."
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 { 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 { IconHeartRateMonitor } from "@tabler/icons-react";
import { opnsenseIntegration } from '.';
import Alert from '@theme/Admonition'
import { firewallWidget } from '../../widgets/firewall';
import { opnsenseIntegration } from ".";
import Alert from "@theme/Admonition";
import { firewallWidget } from "../../widgets/firewall";
<IntegrationHeader
integration={opnsenseIntegration}
categories={['Firewall']}
/>
<IntegrationHeader integration={opnsenseIntegration} categories={["Firewall"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: firewallWidget,
}]}
items={[
{
widget: firewallWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
tabLabel: "ApiKey (Key & Secret)",
credentials: ['opnsenseApiKey', 'opnsenseApiSecret'],
header: <Alert type="info">
This integration does not require full API access to the firewall. The following guide outlines the process for creating a restricted OPNsense user with a scrambled password, designed exclusively for API access. This ensures minimal permissions and prevents local login capability.
</Alert>,
steps: [
<IntegrationSecrets
secrets={[
{
tabLabel: "ApiKey (Key & Secret)",
credentials: ["opnsenseApiKey", "opnsenseApiSecret"],
header: (
<Alert type="info">
This integration does not require full API access to the firewall. The following guide outlines the process
for creating a restricted OPNsense user with a scrambled password, designed exclusively for API access. This
ensures minimal permissions and prevents local login capability.
</Alert>
),
steps: [
"Log in to the OPNsense web interface as an administrator",
"Navigate to System → Access → Users",
"Click the + (Add) button to create a new user",
<>
Fill in the user details:
<ul>
<li>Username: Enter a unique name</li>
<li>Password: Leave empty</li>
<li>Scrambled Password: Enable this option</li>
<li>Full name: (Optional) Add a descriptive name</li>
</ul>
Fill in the user details:
<ul>
<li>Username: Enter a unique name</li>
<li>Password: Leave empty</li>
<li>Scrambled Password: Enable this option</li>
<li>Full name: (Optional) Add a descriptive name</li>
</ul>
</>,
<>
In Privileges section → Select the option below:
<ul>
<li>Lobby: Dashboard</li>
<li>Reporting: Traffic</li>
</ul>
In Privileges section → Select the option below:
<ul>
<li>Lobby: Dashboard</li>
<li>Reporting: Traffic</li>
</ul>
</>,
"Click Save",
"Return to the Users list",
"Find the user and click the ticket icon in the Commands column",
"Click Yes in the popup to confirm",
"A txt file will download automatically, containing: Key and Secret",
"Save this file securely—this information will only be shown once"
],
}]} />
"Save this file securely—this information will only be shown once",
],
},
]}
/>
+36 -29
View File
@@ -1,45 +1,52 @@
---
title: 'Overseerr'
title: "Overseerr"
description: "Overseerr is a self-hosted media request management system that integrates with Plex."
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 { 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 { IconZoomQuestion, IconChartBar, IconSearch } from "@tabler/icons-react";
import { overseerrIntegration } from '.';
import { mediaRequestListWidget } from '@site/docs/widgets/media-request-list';
import { mediaRequestStatsWidget } from '@site/docs/widgets/media-request-stats';
import { overseerrIntegration } from ".";
import { mediaRequestListWidget } from "@site/docs/widgets/media-request-list";
import { mediaRequestStatsWidget } from "@site/docs/widgets/media-request-stats";
<IntegrationHeader
integration={overseerrIntegration}
categories={['Media requests']}
/>
<IntegrationHeader integration={overseerrIntegration} categories={["Media requests"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: mediaRequestListWidget
}, {
widget: mediaRequestStatsWidget
}, {
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search"
}
}]}
items={[
{
widget: mediaRequestListWidget,
},
{
widget: mediaRequestStatsWidget,
},
{
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search",
},
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
@@ -1,41 +1,40 @@
---
title: 'Paperless-ngx'
title: "Paperless-ngx"
description: "Paperless-ngx is a document management system that transforms your physical documents into a searchable online archive."
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 { paperlessNgxIntegration } from '.';
import { paperlessNgxWidget } from '@site/docs/widgets/paperless-ngx';
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 { paperlessNgxIntegration } from ".";
import { paperlessNgxWidget } from "@site/docs/widgets/paperless-ngx";
<IntegrationHeader
integration={paperlessNgxIntegration}
categories={['Documents']}
/>
<IntegrationHeader integration={paperlessNgxIntegration} categories={["Documents"]} />
Paperless-ngx provides document statistics including total documents, inbox count, correspondents, tags, and document types.
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: paperlessNgxWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: paperlessNgxWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
'Open your Paperless-ngx instance',
'Navigate to Settings → Django Admin → Tokens',
'Create a new token for your user',
'Copy the token value',
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open your Paperless-ngx instance",
"Navigate to Settings → Django Admin → Tokens",
"Create a new token for your user",
"Copy the token value",
],
},
]}
/>
+25 -26
View File
@@ -1,43 +1,42 @@
---
title: 'PatchMon'
title: "PatchMon"
description: "PatchMon is a patch management and monitoring solution for Linux hosts."
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 { patchmonIntegration } from '.';
import { patchmonWidget } from '@site/docs/widgets/patchmon';
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 { patchmonIntegration } from ".";
import { patchmonWidget } from "@site/docs/widgets/patchmon";
<IntegrationHeader
integration={patchmonIntegration}
categories={['Health Monitoring']}
/>
<IntegrationHeader integration={patchmonIntegration} categories={["Health Monitoring"]} />
PatchMon provides host and package update statistics including total hosts, hosts needing updates, and security update counts.
The PatchMon widget requires users to be **signed in to Homarr**; see the [PatchMon widget documentation](/docs/widgets/patchmon#authentication) for details on authentication and public boards.
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: patchmonWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: patchmonWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['patchmonApiKey', 'patchmonApiSecret'],
steps: [
'Open your PatchMon instance',
'Navigate to Settings and create a new GetHomepage API key',
'Copy the API key and secret from the success dialog',
'Paste them into Homarr — Basic authentication is handled automatically',
]
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["patchmonApiKey", "patchmonApiSecret"],
steps: [
"Open your PatchMon instance",
"Navigate to Settings and create a new GetHomepage API key",
"Copy the API key and secret from the success dialog",
"Paste them into Homarr — Basic authentication is handled automatically",
],
},
]}
/>
+31 -26
View File
@@ -1,48 +1,53 @@
---
title: 'PeaNUT'
description: 'A tiny dashboard for Network UPS Tools (NUT) servers.'
title: "PeaNUT"
description: "A tiny dashboard for Network UPS Tools (NUT) servers."
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 { peaNutIntegration } from '.';
import { upsWidget } from '@site/docs/widgets/ups';
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 { peaNutIntegration } from ".";
import { upsWidget } from "@site/docs/widgets/ups";
<IntegrationHeader
integration={peaNutIntegration}
categories={['UPS', 'Hardware']}
/>
<IntegrationHeader integration={peaNutIntegration} categories={["UPS", "Hardware"]} />
[PeaNUT](https://github.com/Brandawg93/PeaNUT) exposes the data of your [Network UPS Tools](https://networkupstools.org/) servers
over a REST API, which Homarr reads to display the status of your UPS devices.
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
items={[
{
widget: upsWidget,
}]}
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
PeaNUT secures its API with HTTP Basic authentication when the `WEB_USERNAME` and `WEB_PASSWORD` environment variables
are set on the PeaNUT instance. Provide the same credentials here. If the instance runs with `AUTH_DISABLED=true`, no
secrets are required.
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [
"Set WEB_USERNAME and WEB_PASSWORD on your PeaNUT instance.",
"Create an integration in Homarr with the PeaNUT URL and those credentials.",
],
},{
credentials: [],
steps: [
"If PeaNUT runs with AUTH_DISABLED=true, create the integration with no credentials.",
],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [
"Set WEB_USERNAME and WEB_PASSWORD on your PeaNUT instance.",
"Create an integration in Homarr with the PeaNUT URL and those credentials.",
],
},
{
credentials: [],
steps: ["If PeaNUT runs with AUTH_DISABLED=true, create the integration with no credentials."],
},
]}
/>
+36 -29
View File
@@ -1,47 +1,54 @@
---
title: 'Pi-hole'
title: "Pi-hole"
description: "Pi-hole is a network-wide ad blocker that acts as a DNS sinkhole, blocking unwanted content and improving your browsing experience."
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 { 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 { IconAd, IconDeviceGamepad } from "@tabler/icons-react";
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 '.';
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 ".";
<IntegrationHeader integration={piHoleIntegration} categories={["DNS Hole"]} />
<IntegrationHeader
integration={piHoleIntegration}
categories={['DNS Hole']}
/>
<Alert type="note" className='my-2'>
Homarr supports both Pi-hole v5 and v6. It automatically detects the version and uses the correct API.
<Alert type="note" className="my-2">
Homarr supports both Pi-hole v5 and v6. It automatically detects the version and uses the correct API.
</Alert>
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: dnsHoleSummaryWidget,
},{
widget: dnsHoleControlsWidget
}]}
items={[
{
widget: dnsHoleSummaryWidget,
},
{
widget: dnsHoleControlsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [],
body: "Please note, that in v6 of Pi-hole you no longer specify an API key, but instead either a password or application password. We suggest to use the application password when possible."
}, {
credentials: [],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
body: "Please note, that in v6 of Pi-hole you no longer specify an API key, but instead either a password or application password. We suggest to use the application password when possible.",
},
{
credentials: [],
steps: [],
},
]}
/>
+32 -26
View File
@@ -1,41 +1,47 @@
---
title: 'Plex'
title: "Plex"
description: "Plex is a media server platform that allows you to organize, manage, and stream your personal media collection."
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 { 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 { IconVideo, IconTicket } from "@tabler/icons-react";
import { plexIntegration } from '.';
import { mediaServerWidget } from '@site/docs/widgets/media-server';
import { mediaReleasesWidget } from '@site/docs/widgets/media-releases';
import { plexIntegration } from ".";
import { mediaServerWidget } from "@site/docs/widgets/media-server";
import { mediaReleasesWidget } from "@site/docs/widgets/media-releases";
<IntegrationHeader
integration={plexIntegration}
categories={['Media server']}
/>
<IntegrationHeader integration={plexIntegration} categories={["Media server"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: mediaServerWidget },
{ widget: mediaReleasesWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: mediaServerWidget }, { widget: mediaReleasesWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
<span>
Follow the official <a href="https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/" target="_blank" rel="noopener noreferrer">Plex documentation</a> to find your authentication token.
</span>
]
}]} />
Follow the official{" "}
<a
href="https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/"
target="_blank"
rel="noopener noreferrer"
>
Plex documentation
</a>{" "}
to find your authentication token.
</span>,
],
},
]}
/>
+20 -18
View File
@@ -1,32 +1,34 @@
---
title: 'Prowlarr'
title: "Prowlarr"
description: "Prowlarr is an indexer manager for Usenet and BitTorrent, providing a unified interface to manage your indexers."
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 { 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 { IconHeartRateMonitor } from "@tabler/icons-react";
import { prowlarrIntegration } from '.';
import { indexerManagerWidget } from '@site/docs/widgets/indexer-manager';
import { prowlarrIntegration } from ".";
import { indexerManagerWidget } from "@site/docs/widgets/indexer-manager";
<IntegrationHeader
integration={prowlarrIntegration}
categories={['Indexer']}
/>
<IntegrationHeader integration={prowlarrIntegration} categories={["Indexer"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: indexerManagerWidget }]}
/>
<IntegrationCapabilites items={[{ widget: indexerManagerWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+70 -66
View File
@@ -1,103 +1,107 @@
---
title: 'Proxmox'
title: "Proxmox"
description: "Proxmox is a powerful open-source virtualization platform that allows you to run virtual machines and containers."
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 { 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 { IconHeartRateMonitor } from "@tabler/icons-react";
import { proxmoxIntegration } from '.';
import Alert from '@theme/Admonition'
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { proxmoxIntegration } from ".";
import Alert from "@theme/Admonition";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
<IntegrationHeader
integration={proxmoxIntegration}
categories={['System monitoring']}
/>
<IntegrationHeader integration={proxmoxIntegration} categories={["System monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: healthMonitoringWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: healthMonitoringWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
header: <Alert type="caution">
The Proxmox API may not work with Linux PAM standard authentication. It is strongly recommended to use the Proxmox VE authentication server realm when creating your API user.
</Alert>,
credentials: ['username', 'tokenId', 'realm', 'apiKey'],
steps: [
<IntegrationSecrets
secrets={[
{
header: (
<Alert type="caution">
The Proxmox API may not work with Linux PAM standard authentication. It is strongly recommended to use the
Proxmox VE authentication server realm when creating your API user.
</Alert>
),
credentials: ["username", "tokenId", "realm", "apiKey"],
steps: [
"Navigate to the Proxmox portal, click on Datacenter",
"Expand Permissions, click on Groups",
"Click the Create button",
"Name the group something informative, like api-users",
"Click on the Permissions 'folder'",
<>
Click Add {"->"} Group Permission
<ul>
<li>Path: /</li>
<li>Group: group from Step 4 above</li>
<li>Role: PVEAuditor</li>
<li>Propagate: Checked</li>
</ul>
Click Add {"->"} Group Permission
<ul>
<li>Path: /</li>
<li>Group: group from Step 4 above</li>
<li>Role: PVEAuditor</li>
<li>Propagate: Checked</li>
</ul>
</>,
"Expand Permissions, click on Users",
<>
Click the Add button
<ul>
<li>User name: something informative like api</li>
<li>Realm: Proxmox VE authentication server</li>
<li>Password: create a secure password for the user</li>
<li>Confirm Password: re-enter the password</li>
<li>Group: group from Step 4 above</li>
</ul>
Click the Add button
<ul>
<li>User name: something informative like api</li>
<li>Realm: Proxmox VE authentication server</li>
<li>Password: create a secure password for the user</li>
<li>Confirm Password: re-enter the password</li>
<li>Group: group from Step 4 above</li>
</ul>
</>,
"Expand Permissions, click on API Tokens",
<>
Click the Add button
<ul>
<li>User: user from Step 8 above</li>
<li>Token ID: something informative like the application or purpose like homarr</li>
<li>Privilege Separation: unchecked</li>
</ul>
Click the Add button
<ul>
<li>User: user from Step 8 above</li>
<li>Token ID: something informative like the application or purpose like homarr</li>
<li>Privilege Separation: unchecked</li>
</ul>
</>,
"Copy the Secret that is shown in Step 10 because it is only shown once",
"Go back to the 'Permissions' menu",
<>
Click Add {"->"} API Token Permission
<ul>
<li>Path: /</li>
<li>API Token: select the API token created in Step 10</li>
<li>Role: PVE Auditor</li>
<li>Propagate: Checked</li>
</ul>
Click Add {"->"} API Token Permission
<ul>
<li>Path: /</li>
<li>API Token: select the API token created in Step 10</li>
<li>Role: PVE Auditor</li>
<li>Propagate: Checked</li>
</ul>
</>,
],
body: <>
<span>
Sometimes you'll also find the <code>api@pve!homarr</code> format,
within Homarr you'll have to split it up into:
</span>
<ul>
],
body: (
<>
<span>
Sometimes you'll also find the <code>api@pve!homarr</code> format, within Homarr you'll have to split it up
into:
</span>
<ul>
<li>
<b>Username:</b> api
<b>Username:</b> api
</li>
<li>
<b>Realm:</b> pve
<b>Realm:</b> pve
</li>
<li>
<b>Token ID:</b> homarr
<b>Token ID:</b> homarr
</li>
</ul>
</>
}]} />
</ul>
</>
),
},
]}
/>
@@ -1,37 +1,39 @@
---
title: 'qBittorrent'
title: "qBittorrent"
description: "qBittorrent is a free and open-source BitTorrent client."
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 { 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 { IconDownload } from "@tabler/icons-react";
import { qBittorentIntegration } from '.';
import Alert from '@theme/Admonition';
import { downloadsWidget } from '@site/docs/widgets/downloads';
import { qBittorentIntegration } from ".";
import Alert from "@theme/Admonition";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={qBittorentIntegration}
categories={['Torrent client']}
/>
<IntegrationHeader integration={qBittorentIntegration} categories={["Torrent client"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: downloadsWidget }]}
/>
<IntegrationCapabilites items={[{ widget: downloadsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
},{
credentials: ['username', 'password'],
steps: [],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
+20 -19
View File
@@ -1,33 +1,34 @@
---
title: 'Radarr'
title: "Radarr"
description: "Radarr is a movie management tool that automates the process of downloading, sorting, and renaming movies."
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 { 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 { IconCalendar } from "@tabler/icons-react";
import { radarrIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { radarrIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
<IntegrationHeader
integration={radarrIntegration}
categories={['Media manager', "Servarr"]}
/>
<IntegrationHeader integration={radarrIntegration} categories={["Media manager", "Servarr"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: calendarWidget }]}
/>
<IntegrationCapabilites items={[{ widget: calendarWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+20 -19
View File
@@ -1,33 +1,34 @@
---
title: 'Readarr'
title: "Readarr"
description: "Readarr is a book management tool that automates the process of downloading, sorting, and renaming books."
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 { 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 { IconCalendar } from "@tabler/icons-react";
import { readarrIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { readarrIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
<IntegrationHeader
integration={readarrIntegration}
categories={['Media manager', "Servarr"]}
/>
<IntegrationHeader integration={readarrIntegration} categories={["Media manager", "Servarr"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: calendarWidget }]}
/>
<IntegrationCapabilites items={[{ widget: calendarWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+21 -20
View File
@@ -1,34 +1,35 @@
---
title: 'SABnzbd'
title: "SABnzbd"
description: "SABnzbd is an Open Source Binary Newsreader."
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 { 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 { IconDownload } from "@tabler/icons-react";
import { sabnzbdIntegration } from '.';
import Alert from '@theme/Admonition';
import { downloadsWidget } from '@site/docs/widgets/downloads';
import { sabnzbdIntegration } from ".";
import Alert from "@theme/Admonition";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={sabnzbdIntegration}
categories={['Usenet client']}
/>
<IntegrationHeader integration={sabnzbdIntegration} categories={["Usenet client"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: downloadsWidget}]}
/>
<IntegrationCapabilites items={[{ widget: downloadsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+36 -29
View File
@@ -1,45 +1,52 @@
---
title: 'Seerr'
title: "Seerr"
description: "Seerr is a self-hosted media request management system that integrates with various media servers."
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 { 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 { IconZoomQuestion, IconChartBar, IconSearch } from "@tabler/icons-react";
import { seerrIntegration } from '.';
import { mediaRequestListWidget } from '@site/docs/widgets/media-request-list';
import { mediaRequestStatsWidget } from '@site/docs/widgets/media-request-stats';
import { seerrIntegration } from ".";
import { mediaRequestListWidget } from "@site/docs/widgets/media-request-list";
import { mediaRequestStatsWidget } from "@site/docs/widgets/media-request-stats";
<IntegrationHeader
integration={seerrIntegration}
categories={['Media requests']}
/>
<IntegrationHeader integration={seerrIntegration} categories={["Media requests"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: mediaRequestListWidget
}, {
widget: mediaRequestStatsWidget
}, {
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search"
}
}]}
items={[
{
widget: mediaRequestListWidget,
},
{
widget: mediaRequestStatsWidget,
},
{
capability: {
icon: IconSearch,
name: "Media Search",
description: "Search for movies and TV shows directly from Spotlight and request them.",
path: "../../management/search-engines/#media-request-search",
},
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+24 -19
View File
@@ -1,34 +1,39 @@
---
title: 'Slskd'
title: "Slskd"
description: "A modern client-server application for the Soulseek file sharing network."
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 { slskdIntegration } from '.';
import { downloadsWidget } from '@site/docs/widgets/downloads';
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 { slskdIntegration } from ".";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={slskdIntegration}
categories={['System Monitoring']}
/>
<IntegrationHeader integration={slskdIntegration} categories={["System Monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: downloadsWidget
}]}
items={[
{
widget: downloadsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ["apiKey"],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
+20 -19
View File
@@ -1,33 +1,34 @@
---
title: 'Sonarr'
title: "Sonarr"
description: "Sonarr is a TV series management tool that automates the process of downloading, sorting, and renaming episodes."
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 { 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 { IconCalendar } from "@tabler/icons-react";
import { sonarrIntegration } from '.';
import { calendarWidget } from '@site/docs/widgets/calendar';
import { sonarrIntegration } from ".";
import { calendarWidget } from "@site/docs/widgets/calendar";
<IntegrationHeader
integration={sonarrIntegration}
categories={['Media manager', "Servarr"]}
/>
<IntegrationHeader integration={sonarrIntegration} categories={["Media manager", "Servarr"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: calendarWidget }]}
/>
<IntegrationCapabilites items={[{ widget: calendarWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
@@ -1,34 +1,39 @@
---
title: 'Speedtest Tracker'
description: 'Speedtest Tracker is a self-hosted internet performance tracking application.'
title: "Speedtest Tracker"
description: "Speedtest Tracker is a self-hosted internet performance tracking application."
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 { speedtestTrackerIntegration } from '.';
import { speedtestTrackerWidget } from '@site/docs/widgets/speedtest-tracker';
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 { speedtestTrackerIntegration } from ".";
import { speedtestTrackerWidget } from "@site/docs/widgets/speedtest-tracker";
<IntegrationHeader
integration={speedtestTrackerIntegration}
categories={['Speedtest']}
/>
<IntegrationHeader integration={speedtestTrackerIntegration} categories={["Speedtest"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: speedtestTrackerWidget
}]}
items={[
{
widget: speedtestTrackerWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
]}
/>
@@ -19,11 +19,7 @@ import Alert from "@theme/Admonition";
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: healthMonitoringWidget },
{ widget: systemResourcesWidget },
{ widget: systemDisksWidget },
]}
items={[{ widget: healthMonitoringWidget }, { widget: systemResourcesWidget }, { widget: systemDisksWidget }]}
/>
### Supported metrics
+24 -22
View File
@@ -1,36 +1,38 @@
---
title: 'Tdarr'
title: "Tdarr"
description: "Tdarr is a distributed media transcoding system that allows you to process and optimize your media files across multiple nodes."
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 { 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 { IconTransform } from "@tabler/icons-react";
import { tdarrIntegration } from '.';
import { mediaTranscodingWidget } from '@site/docs/widgets/media-transcoding';
import { tdarrIntegration } from ".";
import { mediaTranscodingWidget } from "@site/docs/widgets/media-transcoding";
<IntegrationHeader
integration={tdarrIntegration}
categories={['Media Transcoding']}
/>
<IntegrationHeader integration={tdarrIntegration} categories={["Media Transcoding"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: mediaTranscodingWidget }]}
/>
<IntegrationCapabilites items={[{ widget: mediaTranscodingWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: []
}, {
credentials: [],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [],
},
{
credentials: [],
steps: [],
},
]}
/>
@@ -1,62 +1,72 @@
---
title: 'Technitium DNS'
title: "Technitium DNS"
description: "Technitium DNS Server is a self-hosted DNS server with ad-blocking and network-wide filtering capabilities."
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 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';
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 { technitiumDnsIntegration } from ".";
import { dnsHoleSummaryWidget } from "@site/docs/widgets/dns-hole-summary";
import { dnsHoleControlsWidget } from "@site/docs/widgets/dns-hole-controls";
<IntegrationHeader
integration={technitiumDnsIntegration}
categories={['DNS Hole']}
/>
<IntegrationHeader integration={technitiumDnsIntegration} categories={["DNS Hole"]} />
<Alert type="note" className='my-2'>
Homarr supports Technitium DNS v11 and above. The correct API version is detected automatically - no manual configuration is required.
<Alert type="note" className="my-2">
Homarr supports Technitium DNS v11 and above. The correct API version is detected automatically - no manual
configuration is required.
</Alert>
### Widgets & Capabilities
<IntegrationCapabilites
items={[{
widget: dnsHoleSummaryWidget,
},{
widget: dnsHoleControlsWidget
}]}
items={[
{
widget: dnsHoleSummaryWidget,
},
{
widget: dnsHoleControlsWidget,
},
]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<Alert type="info" className='my-2'>
The **API token** option is recommended. API tokens are non-expiring and do not require storing your admin password in Homarr.
Username and password authentication uses a session token that expires after inactivity, triggering a silent re-login on the next request.
<Alert type="info" className="my-2">
The **API token** option is recommended. API tokens are non-expiring and do not require storing your admin password in
Homarr. Username and password authentication uses a session token that expires after inactivity, triggering a silent
re-login on the next request.
</Alert>
<Alert type="warning" className='my-2'>
The **DNS Hole Controls** widget (enabling, disabling, and timed disabling of blocking) requires the token to have settings-level permissions.
The **DNS Hole Summary** widget (stats only) works with any valid token.
If Homarr cannot read the blocking status due to insufficient permissions, the status indicator will be hidden but statistics will still be shown.
<Alert type="warning" className="my-2">
The **DNS Hole Controls** widget (enabling, disabling, and timed disabling of blocking) requires the token to have
settings-level permissions. The **DNS Hole Summary** widget (stats only) works with any valid token. If Homarr cannot
read the blocking status due to insufficient permissions, the status indicator will be hidden but statistics will
still be shown.
</Alert>
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Open the Technitium DNS web console and sign in.",
"Click on your username in the top-right corner and select \"Create API Token\".",
"Give the token a name (e.g. \"Homarr\") and click \"Create Token\".",
"Copy the generated token and paste it into the API Key field in Homarr."
]
}, {
credentials: ['username', 'password'],
steps: [],
body: "Enter your Technitium DNS admin credentials. Homarr will exchange them for a session token and transparently re-authenticate when the session expires."
}]} />
'Click on your username in the top-right corner and select "Create API Token".',
'Give the token a name (e.g. "Homarr") and click "Create Token".',
"Copy the generated token and paste it into the API Key field in Homarr.",
],
},
{
credentials: ["username", "password"],
steps: [],
body: "Enter your Technitium DNS admin credentials. Homarr will exchange them for a session token and transparently re-authenticate when the session expires.",
},
]}
/>
+23 -24
View File
@@ -1,38 +1,37 @@
---
title: 'Tracearr'
title: "Tracearr"
description: "Tracearr is a comprehensive media monitoring solution that tracks streams, user activity, and policy violations in your media server (including Plex, Jellyfin, Emby)."
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 { tracearrIntegration } from '.';
import { tracearrWidget } from '@site/docs/widgets/tracearr';
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 { tracearrIntegration } from ".";
import { tracearrWidget } from "@site/docs/widgets/tracearr";
<IntegrationHeader
integration={tracearrIntegration}
categories={['Media Monitoring']}
/>
<IntegrationHeader integration={tracearrIntegration} categories={["Media Monitoring"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: tracearrWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: tracearrWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
<span>
In Tracearr, go to <strong>Settings → API</strong> and generate or copy your API key.
</span>
]
}]} />
In Tracearr, go to <strong>Settings → API</strong> and generate or copy your API key.
</span>,
],
},
]}
/>
@@ -1,34 +1,35 @@
---
title: 'Transmission'
title: "Transmission"
description: "A Fast, Easy and Free Bittorrent Client."
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 { 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 { IconDownload } from "@tabler/icons-react";
import { transmissionIntegration } from '.';
import Alert from '@theme/Admonition';
import { downloadsWidget } from '@site/docs/widgets/downloads';
import { transmissionIntegration } from ".";
import Alert from "@theme/Admonition";
import { downloadsWidget } from "@site/docs/widgets/downloads";
<IntegrationHeader
integration={transmissionIntegration}
categories={['Torrent client']}
/>
<IntegrationHeader integration={transmissionIntegration} categories={["Torrent client"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[{ widget: downloadsWidget }]}
/>
<IntegrationCapabilites items={[{ widget: downloadsWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: [],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
+47 -41
View File
@@ -1,61 +1,67 @@
---
title: 'TrueNAS'
title: "TrueNAS"
description: "Enterprise network-attached storage for your home, office, and cloud."
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 { truenasIntegration } from '.';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
import Alert from '@theme/Admonition';
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 { truenasIntegration } from ".";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
import Alert from "@theme/Admonition";
<IntegrationHeader
integration={truenasIntegration}
categories={['NAS', 'Hardware']}
/>
<IntegrationHeader integration={truenasIntegration} categories={["NAS", "Hardware"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: healthMonitoringWidget },
{ widget: systemResourcesWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: healthMonitoringWidget }, { widget: systemResourcesWidget }]} />
### Adding the integration
<AddingIntegration />
<Alert type="info" title="Use the HTTPS address">
TrueNAS only serves its API over HTTPS, so enter the <code>https://</code> URL of your TrueNAS web interface. If it uses a self-signed certificate (the default), add it under <a href="/docs/management/certificates">Management &gt; Tools &gt; Certificates</a> so Homarr can establish the connection.
TrueNAS only serves its API over HTTPS, so enter the <code>https://</code> URL of your TrueNAS web interface. If it
uses a self-signed certificate (the default), add it under{" "}
<a href="/docs/management/certificates">Management &gt; Tools &gt; Certificates</a> so Homarr can establish the
connection.
</Alert>
### Secrets
<IntegrationSecrets secrets={[
<IntegrationSecrets
secrets={[
{
credentials: ['apiKey'],
header: <Alert type="tip" title="Recommended">
API key authentication is the recommended method. It works across current TrueNAS versions and does not depend on user group membership.
</Alert>,
steps: [
"In the TrueNAS web interface, click your user avatar in the top-right corner and select \"API Keys\".",
"Click \"Add\", give the key a name such as \"Homarr\", and confirm.",
"Copy the generated key immediately - TrueNAS only shows it once - and paste it as the API Key when creating the integration in Homarr.",
],
credentials: ["apiKey"],
header: (
<Alert type="tip" title="Recommended">
API key authentication is the recommended method. It works across current TrueNAS versions and does not depend
on user group membership.
</Alert>
),
steps: [
'In the TrueNAS web interface, click your user avatar in the top-right corner and select "API Keys".',
'Click "Add", give the key a name such as "Homarr", and confirm.',
"Copy the generated key immediately - TrueNAS only shows it once - and paste it as the API Key when creating the integration in Homarr.",
],
},
{
credentials: ['username', 'password'],
steps: [
"In the TrueNAS web interface, go to \"Credentials\" > \"Users\" > \"Add\" and create a user with a secure password.",
"Grant the user administrative access so Homarr can read system, pool, and reporting data.",
"Save the user and create the integration in Homarr with these credentials.",
],
body: <Alert type="caution" title="Administrative access required">
The account must have administrative API access. The <code>auxiliary_administrator</code> group was removed in TrueNAS 25.10; on that version or newer, use API key authentication instead, or assign the user a full-admin role.
</Alert>,
credentials: ["username", "password"],
steps: [
'In the TrueNAS web interface, go to "Credentials" > "Users" > "Add" and create a user with a secure password.',
"Grant the user administrative access so Homarr can read system, pool, and reporting data.",
"Save the user and create the integration in Homarr with these credentials.",
],
body: (
<Alert type="caution" title="Administrative access required">
The account must have administrative API access. The <code>auxiliary_administrator</code> group was removed in
TrueNAS 25.10; on that version or newer, use API key authentication instead, or assign the user a full-admin
role.
</Alert>
),
},
]} />
]}
/>
+36 -37
View File
@@ -1,53 +1,52 @@
---
title: 'Umami'
description: 'Privacy-focused, open-source web analytics'
title: "Umami"
description: "Privacy-focused, open-source web analytics"
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 { umamiIntegration } from '.';
import { umamiWidget } from '../../widgets/umami';
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 { umamiIntegration } from ".";
import { umamiWidget } from "../../widgets/umami";
<IntegrationHeader
integration={umamiIntegration}
categories={['Analytics']}
/>
<IntegrationHeader integration={umamiIntegration} categories={["Analytics"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: umamiWidget }
]}
/>
<IntegrationCapabilites items={[{ widget: umamiWidget }]} />
### Adding the integration
<AddingIntegration />
:::tip URL configuration
- **Umami Cloud:** Use `https://api.umami.is/v1`
- **Self-hosted:** Use `http://your-umami-host:3000/api`
:::
:::
### Secrets
<IntegrationSecrets secrets={[
{
credentials: ['apiKey'],
steps: [
'Log in to your Umami instance (or Umami Cloud at https://cloud.umami.is)',
'Open Settings → API Keys',
'Click "Create API key"',
'Enter a name, e.g. "Homarr", and save',
'Copy the generated API key into Homarr',
]
},
{
credentials: ['username', 'password'],
steps: [
'Use the username and password of your Umami account',
'Note: username/password auth is for self-hosted instances only - Umami Cloud requires an API key',
]
}
]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
"Log in to your Umami instance (or Umami Cloud at https://cloud.umami.is)",
"Open Settings → API Keys",
'Click "Create API key"',
'Enter a name, e.g. "Homarr", and save',
"Copy the generated API key into Homarr",
],
},
{
credentials: ["username", "password"],
steps: [
"Use the username and password of your Umami account",
"Note: username/password auth is for self-hosted instances only - Umami Cloud requires an API key",
],
},
]}
/>
@@ -1,40 +1,40 @@
---
title: 'Unifi Controller'
title: "Unifi Controller"
description: "Unifi Controller is a network management platform for Unifi devices."
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 { 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 { IconTopologyFull } from "@tabler/icons-react";
import { unifiControllerIntegration } from '.';
import { networkControllerSummaryWidget } from '@site/docs/widgets/network-controller-summary';
import { networkControllerStatusWidget } from '@site/docs/widgets/network-controller-status';
import { unifiControllerIntegration } from ".";
import { networkControllerSummaryWidget } from "@site/docs/widgets/network-controller-summary";
import { networkControllerStatusWidget } from "@site/docs/widgets/network-controller-status";
<IntegrationHeader
integration={unifiControllerIntegration}
categories={['Network controller']}
/>
<IntegrationHeader integration={unifiControllerIntegration} categories={["Network controller"]} />
This integration is using the [node-unifi](https://www.npmjs.com/package/node-unifi) library under the hood to connect to the Unifi Controller.
Therfore it should support CloudKey Gen1, CloudKey Gen2, UnifiOS-based UDM-Pro controllers as well as self-hosted UniFi controllers.
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: networkControllerSummaryWidget },
{ widget: networkControllerStatusWidget}
]}
items={[{ widget: networkControllerSummaryWidget }, { widget: networkControllerStatusWidget }]}
/>
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['username', 'password'],
steps: []
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["username", "password"],
steps: [],
},
]}
/>
+53 -41
View File
@@ -1,59 +1,71 @@
---
title: 'Unraid'
title: "Unraid"
description: "Versatile operating system that lets you run applications, virtual machines, and storage devices on your server"
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 { unraidIntegration } from '.';
import { systemResourcesWidget } from '@site/docs/widgets/system-resources';
import { healthMonitoringWidget } from '@site/docs/widgets/health-monitoring';
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 { unraidIntegration } from ".";
import { systemResourcesWidget } from "@site/docs/widgets/system-resources";
import { healthMonitoringWidget } from "@site/docs/widgets/health-monitoring";
import imgManagement from "./imgs/unraid-management.png";
import imgCreateApiKey from "./imgs/unraid-create-api-key.png";
import imgCopyApiKey from "./imgs/copy-api-key.png";
import imgSelectApikeyPreset from "./imgs/unraid-select-api-key-preset.png";
<IntegrationHeader
integration={unraidIntegration}
categories={['NAS', 'Hardware']}
/>
<IntegrationHeader integration={unraidIntegration} categories={["NAS", "Hardware"]} />
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: healthMonitoringWidget },
{ widget: systemResourcesWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: healthMonitoringWidget }, { widget: systemResourcesWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['apiKey'],
steps: [
<span>Are you using Unraid pre-7.2? If yes, please first <a href={"https://docs.unraid.net/API/#plugin-installation-pre-72-and-advanced-users"} target={"_blank"}>follow the steps here to install the Unraid API</a>.</span>,
<>
<span>Open the settings and open the management access</span><br/>
<img src={imgManagement} alt="Unraid management" style={{ height: 160 }} />
</>,
<>
<span>Click on the "API Keys" tab at the top and click on the "create API key" button. Choose "Create new"</span><br/>
<img src={imgCreateApiKey} alt="Unraid management" style={{ height: 120 }} />
</>,
<>
<span>Enter a suitable name for your API key (e.g. Homarr), select the "Viewer" preset and submit the modal.</span><br/>
<img src={imgSelectApikeyPreset} alt="Unraid management" style={{ height: 350 }} />
</>,
<>
<span>Last, copy the API key after your API key has been created</span><br/>
<img src={imgCopyApiKey} alt="Unraid management" style={{ height: 200 }} />
</>
],
}]} />
<IntegrationSecrets
secrets={[
{
credentials: ["apiKey"],
steps: [
<span>
Are you using Unraid pre-7.2? If yes, please first{" "}
<a href={"https://docs.unraid.net/API/#plugin-installation-pre-72-and-advanced-users"} target={"_blank"}>
follow the steps here to install the Unraid API
</a>
.
</span>,
<>
<span>Open the settings and open the management access</span>
<br />
<img src={imgManagement} alt="Unraid management" style={{ height: 160 }} />
</>,
<>
<span>
Click on the "API Keys" tab at the top and click on the "create API key" button. Choose "Create new"
</span>
<br />
<img src={imgCreateApiKey} alt="Unraid management" style={{ height: 120 }} />
</>,
<>
<span>
Enter a suitable name for your API key (e.g. Homarr), select the "Viewer" preset and submit the modal.
</span>
<br />
<img src={imgSelectApikeyPreset} alt="Unraid management" style={{ height: 350 }} />
</>,
<>
<span>Last, copy the API key after your API key has been created</span>
<br />
<img src={imgCopyApiKey} alt="Unraid management" style={{ height: 200 }} />
</>,
],
},
]}
/>
@@ -1,43 +1,42 @@
---
title: 'Uptime Kuma'
title: "Uptime Kuma"
description: "Uptime Kuma is a self-hosted monitoring tool that tracks the availability of your services and websites."
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 { uptimeKumaIntegration } from '.';
import { uptimeKumaWidget } from '@site/docs/widgets/uptime-kuma';
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 { uptimeKumaIntegration } from ".";
import { uptimeKumaWidget } from "@site/docs/widgets/uptime-kuma";
<IntegrationHeader
integration={uptimeKumaIntegration}
categories={['Monitoring']}
/>
<IntegrationHeader integration={uptimeKumaIntegration} categories={["Monitoring"]} />
Uptime Kuma monitors the availability of your services and provides uptime statistics through its status page API.
### Widgets & Capabilities
<IntegrationCapabilites
items={[
{ widget: uptimeKumaWidget },
]}
/>
<IntegrationCapabilites items={[{ widget: uptimeKumaWidget }]} />
### Adding the integration
<AddingIntegration />
### Secrets
<IntegrationSecrets secrets={[{
credentials: ['slug'],
steps: [
'Navigate to your Uptime Kuma instance',
'Go to Status Pages and create or select a status page',
<IntegrationSecrets
secrets={[
{
credentials: ["slug"],
steps: [
"Navigate to your Uptime Kuma instance",
"Go to Status Pages and create or select a status page",
'The slug is the URL path of your status page (e.g. "default" for /status/default)',
]
}]} />
],
},
]}
/>
:::tip
If you don't specify a slug, Homarr will use `default` as the status page slug.
+4 -4
View File
@@ -24,10 +24,10 @@ Navigate to `Management` → `Tools` → `Backup`. You must have **admin** permi
Click the **Export** button in the export card. You'll be prompted to type `I understand` to confirm. Once confirmed, a ZIP file downloads containing:
| File | Description |
| -------------------- | ------------------------------------------------------------------- |
| `db.sqlite` | Full SQLite database with all entities |
| `metadata.json` | Backup metadata: Homarr version, creation timestamp, encryption key |
| File | Description |
| --------------- | ------------------------------------------------------------------- |
| `db.sqlite` | Full SQLite database with all entities |
| `metadata.json` | Backup metadata: Homarr version, creation timestamp, encryption key |
The backup contains the complete database. It includes Custom Widgets and all other Homarr configuration.
@@ -7,27 +7,29 @@ tags:
---
# Certificates
On this page you can manage your trusted certificates.
On this page you can manage your trusted certificates.
For example if you use a self signed certificate for one of the integrations you want to connect, you can add it here.
Below you can see a screenshot of the certificates page.
The items show the subject, filename and when it expires.
Below you can see a screenshot of the certificates page.
The items show the subject, filename and when it expires.
The color of the icon indicates how long it is valid.
![](./img/screenshot.png)
| Color | Meaning |
| --- | --- |
| 🟩 Green | Valid for more than 30 days |
| Color | Meaning |
| --------- | --------------------------- |
| 🟩 Green | Valid for more than 30 days |
| 🟨 Yellow | Valid for less than 30 days |
| 🟧 Orange | Valid for less than a week |
| 🟥 Red | Valid for less than a day |
| 🟧 Orange | Valid for less than a week |
| 🟥 Red | Valid for less than a day |
## Opening the certificates page
Navigate to ``Management`` > ``Tools`` > ``Certificates``.
Navigate to `Management` > `Tools` > `Certificates`.
## Add a certificate
To add a certificate click on the "Add certificate" button.
![](./img/add-button.png)
@@ -62,4 +64,4 @@ Below you can find instructions for some of the integrations.
Since version 6 of Pi-hole, the web interface can be accessed through HTTPS.
The certificate can be found in the path `/etc/pihole/tls_ca.crt`. To add the certificate, this file needs to be copied and uploaded to Homarr.
You can find more details regarding SSL / TLS for Pi-hole [here](https://docs.pi-hole.net/api/tls/).
You can find more details regarding SSL / TLS for Pi-hole [here](https://docs.pi-hole.net/api/tls/).
@@ -6,11 +6,13 @@ tags:
---
# Integrations
Integrations are connections to supported third party applications.
This page will describe the process of managing integrations but the process may vary depending on your specific integration.
Check [the available integrations](/docs/category/integrations) for further information.
## Create an integration
To create an integration, you can choose the supported application from the dropdown at the top right:
![](./img/create-integration-dropdown.png)
@@ -20,19 +22,24 @@ Next, you'll need to fill out the required fields to configure the integration:
![](./img/form-create-integration.png)
### Name
Must be at least 1 character long, can be chosen freely.
### Url
This must be the base URL of the application where Homarr should connect to.
A few examples for this field include:
- http://sabnzbd.example.com
- https://example.com/sabnzbd
You must not append any path after the base URL. Some examples for incorrect usage:
- http://sabnzbd.example.com/settings
- https://example.com/sabnzbd/settings
### Secrets
An integration may or may not require secrets to function.
To process to obtain them is usually [documented in the integration pages](/docs/category/integrations).
Secrets are encrypted using a symmetric encryption and stored in the database.
@@ -47,6 +54,7 @@ If you already have an application created, you can also link it to the integrat
On the edit page you can always change or remove the linked application.
### Testing and saving integration
It is not allowed to create an integration without passing the test.
This is to ensure that you minimize the amount of broken applications on your Homarr instance.
The test and create button will perform a network request to the application and authenticate if required.
@@ -62,6 +70,7 @@ On the edit page of an integration, you can manage which users / groups can
![](./img/integration-permissions.png)
## Troubleshooting connection
The connection to your integrations can fail due to many factors. Most of the time it should show you the reason why it failed.
If it doesn't, you can follow these steps to troubleshoot the issue:
@@ -70,23 +79,23 @@ If it doesn't, you can follow these steps to troubleshoot the issue:
- The secrets must be correct and have the correct permissions.
2. If you use https to connect to the application, check the chapter below about [certificate issues](#certificate-issues).
3. Check whether you followed the Homarr documentation and didn't skip any steps.
This is the most often mistake that create many noisy support requests and following all steps will often resolve the problems.
This is the most often mistake that create many noisy support requests and following all steps will often resolve the problems.
4. Check Homarr's logs for more information. As we have no control over breaking changes in upstream APIs and third party software,
they can break without notice in unexpected ways which can also lead to errors within Homarr. In such case, these occurrences must be reported
and fixed within the source code of Homarr.
5. Check whether the host can reach the destination hostname / IP using ``ping`` and ``curl`` or ``wget`` afterward.
Execute this command on the host machine, not inside containers, to check whether it can connect or not.
they can break without notice in unexpected ways which can also lead to errors within Homarr. In such case, these occurrences must be reported
and fixed within the source code of Homarr.
5. Check whether the host can reach the destination hostname / IP using `ping` and `curl` or `wget` afterward.
Execute this command on the host machine, not inside containers, to check whether it can connect or not.
6. Check whether the container / pod can reach the destination hostname / IP. Execute the same commands in the shell inside the container / pod.
7. Check your reverse proxy / authentication proxy logs for failures / hints
8. Check your security log of tunnels and VPNs
9. Check your router for security events
10. Check your VLAN configuration and firewall rules
11. Check your DNS settings for the host machine and the containers / pods and whether they can resolve the hostnames
12. Check throughput and stability of your network connection using ``iperf3``
12. Check throughput and stability of your network connection using `iperf3`
13. Check syslog / drivers of your OS for hints
14. Check logs of your destination applications (eg. SABnzbd)
15. Attempt to disable CSRF / tamper protections when absolutely no other workaround available -> this comes with some security implications - be careful!
Re-enable if this didn't fix the issue.
Re-enable if this didn't fix the issue.
If none of these troubleshooting steps worked, you can request support from our team in Discord or GitHub.
@@ -95,4 +104,4 @@ If none of these troubleshooting steps worked, you can request support from our
If you are using a self-signed certificate you'll need to add it to the [trusted certificates](../certificates) in Homarr.
Most of the time you should also get a button to add the certificate automatically when you try to connect to the integration.
Please check that the certificate is the one you are expecting to prevent Man in the Middle attacks.
For some integrations, you can find a guide on how to retrieve the certificate [here](../certificates/#obtaining-certificates).
For some integrations, you can find a guide on how to retrieve the certificate [here](../certificates/#obtaining-certificates).
+2 -1
View File
@@ -7,7 +7,8 @@ tags:
---
# Media
Using the media feature, you can upload images for custom icons to Homarr.
Images will be stored in the database. They can be selected in the [icon picker](/docs/advanced/icons).
![](./img/screenshot.png)
![](./img/screenshot.png)
@@ -6,6 +6,7 @@ tags:
---
# Search Engines
Using the search engines, terms can be quickly searched simply by opening the search bar at the top or using the keyboard shortcut `CTRL + K`.
![](./img/search-engines.png)
@@ -13,31 +14,36 @@ Using the search engines, terms can be quickly searched simply by opening the se
You can add any search engine that has a search URL that accepts a search term as a parameter.
## Create search engine
To create a custom search engine, you can click the button at the top of the page.
![](./img/create-search-engine.png)
### Name
The name can be chosen freely. It will be displayed in the search box popover.
### Short
Prefix that is used to choose the search engine in the popover using the keyboard.
It is recommended that this value is kept short (for example ``g`` for Google and ``e`` for Ecosia).
It is recommended that this value is kept short (for example `g` for Google and `e` for Ecosia).
### Configuration
In the configuration section you can select between two options.
#### Search template
The template must be a valid URL that incldues the ``%s`` placeholder.
Homarr will replace the ``%s`` with the term that the user entered.
The template must be a valid URL that incldues the `%s` placeholder.
Homarr will replace the `%s` with the term that the user entered.
##### Examples
- Google: ``https://www.google.com/search?q=%s``
- Ecosia: ``https://www.ecosia.org/search?q=%s``
- DuckDuckGo: ``https://duckduckgo.com/?q=%s``
- Bing: ``https://www.bing.com/search?q=%s``
- YouTube: ``https://www.youtube.com/results?search_query=%s``
- Google: `https://www.google.com/search?q=%s`
- Ecosia: `https://www.ecosia.org/search?q=%s`
- DuckDuckGo: `https://duckduckgo.com/?q=%s`
- Bing: `https://www.bing.com/search?q=%s`
- YouTube: `https://www.youtube.com/results?search_query=%s`
## Media request search
@@ -45,12 +51,14 @@ Jellyseerr, Overseerr, and Seerr integrations have a dedicated **Spotlight mode*
This mode does not require creating a search engine entry - it is available automatically when you have a compatible integration configured.
You can access it from:
- The **Modes list** in Spotlight (opened with `CTRL + K`)
- The **search button** on the media request list and stats widgets
### Availability indicators
Search results display colored status badges showing the media's current state in your integration:
- **Available** - fully available in your media library
- **Partial** - some content (e.g. seasons) is available
- **Processing** - currently being downloaded or processed
@@ -38,6 +38,3 @@ You can disable a task by clicking the "Power" button, which will change it to a
When a task is disabled, it will not run automatically according to its schedule.
You can enable it again by clicking the "Power-Off" button, which will change it back to a "Power" button.
Running a task manually is still possible when it is disabled.
+35 -6
View File
@@ -20,8 +20,10 @@ Homarr supports [single sign on for easier and seamless authentication](/docs/ad
:::
## Manage users
### Creating new users
To create new users, you must navigate to ``Mangement`` > ``Users`` > ``Manage`` and click on the create button to create a new one: \
To create new users, you must navigate to `Mangement` > `Users` > `Manage` and click on the create button to create a new one: \
![](./img/button-create-user.png)
You'll be guided through the process using a wizard: \
@@ -35,25 +37,31 @@ After you completed all steps, you can start over to create another user or choo
![](./img/wizard-complete.png)
## Editing a user
A user can be edited on the ``Mangement`` > ``Users`` > ``Manage`` page when you click on the username.
A user can be edited on the `Mangement` > `Users` > `Manage` page when you click on the username.
Here you'll have access to two tabs: **General** and **Security**.
### General tab
#### Username
This is the unique username that identifies this user. It can be changed to anything but must be at least 3 characters long with a limit of 255 characters.
This name will be used for the credential's login. It is also used to auto-generate profile pictures if no picture was uploaded.
#### E-Mail
This is the unique email of the user. As of 1.0, it is not used for any notifications and only for organizational purposes.
This field is optional.
#### Language
This is the currently selected language of the user.
Changing the language will change all text & the right to left (RTL) feature in some languages.
By default, Homarr will choose English as the default language. Here you can override the language for this specific user.
The user may choose a different language by themselves afterward.
#### Home board
Optional field for the board that is loaded by default if no board was specified in the URL.
Only boards that the user has permission to are being shown.
@@ -70,6 +78,7 @@ Choose the first day of the week for the user. This will affect the calendar wid
Option to show icons for status check instead of colored dots.
#### Delete
This action will permanently delete the user from the database, including any preferences they set.
If the user created boards, they wil **not** be deleted.
This action is **irreversible** and cannot be undone. All data is permanently lost.
@@ -77,6 +86,7 @@ This action is **irreversible** and cannot be undone. All data is permanently lo
### Security tab
#### Change password
Here the password for this user can be changed.
It must also meet the password requirements of Homarr.
The password is stored as an encrypted value with a salt in the database - this means the value cannot be read out from the database afterward.
@@ -85,50 +95,63 @@ This functionality can also be useful to lock out a bad actor without tampering
For security reasons, you must confirm the password a second time.
## Groups
Using groups, you can manage the permissions of users.
Members can be directly assigned to groups.
A user will have the permissions of all groups they are a member of.
A user will have the permissions of all groups they are a member of.
Some permissions include other permissions, for example the "Full board access" permission includes all board permissions.
By default, a group called "credentials-admin" will be generated where the first user will be placed.
However, you can create as many groups as you'd like.
### Creating a group
Click on the button ``New group`` to create a new one.
Click on the button `New group` to create a new one.
Homarr will prompt you for a group name.
### Managing a group
#### General tab
##### Name
Name for the group that can be chosen freely.
##### Transfer ownership
Every group has an owner. Using this button, the ownership can be transferred to a different user.
Group ownership is only organizational.
##### Delete
Deletes the group permanently. This change is irreversible.
#### Settings tab
In this tab, you can configure some settings for the group. Those settings will be prioritized by the order of the groups on the groups list page
##### Priorization
The higher a group in the list, the higher the priority. This means that if a user is in multiple groups, the permissions of the group with the highest priority will be used.
It will always fallback to the everyone group if no other group permissions are set.
![](./img/groups-list.png)
##### Boards
Configure board settings for a group. User specific settings will override group settings.
###### Home board
The board that is loaded by default if no board was specified in the URL.
###### Mobile board
The board that is loaded by default on mobile devices.
#### Members tab
In this tab, you can assign users to the group. With the button at the top right, a new member can be added to the group:
![](./img/add-group-member.png)
@@ -138,6 +161,7 @@ Members can be removed from the group using the remove button at the end:
![](./img/remove-group-member.png)
#### Permissions tab
In this tab, you manage what permissions the members of this group will have.
Currently, the following permissions are available:
@@ -163,9 +187,11 @@ When you changed permissions, you must confirm your changes by clicking the bann
![](./img/changing-group-permissions.png)
#### Special groups
Currently one special group exists. This group is `everyone`. It automatically adds every user that is known to Homarr to its members. Neither its name nor its members can be changed.
## Invites
Invites are an easy-to-use system to allow users to onboard themselves.
It is useful in companies or large-scale homelabs where many users must be onboarded at the same time.
You should trust the end user that they enter their data truthfully as the administrator will not confirm the entered data after the user has completed the onboarding.
@@ -174,6 +200,7 @@ This feature can only be used when credentials authentication is enabled.
An invitation link can be used indefinitely.
### Creating an invitation
Click on the button:
![](./img/create-invitation-button.png)
@@ -184,14 +211,15 @@ The default is 4 hours in the future.
![](./img/invitation-expiry-date.png)
Next, click ``Create`` and you'll get a confirmation with an ID, Token and a link that can be copied:
Next, click `Create` and you'll get a confirmation with an ID, Token and a link that can be copied:
![](./img/create-invitation-confirmation.png)
Both ID and Token are also in the URL. Ensure that you copy either ID & Token or the URL - it will never be shown again.
Clicking the ``Copy & close`` button will copy the URL to your clipboard.
Clicking the `Copy & close` button will copy the URL to your clipboard.
### Self-onboarding
Clicking the invitation link will bring up a form with fields for the username and password:
![](./img/invitation-self-onboarding.png)
@@ -199,6 +227,7 @@ Clicking the invitation link will bring up a form with fields for the username a
At the bottom of the page, the user who created the invitation can be seen.
### Deleting an invitation
If an invitation needs to be deleted before or after the expiry, the delete button at the end of the table can be used:
![](./img/deleting-invitation.png)
+17 -17
View File
@@ -1,35 +1,35 @@
---
title: 'Anchor Note'
description: 'Display and edit a selected note from Anchor'
title: "Anchor Note"
description: "Display and edit a selected note from Anchor"
hide_title: true
---
import { WidgetHeader } from '@site/src/components/widgets/header';
import { AddingWidget } from '@site/src/components/widgets/adding';
import { WidgetConfig } from '@site/src/components/widgets/configuration';
import { WidgetIntegrations } from '@site/src/components/widgets/integrations';
import { anchorNoteWidget } from '.';
import { anchorIntegration } from '@site/docs/integrations/anchor';
import { WidgetHeader } from "@site/src/components/widgets/header";
import { AddingWidget } from "@site/src/components/widgets/adding";
import { WidgetConfig } from "@site/src/components/widgets/configuration";
import { WidgetIntegrations } from "@site/src/components/widgets/integrations";
import { anchorNoteWidget } from ".";
import { anchorIntegration } from "@site/docs/integrations/anchor";
<WidgetHeader
widget={anchorNoteWidget}
categories={['Notes']}
/>
<WidgetHeader widget={anchorNoteWidget} categories={["Notes"]} />
The Anchor Note widget shows a selected note from your Anchor integration. If your note permissions allow it, you can also edit the note title and content directly in Homarr.
### Screenshots
import anchorNoteWidgetScreenshot from './img/widget.png';
import anchorNoteWidgetScreenshot from "./img/widget.png";
<img src={anchorNoteWidgetScreenshot} alt="anchor-note-widget" width={256} height={256} />
### Supported Integrations
<WidgetIntegrations items={[{
integration: anchorIntegration
}]} />
<WidgetIntegrations
items={[
{
integration: anchorIntegration,
},
]}
/>
### Interactions
+12 -15
View File
@@ -1,30 +1,26 @@
---
title: 'App'
description: 'Embeds an app into the board.'
title: "App"
description: "Embeds an app into the board."
hide_title: true
---
import { AddingWidget } from '@site/src/components/widgets/adding';
import { WidgetConfig } from '@site/src/components/widgets/configuration';
import { WidgetHeader } from '@site/src/components/widgets/header';
import { appWidget } from '.';
import { AddingWidget } from "@site/src/components/widgets/adding";
import { WidgetConfig } from "@site/src/components/widgets/configuration";
import { WidgetHeader } from "@site/src/components/widgets/header";
import { appWidget } from ".";
<WidgetHeader
widget={appWidget}
categories={['Links', 'Apps']}
/>
<WidgetHeader widget={appWidget} categories={["Links", "Apps"]} />
The app widget allows you to add a link to an application or a website that you want to access quickly from your Homarr board.
It also supports a status check to indicate whether Homarr can reach the application or website.
### Screenshots
import githubApp from './img/github.png';
import jellyseerrApp from './img/jellyseerr-description-tooltip.png';
import piHoleApp from './img/pi-hole-ping-icon.png';
import githubApp from "./img/github.png";
import jellyseerrApp from "./img/jellyseerr-description-tooltip.png";
import piHoleApp from "./img/pi-hole-ping-icon.png";
<div className='flex gap-1'>
<div className="flex gap-1">
<img src={githubApp} alt="app github with-status-check" width={128 * 1.5} height={128 * 1.5} />
<img src={piHoleApp} alt="app pi-hole with-status-check status-check-icon" width={128 * 1.5} height={128 * 1.5} />
<img src={jellyseerrApp} alt="app jellyseerr with-description-tooltip" height={128 * 1.5} />
@@ -34,4 +30,5 @@ import piHoleApp from './img/pi-hole-ping-icon.png';
<AddingWidget />
### Configuration
<WidgetConfig configuration={appWidget.configuration} />
Loaded 100 of 215 files, more files were not shown because too many files have changed in this diff. Show more