Установка
Эта инструкция рассчитана на то, что вы никогда раньше не разворачивали Docker-приложения и не администрировали Linux-сервер. Все команды даны в готовом для копирования виде.
Что понадобится
- Linux-сервер (VPS/выделенный сервер) — подойдёт Ubuntu 22.04/24.04, Debian 12 или дистрибутив RedHat-семейства (AlmaLinux 9/10, Rocky Linux 9/10, RHEL 9/10). Требования к CPU/RAM/диску — в таблице ниже.
- Docker и Docker Compose — единственная зависимость. Больше ничего (ни PHP, ни nginx, ни базы данных) устанавливать вручную не нужно — всё это уже упаковано в контейнеры.
- Доступ к серверу по SSH.
- (Не обязательно, но желательно для реальной эксплуатации) доменное имя, указывающее на IP сервера.
Системные требования
Gotcha поднимает на одном сервере три процесса: само приложение (Go), PostgreSQL и ClickHouse. Основной потребитель памяти и диска — ClickHouse, в котором хранится телеметрия (события, трейсы, метрики, профили), поэтому и требования определяются в первую очередь им.
| Минимум | Рекомендуется | |
|---|---|---|
| CPU | 2 vCPU | 4 vCPU |
| RAM | 2 ГБ | 4 ГБ и больше |
| Диск | 20 ГБ SSD | 40 ГБ SSD и больше |
- ОС: Ubuntu 22.04/24.04, Debian 12 или RedHat-семейство (AlmaLinux 9/10, Rocky Linux 9/10, RHEL 9/10), архитектура x86-64 (amd64). Gotcha работает в Docker, поэтому дистрибутив почти не важен — различия только в командах установки Docker/git и в файрволе, они отмечены по ходу инструкции.
- RAM. 2 ГБ — рабочий минимум для запуска и небольшой нагрузки (личные проекты, стейджинг). Для продакшена с реальным потоком событий закладывайте от 4 ГБ: под нагрузкой ClickHouse тем стабильнее, чем больше ему доступно памяти.
- Диск. Растёт вместе с объёмом телеметрии и сроком её хранения (retention). 20 ГБ хватает, чтобы стартовать; при заметном трафике или длинном retention планируйте больше и следите за свободным местом — как именно, см. Мониторинг gotcha. Диск обязательно SSD — и ClickHouse, и PostgreSQL чувствительны к его латентности.
- CPU. Двух ядер достаточно; дополнительные ядра ускоряют приём всплесков событий и запросы ClickHouse.
- Сеть. Наружу нужен только один порт приложения (по умолчанию 59080). PostgreSQL и ClickHouse наружу не выставляются — они доступны лишь внутри docker-сети.
Если сервер на минимуме (2 vCPU / 2 ГБ)
Заводские настройки PostgreSQL и ClickHouse рассчитаны на крупные серверы. На минимальной конфигурации они заметно тратят ресурсы впустую: ClickHouse по умолчанию ведёт подробные системные логи без ограничения срока хранения, и на слабой машине их обслуживание съедает больше, чем полезная работа.
Для таких серверов есть готовый оверлей — запускайте с двумя файлами:
docker compose -f docker-compose.yml -f docker-compose.small.yml up -d
Замеры на VPS 2 ядра / 2 ГБ / 20 ГБ SSD: память ClickHouse снизилась с 880 до 295 МБ, занятое место на диске — с 12 до 9.2 ГБ, load average — с 1.15 до 0.79.
Оверлей ставит потолки, осмысленные только на слабом железе. На сервере с запасом ресурсов его применять не нужно — там он ограничит приём событий и замедлит запросы. Обычный запуск (docker compose up -d) уже включает настройки, полезные на любой машине.
Шаг 1. Проверьте, установлен ли Docker
Подключитесь к серверу по SSH и выполните:
docker --version
docker compose version
Если обе команды напечатали номер версии — Docker уже есть, переходите к шагу 2.
Если вы видите command not found, ставьте Docker. Команды зависят от того, какое у сервера семейство дистрибутивов, — выберите свой раздел.
Ubuntu, Debian и другие deb-дистрибутивы
Официальный скрипт Docker делает всё сам:
curl -fsSL https://get.docker.com | sudo sh
Docker Compose (команда docker compose, с пробелом) ставится вместе с Docker, отдельно не нужен. Сервис после установки запускается сам.
AlmaLinux, Rocky Linux, RHEL и другие rpm-дистрибутивы
Здесь есть две ловушки, из-за которых установка «по привычке» заканчивается неработающим сервером.
Ловушка первая: dnf install docker ставит не Docker. В штатных репозиториях RedHat-семейства пакета Docker нет, а есть podman-docker — обёртка, которая эмулирует команду docker поверх Podman. Выглядит это так:
# dnf install docker
...
Installed: podman-docker-5.8.2-5.el9_8.noarch
# docker --version
Emulate Docker CLI using podman. Create /etc/containers/nodocker to quiet msg.
podman version 5.8.2
# sudo usermod -aG docker $USER
usermod: group 'docker' does not exist
# sudo systemctl enable --now docker
Failed to enable unit: Unit file docker.service does not exist.
Группы docker нет, сервиса docker нет — потому что и Docker никакого нет.
Ловушка вторая: официальный скрипт установки не поддерживает AlmaLinux. curl -fsSL https://get.docker.com | sudo sh на ней отвечает ERROR: Unsupported distribution 'almalinux'.
Правильный путь — официальный репозиторий Docker CE. Если ранее ставили podman-docker, его придётся удалить: он занимает то же имя команды /usr/bin/docker, и установка Docker CE поверх него падает с конфликтом пакетов.
# 1. Убрать обёртку Podman, если она была установлена
sudo dnf remove -y podman-docker
# 2. Подключить официальный репозиторий Docker
sudo dnf install -y dnf-plugins-core
sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 3. Установить Docker и плагин Compose
sudo dnf install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 4. Запустить сервис и включить автозапуск (сам он не стартует)
sudo systemctl enable --now docker
Репозиторий именно centos — Docker не собирает отдельные пакеты для AlmaLinux и Rocky, а собранные для CentOS Stream на них работают. Проверено на AlmaLinux 9 и 10.
После установки (любой дистрибутив)
Добавьте своего пользователя в группу docker, чтобы не набирать sudo перед каждой командой, и перезайдите по SSH, чтобы это применилось:
sudo usermod -aG docker $USER
exit
Зайдите на сервер заново и повторите docker --version и docker compose version — обе команды должны напечатать номер версии.
Шаг 2. Скачайте код Gotcha
Если на сервере есть git
# gitflic (основной, анонимный HTTPS)
git clone https://gitflic.ru/project/otezvikentiy/gotcha.git
# GitHub (зеркало)
git clone https://github.com/OtezVikentiy/gotcha.git
# Контрибьюторы с SSH-доступом могут использовать:
# git clone git@gitflic.ru:otezvikentiy/gotcha.git
cd gotcha
Если git не установлен
Ставить его необязательно — можно скачать архив с зеркала на GitHub и распаковать. curl и tar есть в любом дистрибутиве из коробки:
curl -fsSL https://github.com/OtezVikentiy/gotcha/archive/refs/heads/main.tar.gz -o gotcha.tar.gz
tar xzf gotcha.tar.gz
cd gotcha-main
Разница с git clone только одна: обновляться потом придётся тем же способом — скачивать свежий архив, а не делать git pull. Если планируете обновлять инстанс регулярно, git всё же удобнее: sudo apt install -y git для Ubuntu/Debian, sudo dnf install -y git для AlmaLinux/Rocky/RHEL.
В распакованной папке лежит docker-compose.yml — файл-рецепт, который описывает, какие три контейнера нужно поднять и как их связать между собой. Все дальнейшие команды выполняются из неё.
Шаг 3. Запустите контейнеры
make up-rebuild
(make вычисляет git-версию и вшивает её в сборку — /version и страница «О программе» назовут точный релиз. Если make не установлен, сработает и docker compose up -d, но инстанс будет представляться как «no build metadata» вместо проверяемой версии.)
Что произойдёт:
- Docker соберёт образ приложения Gotcha (компилирует Go-программу в контейнере — при первом запуске это может занять пару минут).
- Поднимутся три контейнера:
gotcha— само приложение: HTTP-сервер, веб-интерфейс, приём событий от SDK, миграции схемы БД при старте.postgres(PostgreSQL 17) — хранит «обычные» данные: пользователей, организации, проекты, правила алертов, инциденты.clickhouse(ClickHouse 25.3) — хранит большие объёмы телеметрии: сами события об ошибках, трейсы, метрики, профили, результаты аптайм-проверок.
- Флаг
-d(«detached») означает «запустить в фоне и вернуть терминал» — контейнеры продолжат работать после того, как вы закроете SSH-сессию.
Postgres и ClickHouse наружу (на хост-машину) не выставлены — до них можно достучаться только изнутри docker-сети, между контейнерами. Наружу торчит только порт приложения.
Проверьте статус:
docker compose ps
Все три строки должны показывать Up (у postgres и clickhouse — Up (healthy), у gotcha может уйти на подъём до минуты первый раз, пока применяются миграции).
Шаг 4. Проверьте, что всё поднялось
Приложение слушает порт 59080 на хосте по умолчанию (см. docker-compose.yml: "${GOTCHA_PORT:-59080}:8080" — это порт хоста слева, порт контейнера справа; выбран нестандартный 59080, чтобы не конфликтовать с другими сервисами на сервере). Проверьте health-эндпойнт:
curl -sf http://localhost:59080/readyz
Ответ вида {"status":"ready","clickhouse":"ok","postgres":"ok"} с HTTP-кодом 200 означает, что приложение поднялось и обе базы данных ему отвечают. Если curl завис или вернул ошибку — см. раздел «Устранение неполадок» ниже.
Ручек две, и отвечают они на разные вопросы:
| Ручка | Вопрос | Когда отдаёт 503 |
|---|---|---|
/healthz | процесс жив? | никогда, пока отвечает HTTP |
/readyz | готов работать? | пока PostgreSQL или ClickHouse недоступны |
Разница важна при настройке оркестратора: /healthz — для liveness-пробы (перезапустить зависший процесс), /readyz — для readiness (не слать трафик). Если повесить liveness на /readyz, сбой хранилища превратится в перезапуск живого контейнера, а каждый перезапуск выбрасывает то, что накопилось в буферах в ожидании возвращения хранилища.
Готовые обёртки есть в Makefile, если вы предпочитаете make:
make up # docker compose up -d
make ps # docker compose ps
make health # curl /readyz
make logs # docker compose logs -f gotcha (Ctrl+C для выхода)
Откройте в браузере http://<IP-адрес-вашего-сервера>:59080 (или http://localhost:59080, если открываете с самого сервера/через SSH-туннель) — должна открыться страница входа Gotcha.
Шаг 5. Задайте секретный ключ (обязательно для реального сервера)
Эти два шага настройки идут до создания первого пользователя намеренно: регистрация — это POST-запрос, и с неверным GOTCHA_BASE_URL тот самый первый POST будет отклонён с 403 (см. шаг 6).
По умолчанию Gotcha использует GOTCHA_SECRET_KEY=insecure-dev-secret. Значение публично — оно лежит прямо в исходном коде на GitFlic, его знает кто угодно. Этим ключом подписываются сессионные cookie и OAuth state-cookie; если оставить дефолт на сервере, доступном по интернету, злоумышленник, знающий этот ключ, может подделать cookie и увести чужой аккаунт через OAuth-вход (account takeover).
Поэтому: если ваш GOTCHA_BASE_URL не localhost/127.0.0.1 (то есть у вас настоящий сервер, а не локальная разработка), приложение откажется стартовать в режимах web, all, ingest и uptime (везде, кроме probe), пока вы не зададите свой ключ.
Сгенерируйте случайный ключ:
openssl rand -base64 32
Создайте файл .env рядом с docker-compose.yml — Docker Compose читает его автоматически. Той же командой ограничьте права на файл: в нём будет лежать мастер-ключ, которым шифруются секреты каналов алертов и SSO, а возможно и пароль SMTP (Резервное копирование уже требует 600 для копии этого файла — оригинал не должен быть слабее):
cp .env.example .env && chmod 600 .env
nano .env
Раскомментируйте GOTCHA_SECRET_KEY и замените значение на то, что вывела команда выше:
GOTCHA_SECRET_KEY=вставьте-сюда-случайную-строку-из-openssl
Примените изменение (пересоздаёт контейнер gotcha с новой переменной окружения):
docker compose up -d
Шаг 6. Укажите публичный адрес (GOTCHA_BASE_URL)
GOTCHA_BASE_URL — это адрес, по которому пользователи и SDK на самом деле обращаются к вашему инстансу. Из него строятся: DSN проектов (то, что вы вставляете в код приложений), ссылки в письмах-приглашениях, ссылки на инциденты в алертах (Telegram/webhook/email). Он же — эталон для проверки происхождения, защищающей каждую форму: POST с адреса, отличного от GOTCHA_BASE_URL, отклоняется с 403 — включая форму регистрации на следующем шаге.
Раскомментируйте в том же .env:
GOTCHA_BASE_URL=https://gotcha.example.com
(или http://<IP-сервера>:59080, если пока без домена и без HTTPS — но см. чек-лист ниже, почему HTTPS важен). Примените:
docker compose up -d
Шаг 7. Создайте первого пользователя
Откройте http://<адрес-сервера>:59080/register и зарегистрируйтесь.
Важно: первый пользователь на чистом инстансе регистрируется всегда, независимо от режима самостоятельной регистрации (GOTCHA_REGISTRATION), и автоматически получает права инстанс-администратора. Это «bootstrap» — так вы получаете первого админа на свежей установке без ручных манипуляций с базой. Все последующие регистрации уже подчиняются GOTCHA_REGISTRATION (подробнее — Конфигурация).
После входа: создайте организацию, затем проект внутри неё. На странице проекта «Подключение» (URL вида /projects/<id>/setup, также доступна кнопкой «Подключение SDK» в списке проектов) будет DSN — адрес, на который направляется SDK вашего приложения (Sentry SDK любого языка работает с Gotcha без изменений, так как используется тот же протокол приёма). Подробный разбор — Первые шаги и SDK и интеграции.
Минимальный чек-лист для продакшена
Прежде чем давать доступ реальным пользователям/направлять на инстанс реальный трафик приложений, убедитесь:
GOTCHA_SECRET_KEY— задан свой случайный ключ (шаг 5), не дефолтный.GOTCHA_BASE_URL— указывает на реальный публичный адрес.HTTPS — Gotcha сам TLS не терминирует, поставьте перед ним reverse-proxy:
- nginx: конфиг с
proxy_pass http://127.0.0.1:59080;и сертификатом от Let’s Encrypt (certbot --nginx). - Caddy: ещё проще, HTTPS настраивается автоматически — в
Caddyfileдостаточно строкиgotcha.example.com { reverse_proxy localhost:59080 }.
Без HTTPS сессионные cookie идут по сети открытым текстом — сервер даже предупредит об этом в логах (
GOTCHA_BASE_URL is non-local plain HTTP).- nginx: конфиг с
SMTP — без него не работают письма-приглашения и email-канал алертов. Настройка — в Конфигурации.
Резервное копирование — настройте до того, как в базе появятся важные данные. См. Резервное копирование и восстановление.
Квоты — если DSN проекта может утечь публично (например, фронтенд-JS), задайте
GOTCHA_DEFAULT_*_QUOTA(по умолчанию в oss-редакции — безлимит). См. Конфигурацию.
Устранение неполадок
Контейнеры не стартуют / падают. Посмотрите логи:
docker compose logs -f gotcha
docker compose logs -f postgres
docker compose logs -f clickhouse
Частая причина — сообщение об ошибке конфигурации (например, требование задать GOTCHA_SECRET_KEY, см. шаг 5) прямо в логе gotcha.
Порт уже занят (bind: address already in use).
На сервере что-то уже слушает 59080. Задайте другой порт хоста через .env:
GOTCHA_PORT=8081
и docker compose up -d. Приложение внутри контейнера по-прежнему слушает 8080 — меняется только то, на какой порт хоста он «пробрасывается».
Не открывается веб-интерфейс, хотя контейнеры Up.
- Проверьте firewall на сервере. Ubuntu/Debian:
sudo ufw status— при включённом ufw разрешите порт:sudo ufw allow 59080/tcp. AlmaLinux/Rocky/RHEL: firewalld включён по умолчанию — разрешите порт:sudo firewall-cmd --permanent --add-port=59080/tcp && sudo firewall-cmd --reload. - Если сервер у облачного провайдера/хостинга — проверьте Security Group / файрвол в панели управления хостингом отдельно от
ufw(часто трафик режется именно там). - Проверьте
curl -sf http://localhost:59080/healthzс самого сервера — если это работает, а снаружи нет, проблема сетевая (firewall/провайдер), а не в Gotcha.
Формы, регистрация или логин отдают forbidden (403).
Gotcha защищает POST-запросы проверкой источника: Origin/Referer запроса должен совпадать с GOTCHA_BASE_URL по scheme и host. Если открыть интерфейс по адресу, отличному от GOTCHA_BASE_URL (например, по http://localhost, когда BASE_URL — публичный HTTPS-домен, или через туннель/прокси с другим хостом), любой POST срежется в 403. Открывайте UI строго по адресу из GOTCHA_BASE_URL.
/readyz отвечает 503 со статусом unavailable у postgres/clickhouse.
Значит приложение живо (/healthz отвечает 200), но не может достучаться до одной из баз. Обычно это означает, что база ещё не поднялась (первый запуск ClickHouse может занимать до минуты) — подождите и повторите. Если не проходит долго — смотрите docker compose logs postgres / docker compose logs clickhouse.
Что дальше
- Конфигурация — полный список переменных окружения.
- Резервное копирование и восстановление.
- Обновление.
- Первые шаги — создание проекта и первое событие.
- SSO — вход через OIDC/Yandex ID/VK ID.