<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>Pusk on DevOps Way - Практические гайды</title>
    <link>https://devopsway.ru/tags/pusk/</link>
    <description>Recent content in Pusk on DevOps Way - Практические гайды</description>
    <image>
      <title>DevOps Way - Практические гайды</title>
      <url>https://devopsway.ru/images/devopsway-og.png</url>
      <link>https://devopsway.ru/images/devopsway-og.png</link>
    </image>
    <generator>Hugo -- 0.160.1</generator>
    <language>ru</language>
    <lastBuildDate>Fri, 10 Apr 2026 12:50:27 +0000</lastBuildDate>
    <atom:link href="https://devopsway.ru/tags/pusk/feed.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Pusk — свой алерт-мессенджер за 5 команд. Гайд от нуля до рабочего сервиса</title>
      <link>https://devopsway.ru/posts/pusk-self-hosted-guide/</link>
      <pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate>
      <guid>https://devopsway.ru/posts/pusk-self-hosted-guide/</guid>
      <description>Ставим Pusk в Docker на свой сервер: от установки Docker до работающего мессенджера с ботами и вебхуками. Пошаговая инструкция.</description>
      <content:encoded><![CDATA[<p>У тебя есть сервер (или просто машина с Ubuntu), и тебе нужен свой мессенджер для алертов. Не Telegram (который блокируют), не Slack (который SaaS), а что-то своё, на своём железе, без зависимостей.</p>
<p><a href="https://github.com/getpusk/pusk">Pusk</a> — это ровно оно. Один бинарник, SQLite внутри, веб-интерфейс из коробки, API совместимый с Telegram Bot API. Ставится в Docker за пару минут.</p>
<p>Ниже — пошаговая установка от чистого сервера до работающего сервиса с организацией, каналами и ботами.</p>
<h2 id="что-нам-понадобится">Что нам понадобится</h2>
<ul>
<li>Сервер или машина с <strong>Ubuntu</strong> (22.04 / 24.04). Подойдёт и Debian.</li>
<li><strong>Root-доступ</strong> или пользователь с <code>sudo</code>.</li>
<li>Сеть — чтобы скачать Docker и образ Pusk.</li>
</ul>
<p>Всё. Больше ничего не нужно. Ни Go, ни Node.js, ни база данных.</p>
<h2 id="шаг-1-ставим-docker">Шаг 1. Ставим Docker</h2>
<p>Docker — это штука, которая запускает приложения в изолированных контейнерах. Не надо ставить зависимости, настраивать окружение — всё уже упаковано в образ.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt update
</span></span><span class="line"><span class="cl">sudo apt install -y docker.io docker-compose-v2
</span></span></code></pre></div><p>Включаем Docker, чтобы он стартовал при загрузке системы:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now docker
</span></span></code></pre></div><p>Проверяем, что Docker работает:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker --version
</span></span></code></pre></div><p>Должно показать что-то вроде <code>Docker version 29.x.x</code>. Если видишь версию — всё в порядке.</p>
<h3 id="запуск-без-sudo-опционально">Запуск без sudo (опционально)</h3>
<p>По умолчанию Docker требует <code>sudo</code> для каждой команды. Чтобы не набирать его постоянно:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo usermod -aG docker <span class="nv">$USER</span>
</span></span></code></pre></div><p>После этого <strong>выйди из терминала и зайди заново</strong> (или перелогинься). Иначе группа не подхватится.</p>
<h2 id="шаг-2-создаём-папку-для-pusk">Шаг 2. Создаём папку для Pusk</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">mkdir -p ~/pusk/data
</span></span><span class="line"><span class="cl"><span class="nb">cd</span> ~/pusk
</span></span></code></pre></div><p><code>data</code> — здесь Pusk будет хранить базу данных и файлы. Эту папку потом бэкапим.</p>
<h2 id="шаг-3-пишем-конфиг">Шаг 3. Пишем конфиг</h2>
<p>Создаём файл <code>docker-compose.yml</code>:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cat &gt; docker-compose.yml <span class="s">&lt;&lt; &#39;EOF&#39;
</span></span></span><span class="line"><span class="cl"><span class="s">services:
</span></span></span><span class="line"><span class="cl"><span class="s">  pusk:
</span></span></span><span class="line"><span class="cl"><span class="s">    image: ghcr.io/getpusk/pusk:latest
</span></span></span><span class="line"><span class="cl"><span class="s">    ports:
</span></span></span><span class="line"><span class="cl"><span class="s">      - &#34;8443:8443&#34;
</span></span></span><span class="line"><span class="cl"><span class="s">    volumes:
</span></span></span><span class="line"><span class="cl"><span class="s">      - ./data:/app/data
</span></span></span><span class="line"><span class="cl"><span class="s">    environment:
</span></span></span><span class="line"><span class="cl"><span class="s">      - PUSK_ADDR=:8443
</span></span></span><span class="line"><span class="cl"><span class="s">    restart: unless-stopped
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span></code></pre></div><p>Что тут написано:</p>
<ul>
<li><code>image</code> — берём готовый образ Pusk из GitHub Container Registry.</li>
<li><code>ports</code> — пробрасываем порт 8443 наружу. По этому порту будет веб-интерфейс.</li>
<li><code>volumes</code> — папка <code>data</code> на хосте монтируется внутрь контейнера. Данные живут на диске, а не внутри контейнера.</li>
<li><code>restart: unless-stopped</code> — если сервер перезагрузится, Pusk запустится автоматически.</li>
</ul>
<h2 id="шаг-4-разбираемся-с-правами-на-папку">Шаг 4. Разбираемся с правами на папку</h2>
<p>Внутри контейнера Pusk работает от пользователя <code>pusk</code> (uid=100). А папку <code>data</code> мы создали от своего пользователя (uid=1000). Контейнер не сможет в неё писать — получит Permission denied.</p>
<p>Фиксим:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo chown -R 100:101 ~/pusk/data
</span></span></code></pre></div><p>Это говорит системе: &ldquo;владелец папки <code>data</code> — пользователь с uid=100&rdquo;, что совпадает с пользователем внутри контейнера.</p>
<blockquote>
<p>Почему так? Docker-контейнеры работают в своём пространстве пользователей. Если uid внутри не совпадает с uid снаружи — файловая система говорит &ldquo;нет доступа&rdquo;. Это нормально и правильно с точки зрения безопасности. <code>chmod 777</code> — не решение, а заметание проблемы под ковёр.</p>
</blockquote>
<h2 id="шаг-5-запускаем">Шаг 5. Запускаем</h2>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> ~/pusk
</span></span><span class="line"><span class="cl">docker compose up -d
</span></span></code></pre></div><p>Docker скачает образ (один раз) и запустит контейнер в фоне (<code>-d</code> = detach).</p>
<p>Проверяем, что контейнер живой:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose ps
</span></span></code></pre></div><p>Должен показать статус <code>Up</code>. Ещё можно дёрнуть health-эндпоинт:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">curl -s http://localhost:8443/api/health
</span></span></code></pre></div><p>Ответ вида <code>{&quot;status&quot;:&quot;ok&quot;,&quot;version&quot;:&quot;v0.7.0&quot;}</code> — значит, всё работает.</p>
<h2 id="шаг-6-открываем-в-браузере">Шаг 6. Открываем в браузере</h2>
<p>Заходим по адресу:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">http://IP-АДРЕС-СЕРВЕРА:8443
</span></span></code></pre></div><p>Если ставишь на локальную машину — <code>http://localhost:8443</code>.</p>
<p>Увидишь лендинг — команда для запуска, список фич, демо-бот справа:</p>
<img alt="Лендинг Pusk после запуска" loading="lazy" src="/images/pusk-guide/pusk-landing.png"><p>Жмём <strong>&ldquo;Create organization&rdquo;</strong> и заполняем:</p>
<ul>
<li><strong>Organization ID</strong> — латиницей, без пробелов (например, <code>myteam</code>)</li>
<li><strong>Name</strong> — название (например, <code>My Team</code>)</li>
<li><strong>Admin username</strong> — логин админа</li>
<li><strong>Password</strong> — пароль</li>
</ul>
<img alt="Форма создания организации" loading="lazy" src="/images/pusk-guide/pusk-create-org.png"><p>Жмём <strong>Create</strong>. Готово — ты внутри. Канал <code>#general</code> создан автоматически, бот готов к работе, онбординг предложит создать канал <code>#alerts</code>:</p>
<img alt="Дашборд Pusk после создания организации" loading="lazy" src="/images/pusk-guide/pusk-dashboard.png"><h2 id="что-дальше">Что дальше</h2>
<h3 id="подключить-мониторинг">Подключить мониторинг</h3>
<p>У Pusk есть вебхуки. Можно подключить Alertmanager, Grafana, Zabbix, Uptime Kuma — что угодно, что умеет слать HTTP POST.</p>
<p>Токен бота видно на главной странице (кнопка &ldquo;Show token&rdquo; под ботом). URL вебхука:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">http://IP-СЕРВЕРА:8443/hook/ТОКЕН-БОТА?format=alertmanager
</span></span></code></pre></div><p>Форматы: <code>alertmanager</code>, <code>grafana</code>, <code>zabbix</code>, <code>raw</code>.</p>
<h3 id="дать-доступ-коллегам">Дать доступ коллегам</h3>
<p>Settings → Invite → скопировать ссылку-приглашение. Человек перейдёт по ней и зарегистрируется.</p>
<h3 id="бэкап">Бэкап</h3>
<p>Вся база данных — в папке <code>~/pusk/data</code>. Бэкапим её:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">cp -r ~/pusk/data ~/pusk-backup-<span class="k">$(</span>date +%Y%m%d<span class="k">)</span>
</span></span></code></pre></div><h3 id="обновить-на-новую-версию">Обновить на новую версию</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="nb">cd</span> ~/pusk
</span></span><span class="line"><span class="cl">docker compose pull
</span></span><span class="line"><span class="cl">docker compose up -d
</span></span></code></pre></div><h3 id="посмотреть-логи">Посмотреть логи</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose logs -f
</span></span></code></pre></div><p><code>-f</code> — следить в реальном времени. <code>Ctrl+C</code> — выйти.</p>
<h3 id="остановить">Остановить</h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">docker compose down
</span></span></code></pre></div><p>Данные в <code>data/</code> останутся на месте. При следующем <code>docker compose up -d</code> всё поднимется как было.</p>
<h2 id="доступ-из-интернета">Доступ из интернета</h2>
<p>Из локальной сети Pusk доступен сразу — по IP сервера и порту 8443.</p>
<p>Если нужен доступ из интернета, есть варианты:</p>
<p><strong>Вариант 1. Проброс порта на роутере.</strong> Заходишь в админку роутера → Port Forwarding → пробрасываешь внешний порт 8443 на внутренний IP:8443 сервера.</p>
<p><strong>Вариант 2. Reverse proxy.</strong> Если есть домен и хочется нормальный HTTPS — ставишь nginx или Caddy перед Pusk. Caddy проще всего — автоматически получает сертификат от Let&rsquo;s Encrypt:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl"><span class="c1"># Пример Caddyfile</span>
</span></span><span class="line"><span class="cl">pusk.example.com <span class="o">{</span>
</span></span><span class="line"><span class="cl">    reverse_proxy localhost:8443
</span></span><span class="line"><span class="cl"><span class="o">}</span>
</span></span></code></pre></div><h2 id="итого">Итого</h2>
<p>Весь процесс — 6 команд:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sudo apt install -y docker.io docker-compose-v2   <span class="c1"># Docker</span>
</span></span><span class="line"><span class="cl">sudo systemctl <span class="nb">enable</span> --now docker                  <span class="c1"># Включить</span>
</span></span><span class="line"><span class="cl">mkdir -p ~/pusk/data <span class="o">&amp;&amp;</span> <span class="nb">cd</span> ~/pusk                   <span class="c1"># Папка</span>
</span></span><span class="line"><span class="cl">cat &gt; docker-compose.yml <span class="s">&lt;&lt; &#39;EOF&#39;                   # Конфиг
</span></span></span><span class="line"><span class="cl"><span class="s"># ... содержимое выше
</span></span></span><span class="line"><span class="cl"><span class="s">EOF</span>
</span></span><span class="line"><span class="cl">sudo chown -R 100:101 ~/pusk/data                  <span class="c1"># Права</span>
</span></span><span class="line"><span class="cl">docker compose up -d                                 <span class="c1"># Запуск</span>
</span></span></code></pre></div><p>Один контейнер, один порт, один файл конфигурации. Данные на диске, бэкап — копирование папки. Обновление — <code>pull &amp;&amp; up -d</code>.</p>
<hr>
<p><em>Ссылки:</em></p>
<ul>
<li><a href="https://github.com/getpusk/pusk">Pusk на GitHub</a></li>
<li><a href="https://github.com/getpusk/pusk#readme">Документация</a></li>
<li><a href="https://github.com/getpusk/pusk#migrating-from-telegram">Миграция с Telegram</a></li>
</ul>
]]></content:encoded>
    </item>
  </channel>
</rss>
