↓ До тексту
  1. Статті/

Homepage - один дашборд на всі домашні сервіси

·5 хвилин
cat /etc/passwd
Автор
cat /etc/passwd
Технічний блог про Linux, DevOps та Open Source технології.
Зміст

Коли вдома крутиться з десяток сервісів - Proxmox, пара баз, медіасервер, моніторинг - рано чи пізно ти ловиш себе на тому, що тримаєш їхні адреси в закладках, а паролі від портів - у голові. Homepage (він же gethomepage) розвʼязує це просто: одна стартова сторінка, де всі твої сервіси зібрані в акуратні групи, з іконками, а де треба - і зі статусом прямо з Docker. Ніякої бази даних, ніякого важкого бекенду - усе налаштовується кількома YAML-файлами, а піднімається за хвилину в контейнері.

Що потрібно зробити?
#

Підняти Homepage у Docker, задати йому кілька груп сервісів, додати закладки й верхні інфо-віджети (погода, ресурси, годинник, пошук), підключити docker-сокет - щоб картки показували стан контейнерів. І одразу глянути, як це виглядає в браузері. Усю консоль, як завжди, записав у терміналі.

З чим працюю?
#

Свіжий Debian/Ubuntu з уже встановленим Docker (якщо його ще нема - це на одну команду). Беру офіційний образ ghcr.io/gethomepage/homepage, фіксую версію v2.4.0 (щоб поведінка й вигляд збігались із цим текстом), контейнер слухає порт 3000.

Піднімаємо контейнер
#

Homepage зручно тримати через compose. Створюємо каталог проєкту і кладемо compose.yml:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
services:
  homepage:
    image: ghcr.io/gethomepage/homepage:v2.4.0
    container_name: homepage
    ports:
      - "3000:3000"
    volumes:
      - ./config:/app/config                          # YAML-конфіг
      - /var/run/docker.sock:/var/run/docker.sock:ro   # для статусу контейнерів
    environment:
      HOMEPAGE_ALLOWED_HOSTS: 192.168.1.50:3000        # ОБОВʼЯЗКОВО, див. нижче
    restart: unless-stopped

Запускаємо:

Homepage у Docker linuxway.com.ua

На першому старті Homepage сам кладе в порожній config/ кілька файлів-скелетів (settings.yaml, services.yaml, widgets.yaml і решту) і одразу показує демо-дашборд. Далі ми їх просто замінимо своїми.

Головна пастка: HOMEPAGE_ALLOWED_HOSTS
#

Ось на чому спотикаються всі, хто ставить Homepage уперше. Починаючи з версії 1.0, якщо заходити не через localhost, Homepage вимагає змінну HOMEPAGE_ALLOWED_HOSTS зі списком дозволених хостів. Нема її (або значення не те) - замість дашборда отримаєш помилку валідації хоста.

  • Формат - список через кому без пробілів, кожен запис може містити порт: homepage.example.com,192.168.1.50:3000.
  • localhost:3000 і 127.0.0.1:3000 дозволені завжди, їх додавати не треба.
  • Якщо бачиш помилку - подивись у лог контейнера (docker compose logs homepage): там надруковано хост рівно так, як його бачить Homepage. Саме це значення й додаєш у список.

Коротко: впиши сюди той IP:порт (або домен), за яким реально відкриватимеш дашборд, - і проблеми не буде.

Налаштовуємо під себе
#

Усі файли лежать у config/. Homepage підхоплює зміни на льоту - зберіг YAML, оновив сторінку в браузері, і готово (рестарт потрібен хіба що коли додаєш власні локальні іконки).

settings.yaml - загальний вигляд
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
title: Домашній сервер
theme: dark            # dark або light
color: slate           # палітра: slate, gray, zinc, blue, green, red...
headerStyle: underlined
layout:                # порядок груп і скільки колонок у кожній
  Інфраструктура:
    style: row
    columns: 2
  Docker:
    style: row
    columns: 3
  Моніторинг:
    style: row
    columns: 2

services.yaml - власне сервіси
#

Структура проста: група -> назва сервісу -> поля. Мінімально потрібен лише href:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
- Інфраструктура:
    - Proxmox:
        href: https://192.168.1.10:8006/
        description: Віртуалізація
        icon: proxmox.png          # іконка з dashboard-icons (можна й без .png)
    - Portainer:
        href: https://192.168.1.11:9443/
        description: Керування Docker
        icon: portainer.png

