MAATRIX / Блог / Homepage на Ubuntu 24.04: пошаговая установка

Homepage на Ubuntu 24.04: пошаговая установка

MAATRIX

Если на сервере крутится десяток сервисов — Portainer, Uptime Kuma, *arr-стек, пара веб-приложений — рано или поздно вы устаёте держать в голове (или в закладках браузера) их адреса и порты. Homepage закрывает эту задачу: единая стартовая страница со ссылками, живыми виджетами статуса и системными метриками. Ниже — установка на чистый Ubuntu 24.04 через Docker, разбор конфигов и вывод в интернет по HTTPS.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →

Что такое Homepage и кому он нужен

Homepage (проект gethomepage, бывший homer-конкурент, написан на Next.js) — это самостоятельно хостящаяся стартовая страница для домашнего или рабочего сервера. Она не проксирует трафик и не заменяет reverse proxy — это просто удобная витрина: карточки сервисов со ссылками, иконками и статус-виджетами, плюс блоки погоды, поиска и системных ресурсов.

Из практических причин ставить именно Homepage, а не писать HTML-страницу руками:

  • конфигурация текстовыми YAML-файлами — удобно версионировать в git и переносить между серверами;
  • десятки готовых интеграций-виджетов (Portainer, Uptime Kuma, Docker, Proxmox, качалки, *arr-стек, роутеры и т.д.) — не нужно самому дёргать API каждого сервиса;
  • автообнаружение контейнеров через Docker-сокет — можно вешать сервисы на дашборд лейблами в docker-compose.yml, без правки YAML вручную;
  • лёгкий вес: контейнер занимает 150-250 МБ RAM в простое, подходит даже для бюджетного VPS.

Если у вас один-два сервиса на сервере, Homepage, скорее всего, избыточен — хватит закладок. Смысл появляется, когда сервисов пять и больше, либо когда дашборд открывают несколько человек в команде.

Подготовка сервера

Понадобится Ubuntu 24.04 LTS с 1 vCPU / 1 ГБ RAM (для самого Homepage этого достаточно с запасом — узкое место обычно в других сервисах на том же сервере) и установленным Docker с Docker Compose plugin. Если Docker ещё не стоит, разверните его по нашей инструкции Ubuntu 24.04: установка Docker с нуля — там же объясняется, зачем добавлять пользователя в группу docker.

Обновите систему и создайте рабочую директорию:

sudo apt update && sudo apt upgrade -y
mkdir -p ~/homepage/config
mkdir -p ~/homepage/images
cd ~/homepage

Проверьте, что Docker и compose-плагин доступны:

docker --version
docker compose version

Если сервер планируется открыть наружу (не только по VPN или локальной сети), сразу настройте firewall (UFW) — открыть нужно будет только 80/443 для reverse proxy, сам Homepage наружу светить портом не обязательно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Установка Homepage через Docker Compose

Официальный образ — ghcr.io/gethomepage/homepage. Создайте файл docker-compose.yml:

services:
  homepage:
    image: ghcr.io/gethomepage/homepage:latest
    container_name: homepage
    restart: unless-stopped
    ports:
      - "3000:3000"
    volumes:
      - ./config:/app/config
      - ./images:/app/public/images
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - PUID=1000
      - PGID=1000
      - HOMEPAGE_ALLOWED_HOSTS=homepage.example.com,127.0.0.1:3000

Пояснения по важным строкам:

  • /var/run/docker.sock монтируется в режиме read-only и нужен только если вы хотите автообнаружение контейнеров и виджет статуса Docker. Если такой автоматизации не нужно — строку можно убрать, это чуть снижает поверхность атаки (доступ к сокету Docker по сути равносилен root на хосте).
  • HOMEPAGE_ALLOWED_HOSTS — обязательная переменная в актуальных версиях Homepage: без неё интерфейс просто откажется загружаться с ошибкой о недопустимом хосте. Перечислите через запятую все домены и адреса, с которых будете открывать дашборд (включая порт, если он нестандартный).
  • PUID/PGID выставляйте под UID реального пользователя на хосте (id -u, id -g), чтобы файлы в ./config создавались не от root.

