diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index 9b39aa24..e9d4ee40 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -1,18 +1,23 @@
name: Bug report
description: Create a report to help us improve
-title: "[Bug] "
+title: "[Bug] Concise description of the issue"
labels: ["bug, unconfirmed"]
body:
- type: markdown
attributes:
value: |
- Have a question? 👉 [Start a new discussion](https://github.com/benphelps/homepage/discussions/new) or [ask in chat](https://discord.gg/SaPGSzrEZC).
+ ## ⚠️ Please remember: issues are for *bugs*
+ That is, something you believe affects every single homepage user, not just you. Otherwise, start with one of the other options below.
+ - type: markdown
+ attributes:
+ value: |
+ Have a question? 👉 [Start a new discussion](https://github.com/gethomepage/homepage/discussions/new) or [ask in chat](https://discord.gg/SaPGSzrEZC).
Before opening an issue, please double check:
- - [The troubleshooting guide](https://gethomepage.dev/en/more/troubleshooting/).
+ - [The troubleshooting guide](https://gethomepage.dev/latest/more/troubleshooting/).
- [The homepage documentation](https://gethomepage.dev/)
- - [Existing issues](https://github.com/benphelps/homepage/search?q=&type=issues) and [discussions](https://github.com/benphelps/homepage/search?q=&type=discussions).
+ - [Existing issues](https://github.com/gethomepage/homepage/search?q=&type=issues) and [discussions](https://github.com/gethomepage/homepage/search?q=&type=discussions).
- type: textarea
id: description
attributes:
@@ -73,7 +78,7 @@ body:
id: troubleshooting
attributes:
label: Troubleshooting
- description: Please include output from your [troubleshooting tests](https://gethomepage.dev/en/more/troubleshooting/#service-widget-errors). If this is a service widget issue and you do not include any information here your issue will be closed. If it is not, indicate e.g. 'n/a'
+ description: Please include output from your [troubleshooting tests](https://gethomepage.dev/latest/more/troubleshooting/#service-widget-errors). If this is a service widget issue and you do not include any information here your issue will be closed. If it is not, indicate e.g. 'n/a'
validations:
required: true
- type: textarea
@@ -88,7 +93,7 @@ body:
options:
- label: Check [the documentation](https://gethomepage.dev/)
required: true
- - label: Follow [the troubleshooting guide](https://gethomepage.dev/en/more/troubleshooting/) (please include output above if applicable).
+ - label: Follow [the troubleshooting guide](https://gethomepage.dev/latest/more/troubleshooting/) (please include output above if applicable).
required: true
- - label: Search [existing issues](https://github.com/benphelps/homepage/search?q=&type=issues) and [discussions](https://github.com/benphelps/homepage/search?q=&type=discussions).
+ - label: Search [existing issues](https://github.com/gethomepage/homepage/search?q=&type=issues) and [discussions](https://github.com/gethomepage/homepage/search?q=&type=discussions).
required: true
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
index a2ae1dfb..e3f14d07 100644
--- a/.github/ISSUE_TEMPLATE/config.yml
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -1,11 +1,11 @@
blank_issues_enabled: false
contact_links:
- name: 🤔 Questions and Help
- url: https://github.com/benphelps/homepage/discussions
+ url: https://github.com/gethomepage/homepage/discussions
about: This issue tracker is for bugs only, not general support questions. Please refer to our Discussions.
- name: 💬 Chat
url: https://discord.gg/k4ruYNrudu
about: Want to discuss homepage with others? Check out our chat.
- name: 🚀 Feature Request
- url: https://github.com/benphelps/homepage/discussions/new?category=feature-requests
+ url: https://github.com/gethomepage/homepage/discussions/new?category=feature-requests
about: Remember to search for existing feature requests and "up-vote" any you like
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 1f7773b8..1cad352a 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -3,10 +3,10 @@
Closes # (issue)
@@ -20,11 +20,12 @@ What type of change does your PR introduce to Homepage?
- [ ] New service widget
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
+- [ ] Documentation only
- [ ] Other (please explain)
## Checklist:
-- [ ] If adding a service widget or a change that requires it, I have added a corresponding PR to the [documentation](https://github.com/benphelps/homepage-docs) here:
-- [ ] If adding a new widget I have reviewed the [guidelines](https://gethomepage.dev/en/more/development/#service-widget-guidelines).
-- [ ] If applicable, I have checked that all tests pass with e.g. `pnpm lint`.
+- [ ] If applicable, I have added corresponding documentation changes.
+- [ ] If applicable, I have reviewed the [feature](https://gethomepage.dev/latest/more/development/#new-feature-guidelines) and / or [service widget guidelines](https://gethomepage.dev/latest/more/development/#service-widget-guidelines).
+- [ ] I have checked that all code style checks pass using [pre-commit hooks](https://gethomepage.dev/latest/more/development/#code-formatting-with-pre-commit-hooks) and [linting checks](https://gethomepage.dev/latest/more/development/#code-linting).
- [ ] If applicable, I have tested my code for new features & regressions on both mobile & desktop devices, using the latest version of major browsers.
diff --git a/.github/workflows/crowdin.yml b/.github/workflows/crowdin.yml
new file mode 100644
index 00000000..e7e473eb
--- /dev/null
+++ b/.github/workflows/crowdin.yml
@@ -0,0 +1,31 @@
+name: Crowdin Action
+
+on:
+ workflow_dispatch:
+ schedule:
+ - cron: '2 */12 * * *'
+ push:
+ paths: [
+ '/public/locales/en/**',
+ ]
+ branches: [ main ]
+
+jobs:
+ synchronize-with-crowdin:
+ name: Crowdin Sync
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+ - name: crowdin action
+ uses: crowdin/github-action@v1
+ with:
+ upload_translations: false
+ download_translations: true
+ crowdin_branch_name: main
+ localization_branch_name: l10n_main
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }}
+ CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }}
diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml
index 8614c727..3bea5512 100644
--- a/.github/workflows/docker-publish.yml
+++ b/.github/workflows/docker-publish.yml
@@ -9,11 +9,20 @@ on:
schedule:
- cron: '20 0 * * *'
push:
- branches: [ "main" ]
+ branches:
+ - main
+ - feature/**
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
+ paths-ignore:
+ - 'docs/**'
+ - 'mkdocs.yml'
pull_request:
branches: [ "main" ]
+ paths-ignore:
+ - 'docs/**'
+ - 'mkdocs.yml'
+ merge_group:
env:
# Use docker.io for Docker Hub if empty
@@ -23,9 +32,28 @@ env:
jobs:
- build:
+ pre-commit:
+ name: Linting Checks
+ runs-on: ubuntu-22.04
+ steps:
+ -
+ name: Checkout repository
+ uses: actions/checkout@v4
+ -
+ name: Install python
+ uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ -
+ name: Check files
+ uses: pre-commit/action@v3.0.0
+ build:
+ name: Docker Build & Push
+ if: github.repository == 'gethomepage/homepage'
runs-on: self-hosted
+ needs:
+ - pre-commit
permissions:
contents: read
packages: write
@@ -49,11 +77,11 @@ jobs:
# https://github.com/marketplace/actions/docker-setup-buildx#with-qemu
- name: Setup QEMU
uses: docker/setup-qemu-action@v3
-
+
# Workaround: https://github.com/docker/build-push-action/issues/461
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v3
-
+
# This step is being disabled because the runner is on a self-hosted machine
# where the cache will stick between runs.
# - name: Cache Docker layers
@@ -91,7 +119,7 @@ jobs:
uses: docker/build-push-action@v5
with:
context: .
- push: ${{ github.event_name != 'pull_request' }}
+ push: ${{ github.event_name != 'pull_request' && !(github.event_name == 'push' && startsWith(github.ref, 'refs/heads/feature')) }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
diff --git a/.github/workflows/docs-publish.yml b/.github/workflows/docs-publish.yml
new file mode 100644
index 00000000..f85f9ee5
--- /dev/null
+++ b/.github/workflows/docs-publish.yml
@@ -0,0 +1,100 @@
+name: Docs
+
+on:
+ push:
+ tags: [ 'v*.*.*' ]
+ branches: ['main']
+ paths:
+ - 'docs/**'
+ - 'mkdocs.yml'
+ pull_request:
+ paths:
+ - 'docs/**'
+ - 'mkdocs.yml'
+ merge_group:
+ workflow_dispatch:
+
+permissions:
+ contents: write
+
+jobs:
+ pre-commit:
+ name: Linting Checks
+ runs-on: ubuntu-22.04
+ steps:
+ -
+ name: Checkout repository
+ uses: actions/checkout@v4
+ -
+ name: Install python
+ uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ -
+ name: Check files
+ uses: pre-commit/action@v3.0.0
+
+ test:
+ name: Test Build
+ if: github.repository == 'gethomepage/homepage' && github.event_name == 'pull_request'
+ runs-on: ubuntu-latest
+ needs:
+ - pre-commit
+ steps:
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+ - uses: actions/cache@v3
+ with:
+ key: mkdocs-material-${{ env.cache_id }}
+ path: .cache
+ restore-keys: |
+ mkdocs-material-
+ - run: sudo apt-get install pngquant
+ - run: pip install mike
+ - run: pip install mkdocs-material
+ - name: Test Docs Build
+ run: MKINSIDERS=false mkdocs build
+ deploy:
+ name: Build & Deploy
+ if: github.repository == 'gethomepage/homepage' && github.event_name != 'pull_request'
+ runs-on: ubuntu-latest
+ needs:
+ - pre-commit
+ steps:
+ - uses: actions/checkout@v4
+ with:
+ ref: main
+ - uses: actions/setup-python@v5
+ with:
+ python-version: 3.x
+ - run: echo "cache_id=$(date --utc '+%V')" >> $GITHUB_ENV
+ - uses: actions/cache@v3
+ with:
+ key: mkdocs-material-${{ env.cache_id }}
+ path: .cache
+ restore-keys: |
+ mkdocs-material-
+ - run: sudo apt-get install pngquant
+ - run: pip install mike==1.1.2
+ - run: pip install git+https://${GH_TOKEN}@github.com/benphelps/mkdocs-material-insiders.git
+ - name: Set Git config
+ run: |
+ git config --global user.name "GitHub Action"
+ git config --global user.email "action@github.com"
+ - name: Sync gh-pages
+ run: |
+ git fetch origin gh-pages
+ git checkout gh-pages
+ git pull origin gh-pages
+ git checkout main
+ - name: Docs Deploy for Main
+ if: github.ref == 'refs/heads/main'
+ run: MKINSIDERS=true mike deploy --update --push ${{github.ref_name}}
+ - name: Docs Deploy for Tags
+ if: github.ref != 'refs/heads/main'
+ run: MKINSIDERS=true mike deploy --update --push ${{github.ref_name}} latest
+env:
+ GH_TOKEN: ${{ secrets.GH_TOKEN }}
diff --git a/.gitignore b/.gitignore
index 7fdc6550..9eccc8c6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -46,4 +46,9 @@ next-env.d.ts
# IDEs
/.idea/
+# MkDocs documentation
+site*/
+.cache/
+# venv
+.venv/
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 00000000..6cc46b47
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,19 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+- repo: https://github.com/pre-commit/pre-commit-hooks
+ rev: v3.2.0
+ hooks:
+ - id: trailing-whitespace
+ - id: end-of-file-fixer
+ - id: check-yaml
+ exclude: "(^mkdocs\\.yml$)"
+ - id: check-added-large-files
+- repo: https://github.com/pre-commit/mirrors-prettier
+ rev: 'v3.0.3'
+ hooks:
+ - id: prettier
+ types_or:
+ - javascript
+ - markdown
+ - jsx
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 00000000..0967ef42
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1 @@
+{}
diff --git a/.vscode/settings.json b/.vscode/settings.json
index 5a9e97f1..5fde0b3a 100644
--- a/.vscode/settings.json
+++ b/.vscode/settings.json
@@ -2,5 +2,18 @@
"files.exclude": {
"**/.next": true,
"**/node_modules": true
- }
-}
\ No newline at end of file
+ },
+ "yaml.schemas": {
+ "https://squidfunk.github.io/mkdocs-material/schema.json": "mkdocs.yml"
+ },
+ "yaml.customTags": [
+ "!ENV scalar",
+ "!ENV sequence",
+ "tag:yaml.org,2002:python/name:material.extensions.emoji.to_svg",
+ "tag:yaml.org,2002:python/name:material.extensions.emoji.twemoji",
+ "tag:yaml.org,2002:python/name:pymdownx.superfences.fence_code_format"
+ ],
+ "[python]": {
+ "editor.defaultFormatter": "ms-python.autopep8"
+ },
+}
diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md
index f989048e..a339e842 100644
--- a/CODE_OF_CONDUCT.md
+++ b/CODE_OF_CONDUCT.md
@@ -17,23 +17,23 @@ diverse, inclusive, and healthy community.
Examples of behavior that contributes to a positive environment for our
community include:
-* Demonstrating empathy and kindness toward other people
-* Being respectful of differing opinions, viewpoints, and experiences
-* Giving and gracefully accepting constructive feedback
-* Accepting responsibility and apologizing to those affected by our mistakes,
+- Demonstrating empathy and kindness toward other people
+- Being respectful of differing opinions, viewpoints, and experiences
+- Giving and gracefully accepting constructive feedback
+- Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
-* Focusing on what is best not just for us as individuals, but for the
+- Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
-* The use of sexualized language or imagery, and sexual attention or
+- The use of sexualized language or imagery, and sexual attention or
advances of any kind
-* Trolling, insulting or derogatory comments, and personal or political attacks
-* Public or private harassment
-* Publishing others' private information, such as a physical or email
+- Trolling, insulting or derogatory comments, and personal or political attacks
+- Public or private harassment
+- Publishing others' private information, such as a physical or email
address, without their explicit permission
-* Other conduct which could reasonably be considered inappropriate in a
+- Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
@@ -106,7 +106,7 @@ Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
-standards, including sustained inappropriate behavior, harassment of an
+standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 2f383ede..efcce663 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,4 +1,5 @@
# Contributing to Homepage
+
We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
@@ -8,16 +9,20 @@ We love your input! We want to make contributing to this project as easy and tra
- Becoming a maintainer
## We Develop with Github
+
We use github to host code, to track issues and feature requests, as well as accept pull requests.
## Any contributions you make will be under the GNU General Public License v3.0
+
In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://choosealicense.com/licenses/gpl-3.0/) that covers the project. Feel free to contact the maintainers if that's a concern.
-## Report bugs using Github's [issues](https://github.com/benphelps/homepage/issues)
-We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/benphelps/homepage/issues/new); it's that easy!
+## Report bugs using Github's [issues](https://github.com/gethomepage/homepage/issues)
+
+We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/gethomepage/homepage/issues/new); it's that easy!
## Write bug reports with detail, background, and sample configurations
-Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue.
+
+Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue.
**Great Bug Reports** tend to have:
@@ -29,16 +34,20 @@ Homepage includes a lot of configuration options and is often deploying in large
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
-People *love* thorough bug reports. I'm not even kidding.
+People _love_ thorough bug reports. I'm not even kidding.
## Development Guidelines
-Please see the [documentation regarding development](https://gethomepage.dev/en/more/development/) and specifically the [guidelines for new service widgets](https://gethomepage.dev/en/more/development/#service-widget-guidelines) if you are considering making one.
+
+Please see the [documentation regarding development](https://gethomepage.dev/latest/more/development/) and specifically the [guidelines for new service widgets](https://gethomepage.dev/latest/more/development/#service-widget-guidelines) if you are considering making one.
## Use a Consistent Coding Style
-This project follows the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), please follow it when submitting pull requests.
+
+Please see information in the docs regarding [code formatting with pre-commit hooks](https://gethomepage.dev/latest/more/development/#code-formatting-with-pre-commit-hooks).
## License
+
By contributing, you agree that your contributions will be licensed under its GNU General Public License.
## References
+
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md)
diff --git a/Dockerfile b/Dockerfile
index 9fec35e7..3e6de756 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -36,9 +36,9 @@ RUN npm run telemetry \
FROM docker.io/node:18-alpine AS runner
LABEL org.opencontainers.image.title "Homepage"
LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations."
-LABEL org.opencontainers.image.url="https://github.com/benphelps/homepage"
-LABEL org.opencontainers.image.documentation='https://github.com/benphelps/homepage/wiki'
-LABEL org.opencontainers.image.source='https://github.com/benphelps/homepage'
+LABEL org.opencontainers.image.url="https://github.com/gethomepage/homepage"
+LABEL org.opencontainers.image.documentation='https://github.com/gethomepage/homepage/wiki'
+LABEL org.opencontainers.image.source='https://github.com/gethomepage/homepage'
LABEL org.opencontainers.image.licenses='Apache-2.0'
ENV NODE_ENV production
diff --git a/README.md b/README.md
index 8d0d27fa..7fc05672 100644
--- a/README.md
+++ b/README.md
@@ -14,12 +14,14 @@
-
+
-
+
+
+
@@ -39,19 +41,19 @@ With features like quick search, bookmarks, weather support, a wide range of int
## Docker Integration
-Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker](https://gethomepage.dev/en/installation/docker/) page for more information.
+Homepage has built-in support for Docker, and can automatically discover and add services to the homepage based on labels. See the [Docker](https://gethomepage.dev/latest/installation/docker/) page for more information.
## Service Widgets
-Homepage also has support for over 100 3rd party services, including all popular starr apps, and most popular self-hosted apps. Some examples include: Radarr, Sonarr, Lidarr, Bazarr, Ombi, Tautulli, Plex, Jellyfin, Emby, Transmission, qBittorrent, Deluge, Jackett, NZBGet, SABnzbd, etc. As well as service integrations, Homepage also has a number of information providers, sourcing information from a variety of external 3rd party APIs. See the [Service](https://gethomepage.dev/en/configs/service-widgets/) page for more information.
+Homepage also has support for over 100 3rd party services, including all popular starr apps, and most popular self-hosted apps. Some examples include: Radarr, Sonarr, Lidarr, Bazarr, Ombi, Tautulli, Plex, Jellyfin, Emby, Transmission, qBittorrent, Deluge, Jackett, NZBGet, SABnzbd, etc. As well as service integrations, Homepage also has a number of information providers, sourcing information from a variety of external 3rd party APIs. See the [Service](https://gethomepage.dev/latest/widgets/) page for more information.
## Information Widgets
-Homepage has built-in support for a number of information providers, including weather, time, date, search, glances and more. System and status information presented at the top of the page. See the [Information Providers](https://gethomepage.dev/en/configs/widgets/) page for more information.
+Homepage has built-in support for a number of information providers, including weather, time, date, search, glances and more. System and status information presented at the top of the page. See the [Information Providers](https://gethomepage.dev/latest/widgets/) page for more information.
## Customization
-Homepage is highly customizable, with support for custom themes, custom CSS & JS, custom layouts, formatting, localization and more. See the [Settings](https://gethomepage.dev/en/configs/settings/) page for more information.
+Homepage is highly customizable, with support for custom themes, custom CSS & JS, custom layouts, formatting, localization and more. See the [Settings](https://gethomepage.dev/latest/configs/settings/) page for more information.
# Getting Started
@@ -65,7 +67,7 @@ Using docker compose:
version: "3.3"
services:
homepage:
- image: ghcr.io/benphelps/homepage:latest
+ image: ghcr.io/gethomepage/homepage:latest
container_name: homepage
environment:
PUID: 1000 -- optional, your user id
@@ -88,7 +90,7 @@ docker run --name homepage \
-v /path/to/config:/app/config \
-v /var/run/docker.sock:/var/run/docker.sock:ro \
--restart unless-stopped \
- ghcr.io/benphelps/homepage:latest
+ ghcr.io/gethomepage/homepage:latest
```
## With Node
@@ -96,7 +98,7 @@ docker run --name homepage \
First, clone the repository:
```bash
-git clone https://github.com/benphelps/homepage.git
+git clone https://github.com/gethomepage/homepage.git
```
Then install dependencies and build the production bundle (I'm using pnpm here, you can use npm or yarn if you like):
@@ -122,7 +124,7 @@ pnpm dev
# Configuration
-Please refere to the [homepage documentation](https://gethomepage.dev/) website for more information. Everything you need to know about configuring Homepage is there. Please read everything carefully before asking for help, as most questions are answered there or are simple YAML configuration issues.
+Please refer to the [homepage documentation](https://gethomepage.dev/) website for more information. Everything you need to know about configuring Homepage is there. Please read everything carefully before asking for help, as most questions are answered there or are simple YAML configuration issues.
# Development
@@ -140,16 +142,34 @@ pnpm dev
Open [http://localhost:3000](http://localhost:3000) to start.
-This is a [Next.js](https://nextjs.org/) application, see their documentation for more information:
+This is a [Next.js](https://nextjs.org/) application, see their documentation for more information.
+
+# Documentation
+
+The homepage documentation is available at [https://gethomepage.dev/](https://gethomepage.dev/).
+
+Homepage uses Material for MkDocs for documentation. To run the documentation locally, first install the dependencies:
+
+```bash
+pip install -r requirements.txt
+```
+
+Then run the development server:
+
+```bash
+mkdocs serve # or build, to build the static site
+```
# Support & Suggestions
-If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/benphelps/homepage/discussions) page.
+If you have any questions, suggestions, or general issues, please start a discussion on the [Discussions](https://github.com/gethomepage/homepage/discussions) page.
-For bug reports, please open an issue on the [Issues](https://github.com/benphelps/homepage/issues) page.
+For bug reports, please open an issue on the [Issues](https://github.com/gethomepage/homepage/issues) page.
-## Contributing & Contributers
+## Contributing & Contributors
Contributions are welcome! Please see the [CONTRIBUTING.md](CONTRIBUTING.md) file for more information.
Thanks to the over 200 contributors who have helped make this project what it is today!
+
+Especially huge thanks to [@shamoon](https://github.com/shamoon), who has been the backbone of this community from the very start.
diff --git a/crowdin.yml b/crowdin.yml
new file mode 100644
index 00000000..c72cbb1b
--- /dev/null
+++ b/crowdin.yml
@@ -0,0 +1,6 @@
+project_id_env: CROWDIN_PROJECT_ID
+api_token_env: CROWDIN_PERSONAL_TOKEN
+preserve_hierarchy: true
+files:
+ - source: /public/locales/en/*.json
+ translation: /public/locales/%osx_locale%/%original_file_name%
diff --git a/docs/assets/banner_dark@2x.png b/docs/assets/banner_dark@2x.png
new file mode 100644
index 00000000..87bcd0a7
Binary files /dev/null and b/docs/assets/banner_dark@2x.png differ
diff --git a/docs/assets/banner_light@2x.png b/docs/assets/banner_light@2x.png
new file mode 100644
index 00000000..721446b8
Binary files /dev/null and b/docs/assets/banner_light@2x.png differ
diff --git a/docs/assets/custom.css b/docs/assets/custom.css
new file mode 100644
index 00000000..f959128e
--- /dev/null
+++ b/docs/assets/custom.css
@@ -0,0 +1,3 @@
+.md-typeset[data-page-id="landing"] .md-header-anchor {
+ display: none;
+}
diff --git a/docs/assets/favicon.ico b/docs/assets/favicon.ico
new file mode 100644
index 00000000..5ffe0eb4
Binary files /dev/null and b/docs/assets/favicon.ico differ
diff --git a/docs/assets/homepage_demo.png b/docs/assets/homepage_demo.png
new file mode 100644
index 00000000..52c69028
Binary files /dev/null and b/docs/assets/homepage_demo.png differ
diff --git a/docs/assets/light_squircle@2x.png b/docs/assets/light_squircle@2x.png
new file mode 100644
index 00000000..e7a1ee29
Binary files /dev/null and b/docs/assets/light_squircle@2x.png differ
diff --git a/docs/configs/bookmarks.md b/docs/configs/bookmarks.md
new file mode 100644
index 00000000..27f6c273
--- /dev/null
+++ b/docs/configs/bookmarks.md
@@ -0,0 +1,32 @@
+---
+title: Bookmarks
+description: Bookmark Configuration
+---
+
+Bookmarks function much the same as [Services](services.md), in how groups and lists work. They're just much simpler, smaller, and contain no extra features other than being a link out.
+
+The design of homepage expects `abbr` to be 2 letters, but is not otherwise forced.
+
+You can also use an icon for bookmarks similar to the [options for service icons](services.md#icons). If both icon and abbreviation are supplied, the icon takes precedence.
+
+By default, the description will use the hostname of the link, but you can override it with a custom description.
+
+```yaml
+- Developer:
+ - Github:
+ - abbr: GH
+ href: https://github.com/
+
+- Social:
+ - Reddit:
+ - icon: reddit.png
+ href: https://reddit.com/
+ description: The front page of the internet
+
+- Entertainment:
+ - YouTube:
+ - abbr: YT
+ href: https://youtube.com/
+```
+
+
diff --git a/docs/configs/custom-css-js.md b/docs/configs/custom-css-js.md
new file mode 100644
index 00000000..a76ea650
--- /dev/null
+++ b/docs/configs/custom-css-js.md
@@ -0,0 +1,17 @@
+---
+title: Custom CSS & JS
+description: Adding Custom CSS or JS
+---
+
+As of version v0.6.30 homepage supports adding your own custom css & javascript. Please do so **at your own risk**.
+
+To add custom css simply edit the `custom.css` file under your config directory, similarly for javascript you would edit `custom.js`. You can then target elements in homepage with various classes / ids to customize things to your liking.
+
+You can also set a specific `id` for a service or bookmark to target with your custom css or javascript, e.g.
+
+```yaml
+Service:
+ id: myserviceid
+ icon: icon.png
+ ...
+```
diff --git a/docs/configs/docker.md b/docs/configs/docker.md
new file mode 100644
index 00000000..2eaf2683
--- /dev/null
+++ b/docs/configs/docker.md
@@ -0,0 +1,238 @@
+---
+title: Docker
+description: Docker Configuration
+---
+
+Docker instances are configured inside the `docker.yaml` file. Both IP:PORT and Socket connections are supported.
+
+For IP:PORT, simply make sure your Docker instance [has been configured](https://gist.github.com/styblope/dc55e0ad2a9848f2cc3307d4819d819f) to accept API traffic over the HTTP API.
+
+```yaml
+my-remote-docker:
+ host: 192.168.0.101
+ port: 2375
+```
+
+## Using Docker TLS
+
+Since Docker supports connecting with TLS and client certificate authentication, you can include TLS details when connecting to the HTTP API. Further details of setting up Docker to accept TLS connections, and generation of the keys and certs can be found [in the Docker documentation](https://docs.docker.com/engine/security/protect-access/#use-tls-https-to-protect-the-docker-daemon-socket). The file entries are relative to the `config` directory (location of `docker.yaml` file).
+
+```yaml
+my-remote-docker:
+ host: 192.168.0.101
+ port: 275
+ tls:
+ keyFile: tls/key.pem
+ caFile: tls/ca.pem
+ certFile: tls/cert.pem
+```
+
+## Using Docker Socket Proxy
+
+Due to security concerns with exposing the docker socket directly, you can use a [docker-socket-proxy](https://github.com/Tecnativa/docker-socket-proxy) container to expose the docker socket on a more restricted and secure API.
+
+Here is an example docker-compose file that will expose the docker socket, and then connect to it from the homepage container:
+
+```yaml
+dockerproxy:
+ image: ghcr.io/tecnativa/docker-socket-proxy:latest
+ container_name: dockerproxy
+ environment:
+ - CONTAINERS=1 # Allow access to viewing containers
+ - SERVICES=1 # Allow access to viewing services (necessary when using Docker Swarm)
+ - TASKS=1 # Allow access to viewing tasks (necessary when using Docker Swarm)
+ - POST=0 # Disallow any POST operations (effectively read-only)
+ ports:
+ - 127.0.0.1:2375:2375
+ volumes:
+ - /var/run/docker.sock:/var/run/docker.sock:ro # Mounted as read-only
+ restart: unless-stopped
+
+homepage:
+ image: ghcr.io/gethomepage/homepage:latest
+ container_name: homepage
+ volumes:
+ - /path/to/config:/app/config
+ ports:
+ - 3000:3000
+ restart: unless-stopped
+```
+
+Then, inside of your `docker.yaml` settings file, you'd configure the docker instance like so:
+
+```yaml
+my-docker:
+ host: dockerproxy
+ port: 2375
+```
+
+## Using Socket Directly
+
+If you'd rather use the socket directly, first make sure that you're passing the local socket into the Docker container.
+
+!!! note
+
+ In order to use the socket directly homepage must be running as root
+
+```yaml
+homepage:
+ image: ghcr.io/gethomepage/homepage:latest
+ container_name: homepage
+ volumes:
+ - /path/to/config:/app/config
+ - /var/run/docker.sock:/var/run/docker.sock # pass local proxy
+ ports:
+ - 3000:3000
+ restart: unless-stopped
+```
+
+If you're using `docker run`, this would be `-v /var/run/docker.sock:/var/run/docker.sock`.
+
+Then, inside of your `docker.yaml` settings file, you'd configure the docker instance like so:
+
+```yaml
+my-docker:
+ socket: /var/run/docker.sock
+```
+
+## Services
+
+Once you've configured your docker instances, you can then apply them to your services, to get stats and status reporting shown.
+
+Inside of the service you'd like to connect to docker:
+
+```yaml
+- Emby:
+ icon: emby.png
+ href: "http://emby.home/"
+ description: Media server
+ server: my-docker # The docker server that was configured
+ container: emby # The name of the container you'd like to connect
+```
+
+## Automatic Service Discovery
+
+Homepage features automatic service discovery for containers with the proper labels attached, all configuration options can be applied using dot notation, beginning with `homepage`.
+
+Below is an example of the same service entry shown above, as docker labels.
+
+```yaml
+services:
+ emby:
+ image: lscr.io/linuxserver/emby:latest
+ container_name: emby
+ ports:
+ - 8096:8096
+ restart: unless-stopped
+ labels:
+ - homepage.group=Media
+ - homepage.name=Emby
+ - homepage.icon=emby.png
+ - homepage.href=http://emby.home/
+ - homepage.description=Media server
+```
+
+When your Docker instance has been properly configured, this service will be automatically discovered and added to your Homepage. **You do not need to specify the `server` or `container` values, as they will be automatically inferred.**
+
+**When using docker swarm use _deploy/labels_**
+
+## Widgets
+
+You may also configure widgets, along with the standard service entry, again, using dot notation.
+
+```yaml
+labels:
+ - homepage.group=Media
+ - homepage.name=Emby
+ - homepage.icon=emby.png
+ - homepage.href=http://emby.home/
+ - homepage.description=Media server
+ - homepage.widget.type=emby
+ - homepage.widget.url=http://emby.home
+ - homepage.widget.key=yourembyapikeyhere
+ - homepage.widget.fields=["field1","field2"] # optional
+```
+
+You can add specify fields for e.g. the [CustomAPI](../widgets/services/customapi.md) widget by using array-style dot notation:
+
+```yaml
+labels:
+ - homepage.group=Media
+ - homepage.name=Emby
+ - homepage.icon=emby.png
+ - homepage.href=http://emby.home/
+ - homepage.description=Media server
+ - homepage.widget.type=customapi
+ - homepage.widget.url=http://argus.service/api/v1/service/summary/emby
+ - homepage.widget.field[0].label=Deployed Version
+ - homepage.widget.field[0].field.status=deployed_version
+ - homepage.widget.field[1].label=Latest Version
+ - homepage.widget.field[1].field.status=latest_version
+```
+
+## Docker Swarm
+
+Docker swarm is supported and Docker services are specified with the same `server` and `container` notation. To enable swarm support you will need to include a `swarm` setting in your docker.yaml, e.g.
+
+```yaml
+my-docker:
+ socket: /var/run/docker.sock
+ swarm: true
+```
+
+For the automatic service discovery to discover all services it is important that homepage should be deployed on a manager node. Set deploy requirements to the master node in your stack yaml config, e.g.
+
+```yaml
+....
+ deploy:
+ placement:
+ constraints:
+ - node.role == manager
+...
+```
+
+In order to detect every service within the Docker swarm it is necessary that service labels should be used and not container labels. Specify the homepage labels as:
+
+```yaml
+....
+ deploy:
+ labels:
+ - homepage.icon=foobar
+...
+```
+
+## Multiple Homepage Instances
+
+The optional field `instanceName` can be configured in [settings.md](settings.md#instance-name) to differentiate between multiple homepage instances.
+
+To limit a label to an instance, insert `.instance.{{instanceName}}` after the `homepage` prefix.
+
+```yaml
+labels:
+ - homepage.group=Media
+ - homepage.name=Emby
+ - homepage.icon=emby.png
+ - homepage.instance.internal.href=http://emby.lan/
+ - homepage.instance.public.href=https://emby.mydomain.com/
+ - homepage.description=Media server
+```
+
+## Ordering
+
+As of v0.6.4 discovered services can include an optional `weight` field to determine sorting such that:
+
+- Default weight for discovered services is 0
+- Default weight for configured services is their index within their group scaled by 100, i.e. (index + 1) \* 100
+- If two items have the same weight value, then they will be sorted by name
+
+## Show stats
+
+You can show the docker stats by clicking the status indicator but this can also be controlled per-service with:
+
+```yaml
+- Example Service:
+ ...
+ showStats: true
+```
+
+Also see the settings for [show docker stats](docker.md#show-docker-stats).
diff --git a/docs/configs/index.md b/docs/configs/index.md
new file mode 100644
index 00000000..a43977f6
--- /dev/null
+++ b/docs/configs/index.md
@@ -0,0 +1,16 @@
+---
+title: Configuration
+description: Homepage Configuration
+---
+
+Homepage uses YAML for configuration, YAML stands for "YAML Ain't Markup Language.". It's a human-readable data serialization format that's a superset of JSON. Great for config files, easy to read and write. Supports complex data types like lists and objects. **Indentation matters.** If you already use Docker Compose, you already use YAML.
+
+Here are some tips when writing YAML:
+
+1. **Use Indentation Carefully**: YAML relies on indentation, not brackets.
+2. Avoid Tabs: Stick to spaces for indentation to avoid parsing errors. 2 spaces are common.
+3. Quote Strings: Use single or double quotes for strings with special characters, this is especially important for API keys.
+4. Key-Value Syntax: Use key: value format. Colon must be followed by a space.
+5. Validate: Always validate your YAML with a linter before deploying.
+
+You can find tons of online YAML validators, here's one: [https://codebeautify.org/yaml-validator](https://codebeautify.org/yaml-validator), heres another: [https://jsonformatter.org/yaml-validator](https://jsonformatter.org/yaml-validator).
diff --git a/docs/configs/kubernetes.md b/docs/configs/kubernetes.md
new file mode 100644
index 00000000..c1777612
--- /dev/null
+++ b/docs/configs/kubernetes.md
@@ -0,0 +1,139 @@
+---
+title: Kubernetes
+description: Kubernetes Configuration
+---
+
+The Kubernetes connectivity has the following requirements:
+
+- Kubernetes 1.19+
+- Metrics Service
+- An Ingress controller
+
+The Kubernetes connection is configured in the `kubernetes.yaml` file. There are 3 modes to choose from:
+
+- **disabled** - disables kubernetes connectivity
+- **default** - uses the default kubeconfig [resolution](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/)
+- **cluster** - uses a service account inside the cluster
+
+```yaml
+mode: default
+```
+
+## Services
+
+Once the Kubernetes connection is configured, individual services can be configured to pull statistics. Only CPU and Memory are currently supported.
+
+Inside of the service you'd like to connect to a pod:
+
+```yaml
+- Emby:
+ icon: emby.png
+ href: "http://emby.home/"
+ description: Media server
+ namespace: media # The kubernetes namespace the app resides in
+ app: emby # The name of the deployed app
+```
+
+The `app` field is used to create a label selector, in this example case it would match pods with the label: `app.kubernetes.io/name=emby`.
+
+Sometimes this is insufficient for complex or atypical application deployments. In these cases, the `pod-selector` field can be used. Any field selector can be used with it, so it allows for some very powerful selection capabilities.
+
+For instance, it can be utilized to roll multiple underlying deployments under one application to see a high-level aggregate:
+
+```yaml
+- Element Chat:
+ icon: matrix-light.png
+ href: https://chat.example.com
+ description: Matrix Synapse Powered Chat
+ app: matrix-element
+ namespace: comms
+ pod-selector: >-
+ app.kubernetes.io/instance in (
+ matrix-element,
+ matrix-media-repo,
+ matrix-media-repo-postgresql,
+ matrix-synapse
+ )
+```
+
+!!! note
+
+ A blank string as a pod-selector does not deactivate it, but will actually select all pods in the namespace. This is a useful way to capture the resource usage of a complex application siloed to a single namespace, like Longhorn.
+
+## Automatic Service Discovery
+
+Homepage features automatic service discovery by Ingress annotations. All configuration options can be applied using typical annotation syntax, beginning with `gethomepage.dev/`.
+
+```yaml
+apiVersion: networking.k8s.io/v1
+kind: Ingress
+metadata:
+ name: emby
+ annotations:
+ gethomepage.dev/enabled: "true"
+ gethomepage.dev/description: Media Server
+ gethomepage.dev/group: Media
+ gethomepage.dev/icon: emby.png
+ gethomepage.dev/name: Emby
+ gethomepage.dev/widget.type: "emby"
+ gethomepage.dev/widget.url: "https://emby.example.com"
+ gethomepage.dev/pod-selector: ""
+ gethomepage.dev/weight: 10 # optional
+spec:
+ rules:
+ - host: emby.example.com
+ http:
+ paths:
+ - backend:
+ service:
+ name: emby
+ port:
+ number: 8080
+ path: /
+ pathType: Prefix
+```
+
+When the Kubernetes cluster connection has been properly configured, this service will be automatically discovered and added to your Homepage. **You do not need to specify the `namespace` or `app` values, as they will be automatically inferred.**
+
+### Traefik IngressRoute support
+
+Homepage can also read ingresses defined using the Traefik IngressRoute custom resource definition. Due to the complex nature of Traefik routing rules, it is required for the `gethomepage.dev/href` annotation to be set:
+
+```yaml
+apiVersion: traefik.io/v1alpha1
+kind: IngressRoute
+metadata:
+ name: emby
+ annotations:
+ gethomepage.dev/href: "https://emby.example.com"
+ gethomepage.dev/enabled: "true"
+ gethomepage.dev/description: Media Server
+ gethomepage.dev/group: Media
+ gethomepage.dev/icon: emby.png
+ gethomepage.dev/app: emby-app # optional, may be needed if app.kubernetes.io/name != ingress metadata.name
+ gethomepage.dev/name: Emby
+ gethomepage.dev/widget.type: "emby"
+ gethomepage.dev/widget.url: "https://emby.example.com"
+ gethomepage.dev/pod-selector: ""
+ gethomepage.dev/weight: 10 # optional
+spec:
+ entryPoints:
+ - websecure
+ routes:
+ - kind: Rule
+ match: Host(`emby.example.com`)
+ services:
+ - kind: Service
+ name: emby
+ namespace: emby
+ port: 8080
+ scheme: http
+ strategy: RoundRobin
+ weight: 10
+```
+
+If the `href` attribute is not present, Homepage will ignore the specific IngressRoute.
+
+## Caveats
+
+Similarly to Docker service discovery, there currently is no rigid ordering to discovered services and discovered services will be displayed above those specified in the `services.yaml`.
diff --git a/docs/configs/service-widgets.md b/docs/configs/service-widgets.md
new file mode 100644
index 00000000..9c54964e
--- /dev/null
+++ b/docs/configs/service-widgets.md
@@ -0,0 +1,40 @@
+---
+title: Service Widgets
+description: Service Widget Configuration
+---
+
+Unless otherwise noted, URLs should not end with a `/` or other API path. Each widget will handle the path on its own.
+
+Each service can have one widget attached to it (often matching the service type, but that's not forced).
+
+In addition to the href of the service, you can also specify the target location in which to open that link. See [Link Target](settings.md#link-target) for more details.
+
+Using Emby as an example, this is how you would attach the Emby service widget.
+
+```yaml
+- Emby:
+ icon: emby.png
+ href: http://emby.host.or.ip/
+ description: Movies & TV Shows
+ widget:
+ type: emby
+ url: http://emby.host.or.ip
+ key: apikeyapikeyapikeyapikeyapikey
+```
+
+## Field Visibility
+
+Each widget can optionally provide a list of which fields should be visible via the `fields` widget property. If no fields are specified, then all fields will be displayed. The `fields` property must be a valid YAML array of strings. As an example, here is the entry for Sonarr showing only a couple of fields.
+
+**In all cases a widget will work and display all fields without specifying the `fields` property.**
+
+```yaml
+- Sonarr:
+ icon: sonarr.png
+ href: http://sonarr.host.or.ip
+ widget:
+ type: sonarr
+ fields: ["wanted", "queued"]
+ url: http://sonarr.host.or.ip
+ key: apikeyapikeyapikeyapikeyapikey
+```
diff --git a/docs/configs/services.md b/docs/configs/services.md
new file mode 100644
index 00000000..82e42f67
--- /dev/null
+++ b/docs/configs/services.md
@@ -0,0 +1,208 @@
+---
+title: Services
+description: Service Configuration
+---
+
+Services are configured inside the `services.yaml` file. You can have any number of groups, and any number of services per group.
+
+## Groups
+
+Groups are defined as top-level array entries.
+
+```yaml
+- Group A:
+ - Service A:
+ href: http://localhost/
+
+- Group B:
+ - Service B:
+ href: http://localhost/
+```
+
+
+
+## Services
+
+Services are defined as array entries on groups,
+
+```yaml
+- Group A:
+ - Service A:
+ href: http://localhost/
+
+ - Service B:
+ href: http://localhost/
+
+ - Service C:
+ href: http://localhost/
+
+- Group B:
+ - Service D:
+ href: http://localhost/
+```
+
+
+
+## Descriptions
+
+Services may have descriptions,
+
+```yaml
+- Group A:
+ - Service A:
+ href: http://localhost/
+ description: This is my service
+
+- Group B:
+ - Service B:
+ href: http://localhost/
+ description: This is another service
+```
+
+
+
+## Icons
+
+Services may have an icon attached to them, you can use icons from [Dashboard Icons](https://github.com/walkxcode/dashboard-icons) automatically, by passing the name of the icon, with, or without `.png` or with `.svg` to use the svg version.
+
+You can also specify prefixed icons from [Material Design Icons](https://materialdesignicons.com) with `mdi-XX` or [Simple Icons](https://simpleicons.org/) with `si-XX`.
+
+You can specify a custom color by adding a hex color code as suffix e.g. `mdi-XX-#f0d453` or `si-XX-#a712a2`.
+
+To use a remote icon, use the absolute URL (e.g. `https://...`).
+
+To use a local icon, first create a Docker mount to `/app/public/icons` and then reference your icon as `/icons/myicon.png`. You will need to restart the container when adding new icons.
+
+!!! warning
+
+ Material Design Icons for **brands** were deprecated and may be removed in the future. Using Simple Icons for brand icons will prevent any issues if / when the Material Design Icons are removed.
+
+```yaml
+- Group A:
+ - Sonarr:
+ icon: sonarr.png
+ href: http://sonarr.host/
+ description: Series management
+
+- Group B:
+ - Radarr:
+ icon: radarr.png
+ href: http://radarr.host/
+ description: Movie management
+
+- Group C:
+ - Service:
+ icon: mdi-flask-outline
+ href: http://service.host/
+ description: My cool service
+```
+
+
+
+## Ping
+
+Services may have an optional `ping` property that allows you to monitor the availability of an external host. As of v0.8.0, the ping feature attempts to use a true (ICMP) ping command on the underlying host.
+
+```yaml
+- Group A:
+ - Sonarr:
+ icon: sonarr.png
+ href: http://sonarr.host/
+ ping: sonarr.host
+
+- Group B:
+ - Radarr:
+ icon: radarr.png
+ href: http://radarr.host/
+ ping: some.other.host
+```
+
+
+
+You can also apply different styles to the ping indicator by using the `statusStyle` property, see [settings](settings.md#status-style).
+
+## Site Monitor
+
+Services may have an optional `siteMonitor` property (formerly `ping`) that allows you to monitor the availability of a URL you chose and have the response time displayed. You do not need to set your monitor URL equal to your href or ping URL.
+
+!!! note
+
+ The site monitor feature works by making an http `HEAD` request to the URL, and falls back to `GET` in case that fails. It will not, for example, login if the URL requires auth or is behind e.g. Authelia. In the case of a reverse proxy and/or auth this usually requires the use of an 'internal' URL to make the site monitor feature correctly display status.
+
+```yaml
+- Group A:
+ - Sonarr:
+ icon: sonarr.png
+ href: http://sonarr.host/
+ siteMonitor: http://sonarr.host/
+
+- Group B:
+ - Radarr:
+ icon: radarr.png
+ href: http://radarr.host/
+ siteMonitor: http://some.other.host/
+```
+
+You can also apply different styles to the site monitor indicator by using the `statusStyle` property, see [settings](settings.md#status-style).
+
+## Docker Integration
+
+Services may be connected to a Docker container, either running on the local machine, or a remote machine.
+
+```yaml
+- Group A:
+ - Service A:
+ href: http://localhost/
+ description: This is my service
+ server: my-server
+ container: my-container
+
+- Group B:
+ - Service B:
+ href: http://localhost/
+ description: This is another service
+ server: other-server
+ container: other-container
+```
+
+
+
+**Clicking on the status label of a service with Docker integration enabled will expand the container stats, where you can see CPU, Memory, and Network activity.**
+
+!!! note
+
+ This can also be controlled with `showStats`. See [show docker stats](docker.md#show-docker-stats) for more information
+
+
+
+## Service Integrations
+
+Services may also have a service widget (or integration) attached to them, this works independently of the Docker integration.
+
+You can find information and configuration for each of the supported integrations on the [Service Widgets](service-widgets.md) page.
+
+Here is an example of a Radarr & Sonarr service, with their respective integrations.
+
+```yaml
+- Group A:
+ - Sonarr:
+ icon: sonarr.png
+ href: http://sonarr.host/
+ description: Series management
+ widget:
+ type: sonarr
+ url: http://sonarr.host
+ key: apikeyapikeyapikeyapikeyapikey
+
+- Group B:
+ - Radarr:
+ icon: radarr.png
+ href: http://radarr.host/
+ description: Movie management
+ widget:
+ type: radarr
+ url: http://radarr.host
+ key: apikeyapikeyapikeyapikeyapikey
+```
+
+
diff --git a/docs/configs/settings.md b/docs/configs/settings.md
new file mode 100644
index 00000000..fdc5eff2
--- /dev/null
+++ b/docs/configs/settings.md
@@ -0,0 +1,457 @@
+---
+title: Settings
+description: Service Configuration
+---
+
+The `settings.yaml` file allows you to define application level options. For changes made to this file to take effect, you will need to regenerate the static HTML, this can be done by clicking the refresh icon in the bottom right of the page.
+
+## Title
+
+You can customize the title of the page if you'd like.
+
+```yaml
+title: My Awesome Homepage
+```
+
+## Start URL
+
+You can customize the start_url as required for installable apps. The default is "/".
+
+```yaml
+startUrl: https://custom.url
+```
+
+## Background Image
+
+!!! warning "Heads Up!"
+
+ You will need to restart the container any time you add new images, this is a limitation of the Next.js static site server.
+
+!!! warning "Heads Up!"
+
+ Do not create a bind mount to the entire `/app/public/` directory.
+
+If you'd like to use a background image instead of the solid theme color, you may provide a full URL to an image of your choice.
+
+```yaml
+background: https://images.unsplash.com/photo-1502790671504-542ad42d5189?auto=format&fit=crop&w=2560&q=80
+```
+
+Or you may pass the path to a local image relative to e.g. `/app/public/images` directory.
+
+For example, inside of your Docker Compose file, mount a path to where your images are kept:
+
+```yaml
+volumes:
+ - /my/homepage/images:/app/public/images
+```
+
+and then reference that image:
+
+```yaml
+background: /images/background.png
+```
+
+### Background Opacity & Filters
+
+You can specify filters to apply over your background image for blur, saturation and brightness as well as opacity to blend with the background color. The first three filter settings use tailwind CSS classes, see notes below regarding the options for each. You do not need to specify all options.
+
+```yaml
+background:
+ image: /images/background.png
+ blur: sm # sm, "", md, xl... see https://tailwindcss.com/docs/backdrop-blur
+ saturate: 50 # 0, 50, 100... see https://tailwindcss.com/docs/backdrop-saturate
+ brightness: 50 # 0, 50, 75... see https://tailwindcss.com/docs/backdrop-brightness
+ opacity: 50 # 0-100
+```
+
+### Card Background Blur
+
+You can apply a blur filter to the service & bookmark cards. Note this option is incompatible with the background blur, saturate and brightness filters.
+
+```yaml
+cardBlur: sm # sm, "", md, etc... see https://tailwindcss.com/docs/backdrop-blur
+```
+
+## Favicon
+
+If you'd like to use a custom favicon instead of the included one, you may provide a full URL to an image of your choice.
+
+```yaml
+favicon: https://www.google.com/favicon.ico
+```
+
+Or you may pass the path to a local image relative to the `/app/public` directory. See [Background Image](#background-image) for more detailed information on how to provide your own files.
+
+## Theme
+
+You can configure a fixed them (and disable the theme switcher) by passing the `theme` option, like so:
+
+```yaml
+theme: dark # or light
+```
+
+## Color Palette
+
+You can configured a fixed color palette (and disable the palette switcher) by passing the `color` option, like so:
+
+```yaml
+color: slate
+```
+
+Supported colors are: `slate`, `gray`, `zinc`, `neutral`, `stone`, `amber`, `yellow`, `lime`, `green`, `emerald`, `teal`, `cyan`, `sky`, `blue`, `indigo`, `violet`, `purple`, `fuchsia`, `pink`, `rose`, `red`, `white`
+
+## Layout
+
+You can configure service and bookmarks sections to be either "column" or "row" based layouts, like so:
+
+Assuming you have a group named `Media` in your `services.yaml` or `bookmarks.yaml` file,
+
+```yaml
+layout:
+ Media:
+ style: row
+ columns: 4
+```
+
+As an example, this would produce the following layout:
+
+
+
+### Sorting
+
+Service groups and bookmark groups can be mixed in order, **but should use different group names**. If you do not specify any bookmark groups they will all show at the bottom of the page.
+
+**_Using the same name for a service and bookmark group can cause unexpected behavior like a bookmark group being hidden_**
+
+Groups will sort based on the order in the layout block. You can also mix in groups defined by docker labels, e.g.
+
+```yaml
+layout:
+ - Auto-Discovered1:
+ - Configured1:
+ - Configured2:
+ - Auto-Discovered2:
+ - Configured3:
+ style: row
+ columns: 3
+```
+
+### Headers
+
+You can hide headers for each section in the layout as well by passing `header` as false, like so:
+
+```yaml
+layout:
+ Section A:
+ header: false
+ Section B:
+ style: row
+ columns: 3
+ header: false
+```
+
+### Category Icons
+
+You can also add an icon to a category under the `layout` setting similar to the [options for service icons](services.md#icons), e.g.
+
+```yaml
+ Home Management & Info:
+ icon: home-assistant.png
+ Server Tools:
+ icon: https://cdn-icons-png.flaticon.com/512/252/252035.png
+ ...
+```
+
+### Icon Style
+
+The default style for icons (e.g. `icon: mdi-XXXX`) is a gradient, or you can specify that prefixed icons match your theme with a 'flat' style using the setting below.
+More information about prefixed icons can be found in [options for service icons](services.md#icons).
+
+```yaml
+iconStyle: theme # optional, defaults to gradient
+```
+
+### Tabs
+
+Version 0.6.30 introduced a tabbed view to layouts which can be optionally specified in the layout. Tabs is only active if you set the `tab` field on at least one layout group.
+
+Tabs are sorted based on the order in the layout block. If a group has no tab specified (and tabs are set on other groups), services and bookmarks will be shown on all tabs.
+
+Every tab can be accessed directly by visiting Homepage URL with `#Group` (name lowercase and URI-encoded) at the end of the URL.
+
+For example, the following would create four tabs:
+
+```yaml
+layout:
+ ...
+ Bookmark Group on First Tab:
+ tab: First
+
+ First Service Group:
+ tab: First
+ style: row
+ columns: 4
+
+ Second Service Group:
+ tab: Second
+ columns: 4
+
+ Third Service Group:
+ tab: Third
+ style: row
+
+ Bookmark Group on Fourth Tab:
+ tab: Fourth
+
+ Service Group on every Tab:
+ style: row
+ columns: 4
+```
+
+### Five Columns
+
+You can add a fifth column (when `style: columns` which is default) by adding:
+
+```yaml
+fiveColumns: true
+```
+
+By default homepage will max out at 4 columns for column style
+
+### Collapsible sections
+
+You can disable the collapsible feature of services & bookmarks by adding:
+
+```yaml
+disableCollapse: true
+```
+
+By default the feature is enabled.
+
+### Use Equal Height Cards
+
+You can enable equal height cards for groups of services, this will make all cards in a row the same height.
+
+Global setting in `settings.yaml`:
+
+```yaml
+useEqualHeights: true
+```
+
+Per layout group in `settings.yaml`:
+
+```yaml
+useEqualHeights: false
+layout:
+ ...
+ Group Name:
+ useEqualHeights: true # overrides global setting
+```
+
+By default the feature is disabled
+
+## Header Style
+
+There are currently 4 options for header styles, you can see each one below.
+
+
+
+```yaml
+headerStyle: underlined # default style
+```
+
+---
+
+
+
+```yaml
+headerStyle: boxed
+```
+
+---
+
+
+
+```yaml
+headerStyle: clean
+```
+
+---
+
+
+
+```yaml
+headerStyle: boxedWidgets
+```
+
+## Base URL
+
+In some proxy configurations, it may be necessary to set the documents base URL. You can do this by providing a `base` value, like so:
+
+```yaml
+base: http://host.local/homepage
+```
+
+**_The URL must be a full, absolute URL, or it will be ignored by the browser._**
+
+## Language
+
+Set your desired language using:
+
+```yaml
+language: fr
+```
+
+Currently supported languages: ca, de, en, es, fr, he, hr, hu, it, nb-NO, nl, pt, ru, sv, vi, zh-CN, zh-Hant
+
+You can also specify locales e.g. for the DateTime widget, e.g. en-AU, en-GB, etc.
+
+## Link Target
+
+Changes the behaviour of links on the homepage,
+
+```yaml
+target: _blank # Possible options include _blank, _self, and _top
+```
+
+Use `_blank` to open links in a new tab, `_self` to open links in the same tab, and `_top` to open links in a new window.
+
+This can also be set for individual services. Note setting this at the service level overrides any setting in settings.json, e.g.:
+
+```yaml
+- Example Service:
+ href: https://example.com/
+ ...
+ target: _self
+```
+
+## Providers
+
+The `providers` section allows you to define shared API provider options and secrets. Currently this allows you to define your weather API keys in secret and is also the location of the Longhorn URL and credentials.
+
+```yaml
+providers:
+ openweathermap: openweathermapapikey
+ weatherapi: weatherapiapikey
+ longhorn:
+ url: https://longhorn.example.com
+ username: admin
+ password: LonghornPassword
+```
+
+You can then pass `provider` instead of `apiKey` in your widget configuration.
+
+```yaml
+- weather:
+ latitude: 50.449684
+ longitude: 30.525026
+ provider: weatherapi
+```
+
+## Quick Launch
+
+You can use the 'Quick Launch' feature to search services, perform a web search or open a URL. To use Quick Launch, just start typing while on your homepage (as long as the search widget doesn't have focus).
+
+
+
+There are a few optional settings for the Quick Launch feature:
+
+- `searchDescriptions`: which lets you control whether item descriptions are included in searches. This is off by default. When enabled, results that match the item name will be placed above those that only match the description.
+- `hideInternetSearch`: disable automatically including the currently-selected web search (e.g. from the widget) as a Quick Launch option. This is false by default, enabling the feature.
+- `hideVisitURL`: disable detecting and offering an option to open URLs. This is false by default, enabling the feature.
+
+```yaml
+quicklaunch:
+ searchDescriptions: true
+ hideInternetSearch: true
+ hideVisitURL: true
+```
+
+## Homepage Version
+
+By default the release version is displayed at the bottom of the page. To hide this, use the `hideVersion` setting, like so:
+
+```yaml
+hideVersion: true
+```
+
+## Log Path
+
+By default the homepage logfile is written to the a `logs` subdirectory of the `config` folder. In order to customize this path, you can set the `logpath` setting. A `logs` folder will be created in that location where the logfile will be written.
+
+```yaml
+logpath: /logfile/path
+```
+
+## Show Docker Stats
+
+You can show all docker stats expanded in `settings.yaml`:
+
+```yaml
+showStats: true
+```
+
+or per-service (`services.yaml`) with:
+
+```yaml
+- Example Service:
+ ...
+ showStats: true
+```
+
+If you have both set the per-service settings take precedence.
+
+## Status Style
+
+You can choose from the following styles for docker or k8s status, site monitor and ping: `dot` or `basic`
+
+- The default is no value, and displays the monitor and ping response time in ms and the docker / k8s container status
+- `dot` shows a green dot for a successful monitor ping or healthy status.
+- `basic` shows either UP or DOWN for monitor & ping
+
+For example:
+
+```yaml
+statusStyle: "dot"
+```
+
+or per-service (`services.yaml`) with:
+
+```yaml
+- Example Service:
+ ...
+ statusStyle: 'dot'
+```
+
+If you have both set, the per-service settings take precedence.
+
+## Instance Name
+
+Name used by automatic docker service discovery to differentiate between multiple homepage instances.
+
+For example:
+
+```yaml
+instanceName: public
+```
+
+## Hide Widget Error Messages
+
+Hide the visible API error messages either globally in `settings.yaml`:
+
+```yaml
+hideErrors: true
+```
+
+or per service widget (`services.yaml`) with:
+
+```yaml
+- Example Service:
+ ...
+ widget:
+ ...
+ hideErrors: true
+```
+
+If either value is set to true, the error message will be hidden.
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 00000000..97a3704b
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,19 @@
+---
+title: Home
+hide:
+ - navigation
+ - toc
+ - path
+---
+
+#
+
+
+
+
+
+
+
+A modern, fully static, fast, secure fully proxied, highly customizable application dashboard with integrations for over 100 services and translations into multiple languages. Easily configured via YAML files or through docker label discovery.
+
+
diff --git a/docs/installation/docker.md b/docs/installation/docker.md
new file mode 100644
index 00000000..1f9f07d6
--- /dev/null
+++ b/docs/installation/docker.md
@@ -0,0 +1,57 @@
+---
+title: Docker Installation
+description: Install and run homepage from Docker
+---
+
+Using docker compose:
+
+```yaml
+version: "3.3"
+services:
+ homepage:
+ image: ghcr.io/gethomepage/homepage:latest
+ container_name: homepage
+ ports:
+ - 3000:3000
+ volumes:
+ - /path/to/config:/app/config # Make sure your local config directory exists
+ - /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations
+```
+
+### Running as non-root
+
+By default, the Homepage container runs as root. Homepage also supports running your container as non-root via the standard `PUID` and `PGID` environment variables. When using these variables, make sure that any volumes mounted in to the container have the correct ownership and permissions set.
+
+_Using the docker socket directly is not the recommended method of integration and requires either running homepage as root or that the user be part of the docker group_
+
+In the docker compose example below, the environment variables `$PUID` and `$PGID` are set in a `.env` file.
+
+```yaml
+version: "3.3"
+services:
+ homepage:
+ image: ghcr.io/gethomepage/homepage:latest
+ container_name: homepage
+ ports:
+ - 3000:3000
+ volumes:
+ - /path/to/config:/app/config # Make sure your local config directory exists
+ - /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations, see alternative methods
+ environment:
+ PUID: $PUID
+ PGID: $PGID
+```
+
+### With Docker Run
+
+```bash
+docker run -p 3000:3000 -v /path/to/config:/app/config -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/gethomepage/homepage:latest
+```
+
+### Using Environment Secrets
+
+You can also include environment variables in your config files to protect sensitive information. Note:
+
+- Environment variables must start with `HOMEPAGE_VAR_` or `HOMEPAGE_FILE_`
+- The value of env var `HOMEPAGE_VAR_XXX` will replace `{{HOMEPAGE_VAR_XXX}}` in any config
+- The value of env var `HOMEPAGE_FILE_XXX` must be a file path, the contents of which will be used to replace `{{HOMEPAGE_FILE_XXX}}` in any config
diff --git a/docs/installation/index.md b/docs/installation/index.md
new file mode 100644
index 00000000..f1d317c4
--- /dev/null
+++ b/docs/installation/index.md
@@ -0,0 +1,25 @@
+---
+title: Installation
+description: Docs intro
+---
+
+
+You have a few options for deploying homepage, depending on your needs. We offer docker images for a majority of platforms. You can also install and run homepage from source if Docker is not your thing. It can even be installed on Kubernetes with Helm.
+
+
+
+
+
+:simple-docker: [ Install on Docker :octicons-arrow-right-24:](docker.md)
+{ .card }
+
+:simple-kubernetes: [ Install on Kubernetes :octicons-arrow-right-24:](k8s.md)
+{ .card }
+
+:simple-unraid: [ Install on UNRAID :octicons-arrow-right-24:](unraid.md)
+{ .card }
+
+:simple-nextdotjs: [ Building from source :octicons-arrow-right-24:](source.md)
+{ .card }
+
+