Команда инженеров · свой ЦОД в РФ · своё железо · своя панель · CloudStack + Linstor · MCP · база знаний по self-hosted
Наблюдаемость и аудит

Gotify

Свой сервер push-уведомлений для команды: у каждого инженера своя учетная запись, приложения с токенами и клиенты, история сообщений остается на сервере, вход через корпоративный SSO по OIDC. Ниже - как устроен Gotify Server 3.1, как ставится в Docker на Ubuntu 24.04 за Caddy и чем отличается от ntfy.

Сентябрь 2026~13 минут чтенияFatmetal Team
Наблюдаемость и аудит Лицензия: MIT, платных модулей нет Статус: запущен у нас, v3.1.0

Вердикт

Подходит
  • IT-отделу или DevOps-команде из 2-20 человек как один приемник алертов: у каждого своя учетка, токены и лента
  • тем, у кого уже стоит Keycloak или Authentik: вход по OIDC, администраторы из групп IdP
  • тем, кому нельзя отдавать текст алертов третьей стороне: сервер наружу не ходит, Android-клиент без Firebase
Не подходит
  • командам на iPhone: официального iOS-клиента нет. Для iOS - ntfy
  • одному человеку с Android: Pushover за 4,99 $ разово или ntfy проще
  • кому нужна эскалация по e-mail, SMS или звонком
Мин. тариф: CPU2-RAM4-DISK50 Рекомендуем: CPU2-RAM4-DISK50 Сложность: easy Время запуска: 1,7 с до контейнеров RAM в простое: ~16 MiB Главный риск: пароль администратора задается только при создании базы Прод-готовность: с оговорками (Caddy с TLS, TRUSTEDPROXIES, бэкап SQLite)
Что это

Gotify: что это и какую задачу решает

Gotify - self-hosted сервер push-уведомлений. Скрипт, cron, мониторинг или CI делают POST на ваш сервер, и сообщение прилетает в Android-приложение и веб-интерфейс - без Firebase, Telegram и чужого SaaS.

Главное в устройстве - модель данных. У пользователя есть приложения (только отправляют, токен с префиксом A) и клиенты (только читают: телефон, браузер, скрипт; токен C). Чужие ленты не видны, самозапись выключена, сообщения хранятся в базе.

С 3.0.0 (июль 2026) - вход через OIDC, session elevation (повторный пароль перед опасными действиями), токены показываются один раз. 3.1.0 (27 августа 2026) довела SSO: локальные пароли можно выключить, администраторы - из группы IdP.

Границы: клиент только Android (Google Play и F-Droid), на iPhone - веб без системных пушей; каналов e-mail и SMS нет; русской локализации нет, кириллица в сообщениях работает.

Go + React в одном бинареSQLiteREST API + WebSocketOIDC (PKCE)Android-клиент, CLIDocker Compose + Caddy
Сценарий

Один приемник алертов на отдел: учетки, токены, история

Веб-интерфейс - три экрана: Messages, Apps и Clients, плюс Users для администратора. На стенде мы завели два приложения, «Мониторинг сервера» и «CI/CD Pipeline», и отправили через API три сообщения с разными приоритетами.

Лента All Messages в Gotify 3.1.0: три карточки с русскими заголовками про бэкап, деплой и заполненный диск, цветные полоски приоритета, слева список приложений
Лента сообщений на стенде: три сообщения с разными приоритетами, отправлены через API. Gotify v3.1.0.

Экран Apps - «кто имеет право писать». Приложение на каждый источник: утек токен - отзывается один источник, а не весь доступ. С 3.x токен виден один раз при создании; ротация есть, подсмотреть старый нельзя.

Экран Applications в Gotify: два приложения Мониторинг сервера и CI/CD Pipeline с описанием, приоритетом, датой и кнопками ротации токена
Приложения-источники: свой токен, описание и дата последнего использования у каждого. v3.1.0.

Экран Clients - «кто имеет право читать». Вход в веб-интерфейс создает клиент на 7 дней; отметка Elevation ends 59 минут - это session elevation: через час опасное действие снова попросит пароль. Basic-auth для скриптов считается поднятой всегда.

Экран Clients в Gotify: клиент Телефон дежурного без срока и клиент chrome текущей сессии с колонками Elevation ends 59m и Expires in 6d 23h
Клиенты-получатели: «Телефон дежурного» создан через API без срока, клиент браузера - при входе на 7 дней.

