После создания сервера Grist разворачивается сам: Docker поднимает контейнер с приложением, отдельный контейнер Caddy выпускает Let's Encrypt и открывает доступ по HTTPS на magic-DNS адресе - вручную ничего настраивать не нужно. Первый старт занимает несколько минут: скачивание образа и запуск контейнеров.

Что внутри

  • Grist (Node.js + Python 3.11 для формул) - приложение: таблицы, связи между ними, права доступа, веб-интерфейс.
  • gVisor - изолированная песочница для исполнения формул (это настоящий Python со стандартной библиотекой) - не отключаем, это защита, а не опция.
  • SQLite - каждый документ отдельный файл в томе /persist, никакой внешней базы. Файл можно скачать и открыть без Grist.
  • Caddy - reverse-proxy и авто-TLS (Let's Encrypt), отдельный контейнер. Grist слушает только localhost.

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

  • Вход закрыт по умолчанию - до первичной настройки любой запрос (страница или API) получает отказ, посторонний с адресом ничего не увидит.
  • Формулы исполняются в песочнице gVisor, а не прямо в контейнере - рецепт включает ее всегда, это не опция для ручной настройки.
  • fail2ban - банит IP после серии неудачных попыток входа по SSH.
  • HTTPS + security-заголовки - Let's Encrypt с автопродлением, HSTS, X-Content-Type-Options, Referrer-Policy.

Как войти

  1. Адрес формируется из IP сервера: замените точки на дефисы и добавьте .fatmetal.net. Пример: IP 45.15.159.190 -> https://45-15-159-190.fatmetal.net.
  2. Первый вход - экран первичной настройки: ключ - пароль этого сервера, тот же, что для SSH; почта - значение ADMIN_EMAIL (если задавали при заказе), иначе admin@<ваш-адрес>. После этого шага вы владелец установки.
  3. Дальше это обычный логин: браузер запоминает сессию, при следующем визите экран настройки не покажется, пока сессия жива. Потеряли сессию (другой браузер, чистка) - тот же ключ на экране настройки пускает внутрь снова, он не одноразовый.

Свой домен

Направьте A-запись на IP этого сервера, задайте DOMAIN=ваш.домен в /etc/grist-mp/params.env и выполните bash /opt/grist-mp/install.sh - Caddy перевыпустит сертификат под новый домен. Полная инструкция - на сервере: cat /root/grist-credentials.txt.

Требования

Тариф CPU2-RAM4-DISK50: в простое Grist держит около 230 МиБ, документ на сто тысяч строк - 419 МиБ, пик при экспорте в XLSX - 657 МиБ. Песочница gVisor добавляет к этому около 69 МиБ - отключать ее не стоит, это защита формул, а не опция. Документация вендора называет "known good" 8 ГБ - продукту столько не требуется.

AI-помощник по формулам - опционально: нужен ключ провайдера моделей на ваш выбор (OpenAI/OpenRouter/любой OpenAI-совместимый), вписывается в ASSISTANT_API_KEY (/etc/grist-mp/params.env). Обращения идут через прокси Fatmetal (api-proxy.fatmetal.net:8080), он уже включен в сервер - свой прокси поднимать не нужно.

Подробный разбор с замерами