Поднимите контейнер:

docker compose up -d
docker compose logs -f homepage

При первом запуске Homepage сам создаст в ./config базовые YAML-файлы, если их там ещё нет. Откройте http://IP-сервера:3000 — должна открыться пустая (или с дефолтными примерами) панель.

Конфигурация: settings, services, bookmarks

Вся настройка Homepage — это правка YAML в ~/homepage/config. После изменения любого файла контейнер сам подхватывает изменения (hot reload), перезапуск не нужен.

Основной внешний вид задаётся в settings.yaml:

title: Домашняя панель
theme: dark
color: slate
headerStyle: clean
layout:
  Инфраструктура:
    style: row
    columns: 3
  Сервисы:
    style: row
    columns: 4

Сами карточки сервисов — в services.yaml, сгруппированы по разделам, объявленным в layout:

- Инфраструктура:
    - Portainer:
        icon: portainer.png
        href: https://portainer.example.com
        description: Управление Docker-контейнерами
        widget:
          type: portainer
          url: https://portainer.example.com
          env: 1
          key: {{HOMEPAGE_VAR_PORTAINER_KEY}}

    - Uptime Kuma:
        icon: uptime-kuma.png
        href: https://status.example.com
        description: Мониторинг доступности сервисов
        widget:
          type: uptimekuma
          url: https://status.example.com
          slug: overall

- Сервисы:
    - Nextcloud:
        icon: nextcloud.png
        href: https://cloud.example.com
        description: Личное облако

Иконки берутся из встроенной библиотеки walkxcode/dashboard-icons по имени файла (portainer.png, nextcloud.png и т.д.) — их не нужно скачивать вручную, достаточно указать имя. Свою иконку можно положить в ./images и сослаться на неё как icon: /images/myicon.png.

Ключи API (как HOMEPAGE_VAR_PORTAINER_KEY выше) удобнее не хранить прямо в services.yaml, а вынести в .env-файл рядом с docker-compose.yml:

HOMEPAGE_VAR_PORTAINER_KEY=ptr_abc123...

и подключить его в compose через env_file: .env. Так секреты не попадут в git, если вы версионируете конфиг Homepage.

Для быстрых ссылок без статус-виджетов есть отдельный bookmarks.yaml — туда логично вынести внешние сервисы (регистратор домена, панель хостинга, документацию), которые физически не на вашем сервере и виджет для них не нужен.

Виджеты: статус сервисов и системные метрики

Главная польза Homepage — не статичные ссылки, а живые данные прямо на карточке. Разделяйте два вида виджетов:

Виджеты-интеграции — опрашивают API конкретного сервиса (Portainer, Uptime Kuma, Sentry, качалки, *arr-приложения). Пример для Uptime Kuma показан выше — если вы уже разворачивали его по инструкции Uptime Kuma на VPS, достаточно взять slug нужного публичного статус-монитора из его настроек.

Информационные виджеты — не привязаны к конкретному сервису, настраиваются в widgets.yaml и обычно выводятся в шапке страницы:

- resources:
    cpu: true
    memory: true
    disk: /

- search:
    provider: duckduckgo
    target: _blank

- datetime:
    text_size: xl
    format:
      timeStyle: short
      dateStyle: short

Виджет resources с cpu/memory/disk читает метрики самого хоста — для этого контейнеру нужен доступ к /proc и /sys, который по умолчанию Docker уже даёт через bind-режим (дополнительных монтирований делать не требуется, resources работает "из коробки" при обычном docker-compose).

Отдельно стоит виджет docker, который через смонтированный сокет показывает статус (running/stopped), использование CPU и RAM для конкретного контейнера прямо на его карточке в services.yaml:

    - Nginx:
        icon: nginx.png
        server: my-docker
        container: nginx

где my-docker — имя, объявленное в отдельном файле docker.yaml:

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

