commit ee165e682d3943b20fc9aa3ee074e1e4ace4b3ac Author: Beda Schmid Date: Thu Aug 6 19:09:25 2026 +0000 Reset history to current sanitized state diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..aa791bf --- /dev/null +++ b/.gitignore @@ -0,0 +1,27 @@ +# ---> VisualStudioCode +.vscode/* +!.vscode/settings.json +!.vscode/tasks.json +!.vscode/launch.json +!.vscode/extensions.json +!.vscode/*.code-snippets + +# Local History for Visual Studio Code +.history/ + +# Built Visual Studio Code Extensions +*.vsix + +*.swp +.DS_Store + +# BEGIN reset-history environment exclusions +.env +.env.* +*.env +*.env.* +!.env.example +!.env.*.example +!*.env.example +!*.env.*.example +# END reset-history environment exclusions diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..efb9808 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to diff --git a/README.md b/README.md new file mode 100644 index 0000000..e32f641 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# Homepage + +Homepage provides a customizable homelab dashboard with service links, status widgets, and infrastructure +integrations. + +## Deployment layout + +- **Compose:** `/srv/docker/homepage/docker-compose.yml` +- **Static configuration/source:** `/srv/docker/homepage/config` for sanitized YAML, CSS, and JavaScript; `/srv/docker/homepage/images` for static dashboard images +- **Non-secret environment:** allowed host `heimdall.lan` and IPv6 proxy disabling are declared inline in +Compose +- **Secrets:** `/srv/docker/secrets/homepage/.env` +- **NVMe application state:** `/srv/appdata/homepage/logs` and `/srv/appdata/homepage/report` +- **Bulk HDD data:** none +- **Other mounts:** `/var/run/docker.sock` read-only for Docker integration and `/data/Data1` read-only for +shared storage visibility + +Secrets are never committed to this repository. The central secret environment +is supplied to the Homepage service; sanitized YAML configuration references +its widget and integration credentials through `HOMEPAGE_VAR_*` placeholders. + +## Dependencies and recovery + +- **Networks/dependencies:** Homepage uses the external `npm_proxy` network at `192.168.96.11`; Docker +integration depends on the read-only Docker socket, storage reporting can use the read-only `/data/Data1` +mount, and configured widgets depend on their respective external services +- **Back up:** `/srv/docker/homepage/config`, `/srv/docker/homepage/images`, and the separately protected +Homepage secret environment +- **Re-creatable:** the Homepage container image and `/srv/appdata/homepage/logs` and `/srv/appdata/homepage/report` diff --git a/config/bookmarks.yaml b/config/bookmarks.yaml new file mode 100644 index 0000000..0bd0993 --- /dev/null +++ b/config/bookmarks.yaml @@ -0,0 +1,4 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/bookmarks + diff --git a/config/custom.css b/config/custom.css new file mode 100644 index 0000000..54c8e22 --- /dev/null +++ b/config/custom.css @@ -0,0 +1,377 @@ +/** + * iOS 26 Liquid Glass Theme for Homepage + * @author Kernyx64 + */ + +@import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap'); + +:root { + --font-primary: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; + --font-mono: 'SF Mono', Consolas, Monaco, monospace; + --glass-bg: rgba(255, 255, 255, 0.05); + --glass-hover: rgba(255, 255, 255, 0.08); + --glass-border: rgba(255, 255, 255, 0.11); + --glass-border-hover: rgba(255, 255, 255, 0.15); + --text-primary: rgba(255, 255, 255, 1); + --text-secondary: rgba(255, 255, 255, 0.85); + --blur: 20px; + --radius: 20px; + --radius-sm: 16px; + --transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); +} + +/* Global Styles */ +body { overflow-x: hidden; min-height: 100vh; position: relative; } +body::before { content: ''; position: fixed; inset: 0; background: rgba(0, 0, 0, 0.35); z-index: -2; } +* { font-family: var(--font-primary) !important; font-weight: 500; -webkit-font-smoothing: antialiased; } +.widget-stat-value, .text-xs, .ping-status { font-family: var(--font-mono) !important; font-weight: 600; } + +/* Glass Base Mixin */ +.service-card, +button[id$='-tab'], +.widget, +.widget-stat, +.bg-theme-200\/50, +.flex-1.service-block, +.flex.flex-col.mt-3.bookmark-list { + backdrop-filter: blur(var(--blur)) saturate(150%); + -webkit-backdrop-filter: blur(var(--blur)) saturate(150%); + transition: var(--transition); + border-radius: var(--radius); + position: relative; + overflow: hidden; +} + +/* Navigation Tabs */ +#myTab { padding: 16px; display: flex; justify-content: center; gap: 8px; } +button[id$='-tab'] { + background: var(--glass-bg); + border: 1px solid var(--glass-border); + color: var(--text-primary); + font-size: 15px; + letter-spacing: -0.2px; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1); +} + +button[id$='-tab']::before { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.3), transparent); + transition: left 0.5s ease; +} + +button[id$='-tab']:hover { + background: rgba(255, 255, 255, 0.22); + border-color: rgba(255, 255, 255, 0.35); + transform: translateY(-1px) scale(1.02); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.3); +} + +button[id$='-tab']:hover::before { left: 100%; } + +button[id$='-tab'][aria-selected="true"] { + background: rgba(255, 255, 255, 0.25); + border-color: rgba(255, 255, 255, 0.4); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2), inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 0 20px rgba(255, 255, 255, 0.1); +} + +/* Header */ +.information-widget-logo img { + width: 64px !important; + height: 64px !important; + border-radius: var(--radius-sm); + box-shadow: 0 8px 25px rgba(0, 0, 0, 0.15), 0 0 15px rgba(255, 255, 255, 0.1); + transition: var(--transition); +} + +.information-widget-logo img:hover { + transform: scale(1.05); + box-shadow: 0 12px 35px rgba(0, 0, 0, 0.2), 0 0 25px rgba(255, 255, 255, 0.15); +} + +.information-widget-logo + .information-widget-greeting span { + font-weight: 700 !important; + color: var(--text-primary) !important; + font-size: 28px !important; + letter-spacing: -0.8px; + text-shadow: 0 2px 20px rgba(0, 0, 0, 0.3); +} + +/* Service Cards */ +.service-card { + background: var(--glass-bg) !important; + border: 1px solid var(--glass-border) !important; + box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.1) !important; +} + +.service-card::before { + content: ''; + position: absolute; + top: 0; + left: 0; + right: 0; + height: 50%; + background: linear-gradient(180deg, rgba(255, 255, 255, 0.05) 0%, transparent 100%); + border-radius: var(--radius) var(--radius) 0 0; + pointer-events: none; + z-index: 1; +} + +.service-card::after { + content: ''; + position: absolute; + top: 0; + left: -100%; + width: 100%; + height: 100%; + background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent); + transition: left 0.6s ease; + z-index: 2; + pointer-events: none; +} + +.service-card:hover { + background: var(--glass-hover) !important; + border-color: var(--glass-border-hover) !important; + box-shadow: 0 8px 16px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.15) !important; +} + +.service-card:hover::after { left: 100%; } +.service-card * { position: relative; z-index: 3; } + +/* Internal Blocks */ +.bg-theme-200\/50, +.flex-1.service-block { + background: rgba(255, 255, 255, 0.08) !important; + border-radius: var(--radius-sm); + border: 1px solid rgba(255, 255, 255, 0.15); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(0, 0, 0, 0.05); +} + +.service-card:hover [class*="bg-theme-200/50"], +.service-card:hover .flex-1.service-block { + background: rgba(255, 255, 255, 0.12) !important; + border-color: rgba(255, 255, 255, 0.2); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.15), 0 4px 12px rgba(0, 0, 0, 0.08); +} + +/* Widgets */ +.widget { + background: rgba(255, 255, 255, 0.15) !important; + border: 1px solid rgba(255, 255, 255, 0.25) !important; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.widget:hover { + background: rgba(255, 255, 255, 0.22) !important; + border-color: rgba(255, 255, 255, 0.35) !important; + transform: translateY(-1px); + box-shadow: 0 12px 40px rgba(0, 0, 0, 0.15), inset 0 1px 0 rgba(255, 255, 255, 0.25); +} + +.widget-stats { + display: grid !important; + grid-template-columns: repeat(auto-fit, minmax(80px, 1fr)) !important; + gap: 8px !important; + margin-top: 8px !important; +} + +.widget-stat { + background: rgba(255, 255, 255, 0.08) !important; + border: 1px solid rgba(255, 255, 255, 0.15) !important; + border-radius: var(--radius-sm) !important; + text-align: center !important; + padding: 8px !important; + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 2px 8px rgba(0, 0, 0, 0.05); +} + +.widget-stat:hover { + background: rgba(255, 255, 255, 0.12) !important; + border-color: rgba(255, 255, 255, 0.2) !important; + transform: scale(1.02); +} + +.widget-stat-value { + font-size: 15px !important; + font-weight: 700 !important; + color: var(--text-primary) !important; + text-shadow: 0 1px 3px rgba(0, 0, 0, 0.2); +} + +.widget-stat-label { + font-size: 11px !important; + color: var(--text-secondary) !important; + margin-top: 4px !important; + text-transform: uppercase; + letter-spacing: 0.5px; + font-weight: 600; +} + +/* Status Dots */ +.status-dot { + width: 8px !important; + height: 8px !important; + border-radius: 50% !important; + margin-left: auto !important; + margin-right: 12px !important; + flex-shrink: 0 !important; + position: relative; +} + +.status-dot::before { + content: ''; + position: absolute; + inset: -3px; + border-radius: 50%; + background: currentColor; + opacity: 0.3; + filter: blur(4px); + animation: pulse 2s ease-in-out infinite; +} + +.ping-up { background-color: #30d158; box-shadow: 0 0 8px #30d158; } +.ping-down { background-color: #ff453a; box-shadow: 0 0 8px #ff453a; } +.ping-warning { background-color: #ffd60a; box-shadow: 0 0 8px #ffd60a; } + +@keyframes pulse { + 0%, 100% { transform: scale(1); opacity: 0.3; } + 50% { transform: scale(1.1); opacity: 0.5; } +} + +/* Typography */ +.service-title { + font-weight: 700 !important; + color: var(--text-primary) !important; + font-size: 16px !important; + letter-spacing: -0.3px; + text-shadow: 0 1px 6px rgba(0, 0, 0, 0.3); +} + +.service-description { + color: var(--text-secondary) !important; + font-size: 13px !important; + font-weight: 500; + letter-spacing: -0.1px; + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); +} + +.text-sm { + white-space: pre-line; + text-align: center; + font-size: 14px; + color: var(--text-secondary); + font-weight: 500; + letter-spacing: -0.1px; + text-shadow: 0 1px 4px rgba(0, 0, 0, 0.25); +} + +/* Bookmarks */ +.flex.flex-col.mt-3.bookmark-list { + background: rgba(255, 255, 255, 0.15); + border: 1px solid rgba(255, 255, 255, 0.25); + padding: 16px 12px; + margin-bottom: 12px; + box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1), inset 0 1px 0 rgba(255, 255, 255, 0.2); +} + +.bookmark-icon { + background: rgba(255, 255, 255, 0.08) !important; + border-radius: var(--radius-sm); + border: 1px solid rgba(255, 255, 255, 0.15); +} + +/* Layout */ +:is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="HOME-tab"])) #layout-groups { + display: grid !important; + grid-template-columns: repeat(4, 1fr) !important; + gap: 16px !important; + align-items: start !important; +} + +:is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="HOME-tab"])) #layout-groups > .services-group { + display: flex !important; + flex-direction: column !important; +} + +:is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="HOME-tab"])) .services { + display: flex !important; + flex-direction: column !important; + gap: 16px !important; +} + +:is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="STAT-tab"])) #layout-groups { + display: flex; + flex-wrap: wrap; + gap: 16px !important; + padding: 16px; +} + +:is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="STAT-tab"])) #layout-groups > .services-group { + flex: 1 1 calc(33.33% - 11px) !important; + max-width: calc(33.33% - 11px) !important; +} + +/* Scrollbar */ +::-webkit-scrollbar { width: 8px; height: 8px; } +::-webkit-scrollbar-track { background: rgba(255, 255, 255, 0.05); border-radius: 4px; } +::-webkit-scrollbar-thumb { background: rgba(255, 255, 255, 0.15); border-radius: 4px; backdrop-filter: blur(8px); } +::-webkit-scrollbar-thumb:hover { background: rgba(255, 255, 255, 0.25); } + +/* Overrides */ +.p-1 { padding: 0.5rem !important; } +.bg-theme-100\/20 { background-color: transparent !important; } + +/* Fix conteneur externe des service cards - Version qui marchait */ +.services > div { + background: transparent !important; + border: none !important; + border-radius: 0 !important; + box-shadow: none !important; + padding: 0 !important; +} + +/* Service cards - Rétablir le style glass correct */ +.service-card { + background: var(--glass-bg) !important; + border: 1px solid var(--glass-border) !important; + border-radius: var(--radius) !important; + backdrop-filter: blur(var(--blur)) saturate(173%) !important; + -webkit-backdrop-filter: blur(var(--blur)) saturate(150%) !important; + box-shadow: + 0 4px 6px rgba(0, 0, 0, 0.1), + inset 0 1px 0 rgba(255, 255, 255, 0.1) !important; +} + +/* Animations */ +@media (prefers-reduced-motion: no-preference) { + .service-card, .widget, button[id$='-tab'] { animation: fadeIn 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) backwards; } + .service-card:nth-child(1) { animation-delay: 0.1s; } + .service-card:nth-child(2) { animation-delay: 0.15s; } + .service-card:nth-child(3) { animation-delay: 0.2s; } + .service-card:nth-child(4) { animation-delay: 0.25s; } +} + +@keyframes fadeIn { + from { opacity: 0; transform: translateY(20px); } + to { opacity: 1; transform: translateY(0); } +} + +/* Responsive */ +@media (max-width: 1024px) { + :is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="HOME-tab"])) #layout-groups { grid-template-columns: repeat(2, 1fr) !important; } + :root { --blur: 16px; } +} + +@media (max-width: 768px) { + :is([id="inner_wrapper"]:has(#tabs [aria-selected="true"][id="HOME-tab"])) #layout-groups { grid-template-columns: 1fr !important; padding: 12px; } + .service-card { min-height: 80px !important; } + .service-title { font-size: 17px !important; } + .service-description { font-size: 14px !important; } + button[id$='-tab'] { padding: 8px 24px; font-size: 14px; } + :root { --blur: 12px; } +} + diff --git a/config/custom.js b/config/custom.js new file mode 100644 index 0000000..e69de29 diff --git a/config/docker.yaml b/config/docker.yaml new file mode 100644 index 0000000..96f84b5 --- /dev/null +++ b/config/docker.yaml @@ -0,0 +1,12 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/docker/ + +# my-docker: +# host: 127.0.0.1 +# port: 2375 + +# my-docker: +# socket: /var/run/docker.sock +nautilus: + socket: /var/run/docker.sock diff --git a/config/kubernetes.yaml b/config/kubernetes.yaml new file mode 100644 index 0000000..aca6e82 --- /dev/null +++ b/config/kubernetes.yaml @@ -0,0 +1,2 @@ +--- +# sample kubernetes config diff --git a/config/logs/.gitkeep b/config/logs/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/proxmox.yaml b/config/proxmox.yaml new file mode 100644 index 0000000..9fd1836 --- /dev/null +++ b/config/proxmox.yaml @@ -0,0 +1,4 @@ +--- +# url: https://proxmox.host.or.ip:8006 +# token: username@pam!Token ID +# secret: secret diff --git a/config/report/.gitkeep b/config/report/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/config/services.yaml b/config/services.yaml new file mode 100644 index 0000000..e608c87 --- /dev/null +++ b/config/services.yaml @@ -0,0 +1,403 @@ +- Media: + - Jellyfin: + href: 'https://movies.lan' + description: Media server + server: nautilus + icon: jellyfin + container: jellyfin + widget: + type: jellyfin + url: 'http://jellyfin:8096' + key: "{{HOMEPAGE_VAR_JELLYFIN_KEY}}" + enableBlocks: true + enableNowPlaying: true + enableUser: true + showEpisodeNumber: true + expandOneStreamToTwoRows: false + - Seerr: + href: 'http://seerr.lan' + description: Media discovery + server: nautilus + icon: jellyseerr + container: seerr + widget: + type: seerr + url: 'http://seerr:5055' + key: "{{HOMEPAGE_VAR_SEERR_KEY}}" + - Radarr: + href: 'http://radarr.lan' + description: Movie automation + icon: radarr + container: radarr + server: nautilus + widget: + type: radarr + url: 'http://radarr:7878' + key: "{{HOMEPAGE_VAR_RADARR_KEY}}" + enableQueue: true + - Sonarr: + href: 'http://sonarr.lan' + description: Series automation + container: sonarr + icon: sonarr + server: nautilus + widget: + type: sonarr + url: 'http://sonarr:8989' + key: "{{HOMEPAGE_VAR_SONARR_KEY}}" + enableQueue: true + - Bazarr: + href: 'https://bazarr.lan' + description: Subtitles automation + container: bazarr + icon: bazarr + server: nautilus + widget: + type: bazarr + url: 'http://bazarr:6767' + key: "{{HOMEPAGE_VAR_BAZARR_KEY}}" + - Lidarr: + href: 'http://lidarr.lan' + description: Music automation + container: lidarr + icon: lidarr + server: nautilus + widget: + type: lidarr + url: 'http://lidarr:8686' + key: "{{HOMEPAGE_VAR_LIDARR_KEY}}" + - Kapowarr: + href: 'http://kapowarr.lan' + description: Comic automation + container: kapowarr + icon: kapowarr + server: nautilus + - Komga: + href: 'http://comics.lan' + description: Comics + container: komga + icon: komga + server: nautilus + widget: + type: komga + url: 'http://komga:25600' + username: beda@tukutoi.com + password: 1Rabenaasfresser + key: "{{HOMEPAGE_VAR_KOMGA_KEY}}" + - Navidrome: + href: 'http://music.lan' + description: Music streaming + container: navidrome + icon: navidrome + server: nautilus + widget: + type: navidrome + url: 'http://navidrome:4533' + user: smileBeda + token: "{{HOMEPAGE_VAR_NAVIDROME_KEY}}" + salt: 32djas7 + - Immich: + href: 'https://photos.lan' + description: Photo Repository + container: immich_server + icon: immich + server: nautilus + widget: + type: immich + url: 'http://immich-server:2283' + key: "{{HOMEPAGE_VAR_IMMICH_KEY}}" + version: 2 + - SABnzbd: + href: 'http://sabnzbd.lan' + description: Usenet downloader + container: sabnzbd + icon: sabnzbd + server: nautilus + widget: + type: sabnzbd + url: 'http://sabnzbd:8080' + key: "{{HOMEPAGE_VAR_SABNZBD_KEY}}" + - Prowlarr: + href: 'http://prowlarr.lan' + description: Indexer Manager + container: prowlarr + icon: prowlarr + server: nautilus + widget: + type: prowlarr + url: 'http://prowlarr:9696' + key: "{{HOMEPAGE_VAR_PROWLARR_KEY}}" + - Sonobarr: + icon: mdi-poll-#628ca6 + href: https://lidify.lan + description: Audio Discovery + container: sonobarr + server: nautilus + widget: + type: customapi + url: http://192.168.97.23:5000/api/stats + method: GET + headers: + X-API-Key: "{{HOMEPAGE_VAR_SONOBARR_KEY}}" # Only if API key is configured + mappings: + - field: users.total + label: Total Users + format: number + - field: artist_requests.total + label: Total Requests + format: number + - field: artist_requests.pending + label: Pending + format: number +- Tools: + - Manager: + href: 'http://manager.lan' + description: Book Keeping + container: manager-container + icon: si-cashapp + server: nautilus + - ConvertX: + href: 'https://convertx.lan' + description: File converter + container: convertx + icon: https://convertx.lan/apple-touch-icon.png + server: nautilus + - IT-Tools: + href: 'https://it-tools.lan' + description: Dev toolbox + container: it-tools + icon: it-tools + server: nautilus + - Gitea: + href: 'https://git.yoonect.com' + description: Git hosting + icon: gitea + server: enigmara + - Draw.io: + href: 'http://drawio.lan' + description: Diagramming tool + container: drawio + icon: draw-io + server: nautilus + - Meals: + href: 'https://meals.lan' + description: Recipes + container: mealie + server: nautilus + icon: mealie + widget: + type: mealie + url: 'http://mealie:9000' + key: "{{HOMEPAGE_VAR_MEALIE_KEY}}" + version: 2 + - Atuin: + href: 'https://atuin.lan' + container: atuin-server + server: nautilus + icon: atuin + description: Magical shell history + - Sensai: + href: 'https://sensai.lan' + description: AI assistant + container: open-webui + server: nautilus + icon: open-webui + - Sonar: + href: 'https://sonar.lan' + description: Code quality + container: sonarqube + server: nautilus + icon: sonarqube + - SolidTime: + href: 'https://solidtime.lan' + description: Time tracking + container: solidtime-app-1 + server: nautilus + icon: solidtime + - Nextcloud: + href: 'https://inubes.app' + icon: nextcloud + ping: 'https://inubes.app' + widget: + type: nextcloud + url: 'https://inubes.app' + username: "{{HOMEPAGE_VAR_NEXTCLOUD_USRNAME}}" + password: "{{HOMEPAGE_VAR_NEXTCLOUD_PWD}}" + - Rybbit: + container: rybbit_client + server: nautilus + href: https://analytics.yoonect.com + icon: si-simpleanalytics + ping: https://analytics.yoonect.com/ + - OnionON: + icon: si-customink + container: copilot-actions-api-1 + server: nautilus + - DMARC Sentinel: + href: https://dmarc-sentinel.lan + description: DMARC monitoring + container: dmarc-sentinel + server: nautilus + widget: + type: customapi + url: http://dmarc-sentinel:8000/api/homepage + headers: + Authorization: "{{HOMEPAGE_VAR_DMARC_SENTINEL_AUTH}}" + mappings: + - field: status + label: Status + - field: dmarc_pass_rate + label: Pass + - field: critical_alerts + label: Critical + - field: warnings + label: Warnings + - field: summary + label: Summary +- System: + - Technitium: + href: 'http://dns.lan' + description: DNS manager + container: technitium-dns + icon: technitium + server: nautilus + widget: + type: technitium + url: 'http://technitium-dns:5380' + key: "{{HOMEPAGE_VAR_TECHNITIUM_KEY}}" + range: LastDay + - NPM: + href: 'https://npm.lan' + description: Proxy Manager + container: npm_proxy + server: nautilus + icon: nginx-proxy-manager + widget: + type: npm + url: 'http://npm_proxy:81' + username: "{{HOMEPAGE_VAR_NPM_USRNAME}}" + password: "{{HOMEPAGE_VAR_NPM_PWD}}" + - Uptime Kuma: + href: 'https://yoonect.com' + description: Uptime Status + icon: uptime-kuma + widget: + type: uptimekuma + url: 'https://yoonect.com' + slug: yoonect-services + - Samba: + description: Crossplatform Folder Sync + server: nautilus + container: samba + icon: https://www.samba.org/samba/style/2010/grey/favicon.ico + - Netdata: + href: 'https://netdata.lan' + description: System metrics + server: nautilus + icon: netdata + widget: + type: netdata + url: 'http://192.168.1.3:19999' + - Grafana: + href: 'https://grafana.lan' + description: Sentinel Stats + container: grafana + icon: grafana + widget: + type: grafana + url: http://grafana:3000 + username: admin + password: "{{HOMEPAGE_VAR_GRAFANA_PWD}}" + - Typesense: + href: https://typesense.lan + icon: https://typesense.org/favicon.png + ping: https://typesense.humanofearth.com/health + - ChangeDetection: + href: 'https://changedetection.lan' + description: Change Monitoring + server: nautilus + icon: si-changedetection + container: changedetection + widget: + type: changedetectionio + url: http://192.168.96.15:5000 + key: "{{HOMEPAGE_VAR_CHANGEDETECTION_KEY}}" + - Prometheus: + href: 'https://prometheus.lan' + description: Monitoring System + server: nautilus + icon: si-prometheus + container: prometheus + widget: + type: prometheus + url: http://192.168.96.14:9090 + - Network: + widget: + type: iframe + name: myIframe + src: https://grafana.lan/d-solo/adqj2k4/wg-tunnel-speed?orgId=1&timezone=browser&refresh=auto&panelId=panel-1&__fea> + referrerPolicy: same-origin # optional, no default + allowPolicy: autoplay; fullscreen; gamepad # optional, no default + allowFullscreen: false # optional, default: true + loadingStrategy: eager # optional, default: eager + allowScrolling: no # optional, default: yes + refreshInterval: 0 # optional, no default +- Websites: + - anamaka.net: + href: 'https://anamaka.net' + icon: 'https://anamaka.net/favicon.ico' + siteMonitor: 'https://anamaka.net' + - dynamicpress.org: + href: 'https://dynamicpress.org' + icon: poste + siteMonitor: 'https://dynamicpress.org' + widget: + type: mailcow + url: 'https://mail.dynamicpress.org' + key: "{{HOMEPAGE_VAR_DYNAMICPRESS_KEY}}" + - generateplugins.com: + href: 'https://generateplugins.com' + icon: 'https://generateplugins.com/favicon.ico' + ping: 'https://www.generateplugins.com' + - howthefact.com: + href: 'https://howthefact.com' + icon: 'https://howthefact.com/favicon.svg' + ping: 'https://howthefact.com' + - billing.tukutoi.com: + href: 'https://billing.tukutoi.com' + icon: 'https://tukutoi.com/favicon.ico' + siteMonitor: 'https://billing.tukutoi.com' + - uhlelox.com: + href: 'https://uhlelox.com' + icon: 'https://uhlelox.com/favicon.ico' + siteMonitor: 'https://uhlelox.com' + - undenk.info: + href: 'https://undenk.info' + icon: 'https://undenk.info/favicon.ico' + ping: 'https://undenk.info' + - humanofearth.com: + href: 'https://www.humanofearth.com' + icon: 'https://www.humanofearth.com/favicon.ico' + ping: 'https://humanofearth.com' +- Users: + - PocketID: + icon: sh-pocket-id-light + href: 'https://auth.yoonect.com' + description: Identity Provider + widget: + type: customapi + url: 'https://auth.yoonect.com/api/users' + method: GET + headers: + X-API-KEY: "{{HOMEPAGE_VAR_POCKETID_KEY}}" + mappings: + - label: Users + format: size + refreshInterval: 86400 + siteMonitor: 'https://auth.yoonect.com' + - Mattermost: + icon: mattermost + href: 'https://chat.tukutoi.com' + description: Mattermost Chat + siteMonitor: 'https://chat.tukutoi.com' + diff --git a/config/settings.yaml b/config/settings.yaml new file mode 100644 index 0000000..ab66119 --- /dev/null +++ b/config/settings.yaml @@ -0,0 +1,49 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/settings/ + +title: Heim +description: Nautilus Local Area Network (LAN) Homepage +background: + image: /images/background.png + #blur: xs # sm, "", md, xl... see https://tailwindcss.com/docs/backdrop-blur +# saturate: 63 # 0, 50, 100... see https://tailwindcss.com/docs/backdrop-saturate + # brightness: 63 # 0, 50, 75... see https://tailwindcss.com/docs/backdrop-brightness + # opacity: 21 # 0-100 + # blur: md + opacity: 65 + brightness: 50 +#cardBlur: sm +favicon: /images/favicon.png +color: zinc +theme: dark +layout: + Media: + style: row + columns: 4 + Tools: + style: row + columns: 4 + System: + style: row + columns: 3 + Babylon: + style: row + columns: 1 + header: false + Websites: + style: row + columns: 4 + Users: + style: row + columns: 2 +headerStyle: boxed +quicklaunch: + searchDescriptions: true + hideInternetSearch: true + showSearchSuggestions: false + hideVisitURL: true + #provider: google # google, duckduckgo, bing, baidu, brave or custom +docker: + showStats: true +useEqualHeights: true diff --git a/config/widgets.yaml b/config/widgets.yaml new file mode 100644 index 0000000..9cabb21 --- /dev/null +++ b/config/widgets.yaml @@ -0,0 +1,35 @@ +--- +# For configuration options and examples, please see: +# https://gethomepage.dev/configs/info-widgets/ + +- logo: + icon: /images/favicon.png + href: https://heimdall.lan + target: _self + +- resources: + cpu: true + memory: true + expanded: true +- resources: + disk: + - / + - /data/Data1 + expanded: true +- resources: + cputemp: true + tempmin: 0 # optional, minimum cpu temp + tempmax: 100 # optional, maximum cpu temp + uptime: true + units: metric # only used by cpu temp, options: 'imperial' or 'metric' + refresh: 3000 # optional, in ms + diskUnits: bytes # optional, bytes (default) or bbytes. Only applies to disk + network: true # optional, uses 'default' if true or specify a network interface name + expanded: true +- datetime: + text_size: xl + locale: ch + format: + dateStyle: short + timeStyle: long + hour12: false diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..7a3993c --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,25 @@ +services: + homepage: + image: ghcr.io/gethomepage/homepage:latest + container_name: homepage + restart: unless-stopped + env_file: + - /srv/docker/secrets/homepage/.env +# ports: + # - 3003:3000 + volumes: + - ./config:/app/config:ro + - /srv/appdata/homepage/logs:/app/config/logs + - /srv/appdata/homepage/report:/app/config/report + - /var/run/docker.sock:/var/run/docker.sock:ro # (optional) For docker integrations + - /data/Data1:/data/Data1:ro + - ./images:/app/public/images:ro + environment: + HOMEPAGE_ALLOWED_HOSTS: heimdall.lan # required, may need port. See gethomepage.dev/installation/#homepage_allowed_hosts + HOMEPAGE_PROXY_DISABLE_IPV6: true + networks: + npm_proxy: + ipv4_address: 192.168.96.11 +networks: + npm_proxy: + external: true diff --git a/images/background.png b/images/background.png new file mode 100644 index 0000000..ea02029 Binary files /dev/null and b/images/background.png differ diff --git a/images/favicon.png b/images/favicon.png new file mode 100644 index 0000000..78cb3db Binary files /dev/null and b/images/favicon.png differ