Пользователей заводит администратор; обычный пользователь чужих приложений не видит. «Кто получает алерты с прода» - это список в Users, а не память о том, кого добавили в чат.

Сравнение

Pushover, Telegram-бот и ntfy: что меняется при переходе

Цены Pushover - с pushover.net/pricing, тарифы ntfy.sh - с их API; сняты 14 сентября 2026.

Одному человеку self-hosting не про экономию: Pushover стоит 4,99 $ разово. Аргумент появляется в команде: Pushover for Teams - 5 $ за пользователя в месяц, на десятерых 600 $ в год; хостед-ntfy.sh - 6-25 $ в месяц. Gotify на CPU2-RAM4-DISK50 за 500 ₽ в месяц обслуживает весь отдел.

ПараметрGotify self-hostedPushover / Teams / Telegram-бот
Модель цены0 за софт, платите за сервер4,99 $ разово; Teams 5 $ за пользователя в месяц
Лимитынет10 000 сообщений в месяц; лимиты Bot API
Где данныеSQLite на вашем дискеу Pushover или Telegram, вместе с токенами
Учетки и SSOпользователи, приложения, клиенты; OIDCу бота - один чат на всех
Мобильные клиентытолько AndroidiOS, Android, десктоп
Эскалациятолько push и вебповторяющиеся emergency-уведомления у Pushover

Gotify или ntfy

Разница в модели по умолчанию. В ntfy топики открыты: кто знает имя, тот пишет и читает, публикация без регистрации; есть iOS и UnifiedPush. В Gotify все закрыто с первого запуска. Один человек - ntfy; команда с учетками и SSO - Gotify; команда на iPhone - ntfy при любом раскладе.

Под капотом

Тех-стек и архитектура

Один бинарь на Go: REST API, WebSocket-стрим /stream, React-интерфейс и встроенный SQLite. Внешних зависимостей нет - ни Redis, ни SMTP, ни исходящих вызовов. База - файл data/gotify.db в томе /app/data, там же иконки; опционально MySQL или PostgreSQL.

Конфигурация с 3.x - только переменные GOTIFY_*, каждая умеет суффикс _FILE для Docker secrets; config.yml больше нет. Android-приложение держит WebSocket само, без Firebase: отсюда приватность и постоянное соединение на телефоне.

