IPFS на сервере. Хостим сайты с ноутбука

h3z35k4o7jwppvlkpbzqg46lcog.jpeg

Мне часто нужно опубликовать статическую страницу или сайт, демо с веб-формой или версткой. Заливать каждый раз куда-то вроде Jsfiddle не всегда удобно, да и редактировать статику в локалхосте куда быстрее и приятнее. Проблемы начинаются, когда мне нужно кому-то показать мою работу, или просто открыть ту же страницу с телефона. Приходится хостить все эти бесконечные рабочие варианты и зарисовки, для каждой заново заливать файлы, прикручивать vhost-ы.

С помощью IPFS можно хостить сайты в интернете прямо с ноутбука, все обновления локальных файлов будут сразу применяться в интернете, и их не нужно куда-то заливать. Когда ноутбук отключен от сети, сайт все равно будет доступен. IPFS это как Bittorrent, только для веба.

В статье мы развернем IPFS ноду на сервере и попробуем эту технологию на практике.

Что такое IPFS

IPFS — это большая децентрализованная p2p-сеть, которую используют как файлообменник, веб-архив или замену Bittorrent. Все крутые примеры использования IPFS в реальных проектах можно посмотреть в зале славы на официальном сайте awesome.ipfs.io.

Вкратце работает оно так: хранимые файлы получают свой мультихэш и разбиваются на блоки, которые разлетаются по всем заинтересованным нодам. На нодах синхронизируется DHT, при скачивании файла собираются блоки с разных (в теории — ближайших) нод. Причём для доступа к файлу или директории не нужно поднимать свою ноду, они все доступны из браузера, что приводит нас к народно любимой фиче: на IPFS можно бесплатно хостить сайты. Но только статику, обновлять любые данные чаще, чем раз в несколько минут неудобно из-за тех же хэшей, которые формируют ссылку и меняются при каждом изменении в файле (существует система постоянных имён IPNS, но она медленная). Впрочем, это не помешало чувакам из Orbitdb запилить базу данных на IPFS, но там свои нюансы. Более подробно почитать про устройство сети можно здесь.

Допустим, у меня есть нода, с которой я бесплатно раздаю статические сайты, сам же на них хожу и иногда привожу коллег посмотреть. Общий объем данных ограничен только размером моего диска, а скорость загрузки — домашним интернетом, что может быть лучше? Но есть ряд проблем. Во-первых, самой IPFS нужно довольно много интернета и солидный кусок процессора, и даже без трафика она всегда отбирает часть ресурсов на синхронизацию DHT. Во-вторых, я в основном работаю с ноутбука и все файлы держу на нём же, и потому же далеко не всегда у меня под рукой домашнее полугигабитное волокно. Кратковременные разрывы для IPFS не проблема, она держит кэш в DHT несколько часов, но стоит куда-то уехать на пару дней, и вот уже все твои проекты радостно высыпаются из сети. Можно запиннить («запомнить») файлы на десктопе, но это как минимум вдвое увеличит трафик, что тоже не комильфо. Что делать? Я попробовал поднять ноду на сервере, чтобы разгрузить ноут, но мне всё еще приходилось грузить файлы вручную, как на обычный хостинг. В итоге я покурил доки и API и написал простенькую утилиту для синхронизации моей локальной статики с сервером.

4x5lxggev2ibpeaonvsaglapaeg.jpeg

У IPFS есть две самостоятельные реализации: go-ipfs и js-ipfs. Мне ближе JS, поэтому я писал на нём. Я хотел чтобы утилита могла подхватывать папки с моими сайтами, и регулярно загружать их в сеть, пока я работаю. Серверная часть должна ловить хэши папок и пиннить их, чтобы файлы не потерялись.

Установка

npm install ipfs -g

У js-ipfs довольно подробный туториал с примерами, поэтому:

git clone https://github.com/ipfs/js-ipfs.git
cd js-ipfs
npm install
npm run build

