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