В compose два контейнера: gotify (gotify/server:3.1.0, 211 MB, наружу только 127.0.0.1:8080) и caddy (caddy:2, 88,7 MB, публичные 80 и 443, Let's Encrypt). Есть зеркало ghcr.io/gotify/server. Тег закрепляем: между 2.x и 3.x обновление ломающее.

Конфигурация

Минимальная конфигурация

Апстрим численных требований не публикует. Ниже - что показал стенд.

Официальный минимумDocker и Compose; цифр по RAM и CPU нет
RAM стека в простое~16 MiB (gotify 6,3 + caddy 9,5)
RAM хоста с ОС и Docker512 MiB занято из 3,8 GiB
Диск после установки2,6 GB из 50 GB; образы 299,7 MB, данные 184 KB
Рекомендуем тарифCPU2-RAM4-DISK50 - 500 ₽ в месяц
i

Почему CPU2-RAM4-DISK50. Стек в простое занимает ~16 MiB - на два порядка меньше 4 GB тарифа; конфигураций меньше в каталоге нет, запас уходит под Uptime Kuma, Beszel или n8n на той же машине. Авточистки истории среди переменных 3.1 нет, но при килобайтных сообщениях 50 GB - это годы.

В маркетплейсе Fatmetal

Не хотите ставить руками?

Этот стек есть в маркетплейсе Fatmetal - можно не повторять установку из этого разбора вручную. Заказываете сервер, за пару минут получаете Gotify на своем домене, валидный TLS и файл с доступами.

Рекомендуемая конфигурация:
2 vCPU · 4 ГБ RAM · 50 ГБ NVMe от 450 ₽/мес

Развернуть в 1 клик →
Развертывание

Развертывание на Fatmetal

Fatmetal Cloud Server + Ubuntu 24.04 + Docker Compose - путь, который прошел на стенде.

  1. Создать VM и поставить Docker

    Тариф CPU2-RAM4-DISK50, Ubuntu 24.04 LTS. На чистом образе Docker нет; Engine и compose-плагин из официального репозитория docs.docker.com встали за 15 секунд.

  2. Написать compose.yml и Caddyfile

    Пароль администратора сгенерируйте до первого запуска: он применяется только при создании базы. Домен к этому моменту должен указывать на IP сервера.

    sudo mkdir -p /opt/gotify/{gotify_data,caddy_data,caddy_config}
    sudo chown -R $USER:$USER /opt/gotify && cd /opt/gotify
    openssl rand -base64 18   # это будет GOTIFY_DEFAULTUSER_PASS
    
    cat > compose.yml <<'EOF'
    services:
      gotify:
        image: gotify/server:3.1.0
        restart: unless-stopped
        environment:
          GOTIFY_DEFAULTUSER_NAME: admin
          GOTIFY_DEFAULTUSER_PASS: "СЮДА_СГЕНЕРИРОВАННЫЙ_ПАРОЛЬ"
          GOTIFY_SERVER_SECURECOOKIE: "true"
          GOTIFY_SERVER_TRUSTEDPROXIES: "172.16.0.0/12"
          GOTIFY_REGISTRATION: "false"
          TZ: "Europe/Moscow"
        ports: ["127.0.0.1:8080:80"]
        volumes: ["./gotify_data:/app/data"]
      caddy:
        image: caddy:2
        restart: unless-stopped
        ports: ["80:80", "443:443"]
        volumes: ["./Caddyfile:/etc/caddy/Caddyfile", "./caddy_data:/data", "./caddy_config:/config"]
    EOF
    printf 'gotify.example.com {\n    reverse_proxy gotify:80\n}\n' > Caddyfile

    SECURECOOKIE=true - cookie сессии только по HTTPS, по голому http после этого не войти. TRUSTEDPROXIES - кому верить в X-Forwarded-For: Caddy приходит из docker-сети (на стенде 172.18.0.0/16), поэтому /12 с запасом. reverse_proxy gotify:80 - по имени сервиса, не localhost; почему - в граблях.

  3. Поднять стек

    sudo docker compose pull && sudo docker compose up -d
    curl -s https://gotify.example.com/version    # {"version":"3.1.0",...}

    Образы скачались за 9,1 с с третьей попытки: первые две (32,7 и 37,1 с) оборвал таймаут Docker Hub. От up -d до контейнеров - 1,7 с, ответ 200 на loopback - через 3,8 мс, сертификат Let's Encrypt - за 1,5 с.

  4. Завести учетки и отправить первое сообщение

    Первый вход - admin и пароль из compose.yml. Учетки инженерам - в Users (или POST /user с Basic-auth администратора); каждый создает приложение в Apps, токен показывается один раз. Дальше - сообщение от имени приложения:

    curl -sS -X POST https://gotify.example.com/message \
      -H "X-Gotify-Key: ТОКЕН_ПРИЛОЖЕНИЯ" \
      -F "title=Диск заполнен на 92%" -F "message=Свободно 3.8 ГБ из 50" -F "priority=8"

    Сообщение появляется в ленте и на телефоне в момент запроса - клиенты держат WebSocket. Инженер ставит Android-приложение и вводит адрес сервера с логином; клиент создается сам.

Настройка

Вход через корпоративный SSO: OIDC с Keycloak или Authentik

Переменные - из gotify-server.env.example для 3.1. На стенде OIDC не включали: у стенда не было IdP, это описание по документации, а не замер.

С 3.0.0 Gotify входит через любой OpenID Connect провайдер с PKCE: апстрим называет Authelia, Dex и Keycloak, Authentik сюда тоже попадает. Нужны issuer, client id и secret из IdP и callback, который заканчивается на /auth/oidc/callback.

      GOTIFY_OIDC_ENABLED: "true"
      GOTIFY_OIDC_ISSUER: "https://auth.example.com/realms/myrealm"   # Keycloak realm
      GOTIFY_OIDC_CLIENTID: "gotify"
      GOTIFY_OIDC_CLIENTSECRET_FILE: "/run/secrets/oidc_secret"
      GOTIFY_OIDC_REDIRECTURL: "https://gotify.example.com/auth/oidc/callback"
      GOTIFY_OIDC_GROUPS_CLAIM: "groups"
      GOTIFY_OIDC_GROUPS_USER: "devops"
      GOTIFY_OIDC_GROUPS_ADMIN: "devops-admins"
      GOTIFY_LOCALAUTH_ENABLED: "false"

GOTIFY_OIDC_AUTOREGISTER (по умолчанию true) создает пользователя при первом входе: новому инженеру достаточно попасть в группу в Keycloak. GROUPS_USER и GROUPS_ADMIN (3.1) решают, кто входит и кто администратор; права пересчитываются при каждом входе.

GOTIFY_LOCALAUTH_ENABLED=false выключает пароли совсем. Для Android-приложения у провайдера регистрируется второй redirect gotify://oidc/callback. Как поднять провайдер - в разборах Keycloak и Authentik.

Интеграции

Алерты без Telegram-бота: один curl с X-Gotify-Key

Отправка - POST /message с токеном приложения в заголовке X-Gotify-Key и полями title, message, priority. Ни SDK, ни регистрации отправителя - поэтому Gotify стал стандартным адресатом для алертов в self-hosted-мире.

Из нашей базы знаний штатно шлют Uptime Kuma (встроенный провайдер), Beszel (через Shoutrrr) и n8n (HTTP-нода). Для cron - curl или gotify push -t "Бэкап" -p 5 "Готово".

Приоритет решает, насколько заметным будет уведомление: бэкапы - низкий, «диск заполнен» - высокий. Чего нет: входящих вебхуков в произвольном формате - Prometheus Alertmanager напрямую не умеет, нужен n8n или адаптер.

Замеры

Что измерили после запуска

Свежая установка без нагрузки; тайминги сняты контролируемым циклом down, rmi, pull, up с сохранением томов.

Стенд14 сентября 2026, Fatmetal Cloud Server CPU2-RAM4-DISK50, Ubuntu 24.04.4 LTS, Docker 29.8.0, Gotify v3.1.0
Установка Docker Engine15 с
Скачивание образов, холодное9,1 с с третьей попытки (первые две: 32,7 и 37,1 с, таймаут Docker Hub)
От docker compose up до контейнеров1,7 с; healthcheck healthy на первой проверке
Итого до рабочего продукта с TLS~5 мин, большая часть - диагностика 502 из-за localhost в Caddyfile
RAM в простое, весь стек~16 MiB (gotify 6,3 / caddy 9,5); CPU 0,00%
Диск после установки2,6 GB из 50 GB; образы 299,7 MB, данные 184 KB
Отклик главной: loopback / за TLS снаружи3,8 мс / 60 мс; /version снаружи - 79,6 мс
i

Главное: ~16 MiB на два контейнера, само приложение - 6,3 MiB. Это самый легкий стек среди наших разборов: ntfy на соседнем стенде брал ~17 MiB, Node-стеки вроде Docmost - под 500.

Проверено на Gotify v3.1.0, сентябрь 2026. На новых версиях результаты могут отличаться.

Подводные камни

Где может сломаться

Грабли с запуска и то, чем 3.x отличается от всего, что написано о Gotify по-русски.

!

Пароль администратора применяется только при первом создании базы. Переменные читаются один раз, когда создается data/gotify.db; дефолт - admin/admin. Дописали пароль после первого старта - ничего не изменится. Лечится: задать до первого up -d, сменить в Users или на пустой базе удалить gotify.db.

!

Русскоязычные инструкции описывают 2.x и не заведутся на 3.x. Мажор 3.0.0 удалил config.yml (для старых - подкоманда migrate-config), токены больше не видны после создания, отправка токеном клиента требует appid. Ставите по чужому compose из 2024 года - ждите падения на старте.

HTTP 502 от Caddy; в логе caddy: dial tcp [::1]:8080: connect: connection refused

Причина. Caddyfile из документации - reverse_proxy localhost:8080, он написан для Caddy на хосте. Внутри контейнера localhost указывает на сам caddy; сертификат при этом выдается нормально.

Решение. reverse_proxy gotify:80 по имени сервиса compose, затем sudo docker compose restart caddy. Те же грабли мы ловили на ntfy.

failed to copy: httpReadSeeker: failed open: ... net/http: timeout awaiting response headers (docker compose pull)

Причина. Транзиентный таймаут Docker Hub на одном из слоев; на стенде случился дважды подряд.

Решение. Повторить sudo docker compose pull; если Docker Hub недоступен системно - image: ghcr.io/gotify/server:3.1.0.

Безопасность

Безопасность и обновления

Релизы - GitHub Releases, есть SECURITY.md; 3.1.0 закрыл advisory GHSA-78w7-2h8c-8252. Обновление в пределах 3.x - смена тега и перезапуск; с 2.x - только по странице «Migrate to 3.x».

cd /opt/gotify && sudo docker compose stop gotify
sudo tar czf ~/gotify-$(date +%F).tgz -C /opt/gotify gotify_data
sed -i 's/gotify\/server:3.1.0/gotify\/server:НОВАЯ_ВЕРСИЯ/' compose.yml
sudo docker compose pull && sudo docker compose up -d

Бэкап - один каталог gotify_data: gotify.db (пользователи, история, хэши токенов) и images с иконками. Либо короткая остановка и tar, как выше, либо sqlite3 gotify.db ".backup copy.db" на горячую. Восстановление - положить каталог рядом с compose.yml; токены переедут с базой.

Что закрыть перед продом:

  • GOTIFY_DEFAULTUSER_PASS задан до первого запуска и не равен admin;
  • приложение слушает только 127.0.0.1:8080, наружу - Caddy с TLS, SECURECOOKIE=true, TRUSTEDPROXIES покрывает прокси;
  • REGISTRATION остается false; одно приложение на источник, токены в скриптах - из secrets;
  • тег образа закреплен; бэкап gotify_data по расписанию и хотя бы раз проверен восстановлением.
Рядом

Связь с другими стеками

  • ntfy - сосед по полке: открытые топики, curl без регистрации, iOS и UnifiedPush. Один человек или команда на iPhone - туда.
  • Uptime Kuma, Beszel - основные отправители; на CPU2-RAM4-DISK50 все три живут на одной машине.
  • Keycloak, Authentik - OIDC-провайдеры для входа команды: группы IdP становятся правами в Gotify.
  • n8n - адаптер для всего, что не умеет слать само: Alertmanager, вебхуки GitLab, почта на входе.
Границы

Когда это НЕ ваш выбор

У команды iPhone

Официального iOS-клиента нет, и апстрим его не обещает. Веб на iPhone работает, но без системных уведомлений - а ради них все затевалось. Ставьте ntfy.

Получатель один, и у него Android

Pushover за 4,99 $ разово или ntfy закрывают задачу без сервера и бэкапов. Gotify одному человеку - только ради истории на своем диске и приватности текста алертов.

Нужна эскалация: e-mail, SMS, звонок, повтор до подтверждения

Gotify - только push и веб. Ни повторяющихся emergency-уведомлений, ни дежурных расписаний. Для on-call с эскалацией это другой класс продуктов.

Нужен вендор с договором и SLA

Community-проект без юрлица, один ведущий автор восемь лет; поддержка - issue на GitHub. Смягчает это MIT и один Go-бинарь с SQLite: стоящий сервер продолжит работать годами без обновлений.

FAQ

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

Хватит ли 2 GB RAM?

С огромным запасом: стек в простое берет ~16 MiB, хост с ОС и Docker - 512 MiB. Конфигураций меньше CPU2-RAM4-DISK50 у Fatmetal нет.

Есть ли клиент для iPhone?

Официального нет: только Android (Google Play и F-Droid) и веб без системных уведомлений. Команде на iOS - ntfy.

Можно пустить команду через Keycloak или Authentik?

Да, с 3.0: переменные GOTIFY_OIDC_*, провайдер должен поддерживать PKCE. С 3.1 администраторы берутся из группы IdP, локальные пароли можно выключить.

Как обновлять и бэкапить?

Остановить gotify, скопировать gotify_data, сменить тег, pull и up -d. С 2.x на 3.x - токены надо перевыпустить.

Какие ограничения лицензии?

MIT: коммерческое использование и изменение без ограничений. Платных редакций и лицензионных ключей нет.

Итог

Gotify - сервер push-уведомлений, с первого запуска устроенный под несколько человек: своя учетка, приложения и клиенты у каждого, история на сервере, с 3.x - вход через корпоративный OIDC. Один Go-контейнер со SQLite плюс Caddy стартует за 1,7 секунды и берет ~16 MiB: на CPU2-RAM4-DISK50 за 500 ₽ в месяц это весь отдел против 5 $ за человека у Pushover for Teams. Принять до установки: клиент только Android, пароль администратора задается один раз.

Рекомендуемая конфигурация для установки:
2 vCPU · 4 ГБ RAM · 50 ГБ NVMe

Не хотите устанавливать вручную?

Запустите Gotify на этой конфигурации автоматически - от 450 ₽/мес.

Запустить Gotify →
Анонсы новых разборов в Telegram-канале Новые гайды и карточки в маркетплейсе первыми @fatmetal_channel →

Этот стек у нас запущен на конфигурации 2 vCPU / 4 GB RAM / 50 GB SSD (тариф CPU2-RAM4-DISK50). Нашли баг в гайде - напишите, поправим в течение дня.