- Docker:
    - Вебсервер:
        href: http://192.168.1.11/
        description: nginx
        icon: nginx.png
        server: my-docker          # імʼя інстансу з docker.yaml
        container: demo-web        # імʼя контейнера -> статус і CPU/RAM
        showStats: true
    - Кеш:
        href: "#"
        description: redis
        icon: redis.png
        server: my-docker
        container: demo-cache
        showStats: true

- Моніторинг:
    - Uptime Kuma:
        href: https://192.168.1.30:3001/
        description: Статус сервісів
        icon: uptime-kuma.png
        ping: 192.168.1.30         # простий індикатор доступності, без ключів

Іконки беруться автоматично: просто icon: sonarr.png (з dashboard-icons), або з префіксом - mdi-server-network (Material Design), si-docker (бренди Simple Icons). Можна й повний https://... на свою картинку.

Деякі віджети сервісів уміють тягнути статистику з самого додатка - але для цього потрібен API-ключ, а це вже секрет. У конфіг кладемо тільки плейсхолдер, реальний ключ у git не комітимо:

1
2
3
4
5
6
7
    - Sonarr:
        href: https://192.168.1.31:8989/
        icon: sonarr.png
        widget:
          type: sonarr
          url: http://192.168.1.31:8989
          key: your-api-key-here   # НІКОЛИ не публікувати справжній ключ

widgets.yaml - верхній рядок
#

Це той рядок зверху: привітання, годинник, погода, ресурси хоста, пошук. Погода через openmeteo - приємно тим, що не потребує ключа й реєстрації:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
- greeting:
    text_size: xl
    text: Вітаю вдома
- datetime:
    text_size: xl
    locale: uk
    format: { dateStyle: long, timeStyle: short }
- openmeteo:                 # погода без API-ключа
    latitude: 50.4501
    longitude: 30.5234
    timezone: Europe/Kyiv
    units: metric
- resources:                 # CPU / RAM / диск / uptime хоста
    label: Система
    cpu: true
    memory: true
    disk: /
    uptime: true
- search:
    provider: duckduckgo
    target: _blank

docker.yaml - статус контейнерів без ключів
#

Найприємніша частина. Монтуємо docker-сокет (ми вже зробили це в compose.yml) і описуємо інстанс:

1
2
my-docker:
  socket: /var/run/docker.sock

Тепер будь-який сервіс із server: my-docker + container: <імʼя> показує статус і статистику контейнера - без жодного API-ключа, дані беруться напряму з Docker.

bookmarks.yaml - закладки
#

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
- Розробка:
    - Github:
        - abbr: GH
          href: https://github.com/
    - Документація:
        - icon: mdi-book-open-variant
          href: https://example.com/docs
- Інструменти:
    - Grafana:
        - icon: grafana.png
          href: https://192.168.1.40:3000/

А тепер - у браузер
#

Зберегли файли, оновили сторінку - і ось що виходить:

Дашборд Homepage: групи сервісів, статус контейнерів із Docker, погода й ресурси

Зверху - привітання, дата, погода (OpenMeteo, без ключа) і ресурси хоста. Нижче - наші групи. Найцікавіше - група Docker: картки тягнуть статус і статистику прямо з docker-сокета, тож видно і стан контейнера (RUNNING / HEALTHY), і його CPU, памʼять та трафік:

Група Docker зблизька: статус RUNNING/HEALTHY і реальні CPU/RAM/мережа кожного контейнера

І все це - без жодного API-ключа, лише завдяки змонтованому сокету.

Куди далі
#

Homepage тягне ще багато всього: власні іконки (том на /app/public/icons), десятки готових віджетів під конкретні застосунки, автодискавері контейнерів через Docker-мітки, інтеграцію з Kubernetes. Але головне ти вже вмієш: групи, сервіси, статус із Docker, інфо-віджети.

Дві речі наостанок. Перше - секрети: ключі у віджетах не комітимо в git і не світимо в скриншотах. Друге - фіксуй версію образу (:v2.4.0, а не :latest), щоб наступне оновлення не змінило вигляд і поведінку несподівано. А коли захочеш виставити дашборд назовні з нормальним HTTPS - це вже робота для reverse proxy, але то окрема історія.

Related