Нода запускается в несколько строк:

const IPFS = require('ipfs')
async function main () {
  const node = await IPFS.create()
}
main()

Конфиги и сиды для неё прописываются тут же, но для старта достаточно этого.
Дальше нужно передать ноде файлы и загрузить их в IPFS. Для этого используем node.add с параметром { recursive: true } для папок. Адрес можно передавать в аргументах при запуске, а сохранять по команде. Важно записать только последний хэш — он от корневой папки:

zt6znegn7ek9vtqs_qudycx3rzq.png

Вся папка успешно ушла в сеть. По ссылке откроется сайт, а саму папку можно проверить на вебморде IPFS:

kagug9rmdcsgfhyb_d-rh21s4sc.png

Дальше чтобы сделать процесс сохранения удобным, я дописал сохранение с номером версии и публикацию в IPNS через node.name.publish. Но сохранение вручную это скучно! Я хочу иметь возможность смотреть обновленный сайт так же быстро, как вижу изменения в локалхосте, а значит, обновление должно происходить автоматически. А ещё если я вдруг забуду сохранить что-то, выключу ноутбук и поеду домой, актуальная версия сохранится не только в редакторе, но и в сети. Сделаем автосейвы по дефолту раз в 10 минут, с возможностью изменять интервал для разных темпов работы. Кстати, если файлы не менялись с последнего сохранения, не поменяется и хэш.

0aywqpsnhwustcwcvvoxjyjnvky.png

Круто, но пока все файлы мы раздаем с локальной машины. Пора подключать серверную ноду! Берём экспериментальный pubsub, получаем топик из аргументов при запуске и пробуем доставить хэш сохранения:

u9bpnezt7fddmxpo3oworszo7rw.png

Ура! Дело за малым — заставить сервер хранить все полученные хэши и пиннить их (node.pin.add), и научить клиент вырубать свою ноду, когда она не нужна (node.stop).

632et_yscta-mwwbzhj5a9mac9y.png
Так выглядит список загрузок на серверной ноде

Что в итоге?

  • Когда я сажусь писать код, он автоматически сохраняется в IPFS
  • Все версии всегда доступны по персональным ссылкам /ipfs/Qm…
  • Я могу публиковать сайт в IPNS, чтобы не слать клиенту ворох ссылок
  • Локальная нода просыпается, только чтобы выгрузить файлы и связаться с сервером, после засыпает обратно
  • Локально у меня хранится только одна копия сайта, трафик на единичные загрузки новых версий кратно меньше фонового трафика ноды IPFS
  • Я наконец-то могу работать в локалхосте без головной боли с версионностью

Всё это счастье обходится мне по цене самого дешевого VPS, ресурсов пока хватает и должно хватить еще где-то на год вперёд, после чего можно будет докупить ещё один сервер или заархивировать старый.

Вообще с помощью IPFS можно делать и гораздо более интересные штуки. Я вот точно хочу довести до ума эту утилитку и написать новую, с гуи. А пока вот держите сайт, который мы писали и хостили всё это время:

https://ipfs.slipner.ru/ — с доменом
https://ipfs.io/ipfs/QmeV7MVFSiWJr8u4dhXzEAoJgbVJsHvSUqjsbQyNL4WrD2 — IPFS
https://gateway.ipfs.io/ipns/QmTjKBMJS8owPUXQFSMjoR4kqFNXXVKB7DqNGgyqibxuff/ — IPNS через официальный гейт

Браузер Opera с поддержкой IPFS


ta4vganttbqfbcoaahcp6e3cd8w.png

Буквально несколько дней назад Opera Software выкатили первый браузер с нативной поддержкой IPFS. Пока, правда, только в мобильной версии для Android. Это значит, что он может напрямую обращаться в сеть IPFS без веб-шлюзов! Ждем когда поддержку добавят в десктопную версию.


odfmwacxus3phgvaxyooajzkns4.png

© Habrahabr.ru