Если сервисы работают не в Docker, а как systemd-юниты (например, DNS-сервер или почтовый сервис), виджет статуса контейнера, разумеется, не подойдёт — для них есть отдельные виджеты для конкретных сервисов, либо просто карточка-ссылка без статуса.

Публикация наружу: домен, reverse proxy, HTTPS

Открывать порт 3000 напрямую в интернет не стоит — правильный путь - reverse proxy с TLS-сертификатом. Проще всего это делается через Caddy, который сам выпускает и продлевает сертификаты Let's Encrypt.

Если Caddy ещё не установлен, разверните его по инструкции Caddy с авто-SSL на Ubuntu 24.04. Затем добавьте блок в Caddyfile:

homepage.example.com {
    reverse_proxy 127.0.0.1:3000
}
sudo systemctl reload caddy

После этого не забудьте обновить HOMEPAGE_ALLOWED_HOSTS в docker-compose.yml на реальный домен и пересоздать контейнер (docker compose up -d), иначе Homepage будет отвергать запросы с этого хоста.

Альтернатива Caddy — Traefik или Nginx Proxy Manager, если у вас уже есть один из них на сервере под другие сервисы; сравнение подходов есть в статье Traefik или Nginx Proxy Manager: что выбрать для сервера. Заводить второй reverse proxy ради одного Homepage смысла нет — используйте тот, что уже настроен для остальных сервисов на сервере.

Если дашборд нужен только вам и команде, а не публично, разумнее вообще не выпускать его в интернет — держите доступ через VPN или ограничьте HOMEPAGE_ALLOWED_HOSTS и правила UFW доступом только с внутренней сети/VPN-подсети.

Резервное копирование и обновление

Вся конфигурация Homepage — это несколько YAML-файлов в ./config, поэтому бэкап тривиален:

tar czf homepage-config-$(date +%F).tar.gz -C ~/homepage config images

Добавьте эту команду в cron раз в сутки и складывайте архив вне сервера (в объектное хранилище или на другой хост) — конфиг маленький, лишним не будет.

Обновление — стандартное для Docker-сервиса:

cd ~/homepage
docker compose pull
docker compose up -d

Перед крупными обновлениями (смена мажорной версии) стоит свериться с CHANGELOG проекта на GitHub — формат некоторых виджетов между версиями менялся, и после апдейта иногда нужно поправить пару полей в services.yaml. Автообновление контейнеров (например, через Watchtower) для дашборда, от которого зависит вся навигация по серверу, лучше не включать — безопаснее обновлять вручную и осознанно.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать сервер

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Homepage требует базу данных?

Нет. Вся конфигурация хранится в YAML-файлах на диске, отдельной БД (PostgreSQL, MySQL и т.п.) не нужно — это одна из причин, почему проект такой лёгкий в развёртывании и бэкапе.

Можно ли обойтись без Docker-сокета?

Да. Автообнаружение контейнеров и виджет docker — опциональная функция. Без монтирования сокета Homepage работает точно так же, просто карточки сервисов и их статус нужно будет прописывать вручную в services.yaml.

Почему после обновления страница не открывается и ругается на хост?

Почти всегда причина — не обновлённый HOMEPAGE_ALLOWED_HOSTS. Проверьте, что домен (и, если нужно, порт) в переменной окружения совпадает с адресом, с которого вы открываете дашборд, и пересоздайте контейнер.

Чем Homepage отличается от Portainer как "центральной панели"?

Portainer управляет именно Docker (контейнерами, образами, томами) и требует прав на сокет. Homepage — витрина для людей: ссылки, статусы, метрики по всем сервисам сразу, включая те, что вообще не в Docker. Их удобно использовать вместе: Portainer как рабочий инструмент, Homepage как точка входа с виджетом статуса того же Portainer.

Виджеты можно расположить не только сверху, но и сгруппировать по разделам?

Да, через layout в settings.yaml — каждому разделу задаётся своё имя, стиль (row/column) и число колонок, а сервисы в services.yaml группируются под теми же именами разделов.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →