🤹

自分で自分をホスティングするWebアプリケーション1: コンセプト

2021/06/18に公開

はじめに

IPFSを使って自分で自分をホスティングするWebアプリケーションについて考えます。「自分で自分をホスティングする」では呼びにくいのでセルフホスティングと呼ぶといいかもしれません。

プロトタイプの実装が完成していたので、記事を書こうと思ったのですが、そもそも何がやりたいのかわからないと思うので、この記事ではまずコンセプトについて説明します。実装についてはその2で書く予定です。

ここでは単に、「ホスティング=Webアプリケーションをインターネット上に公開すること」という程度の意味と考えてください。

IPFSについて詳しくはこちらのサイトをご確認ください。
https://ipfs.io/

まず一旦IPFSのアーキテクチャのおさらいから。

IPFSのアーキテクチャについて


ipfs.io/#why

IPFSはこれまでのサーバクライアント型のアーキテクチャとは異なり、P2Pネットワーク型であるため、ネットワークの帯域幅を節約することができるといわれています。

これはIPFSのノードがキャッシュサーバとして働くためと考えることができます。

状況を単純化するために、3つしかノードがないとして説明してみます。あるノードがファイルを他のノードに要求し受け取った後、受け取ったノードはファイルを保持します。そのためさらに他のノードが同じファイルを欲しくなったときには、2つのノードにファイルを要求することができます。

つまりあるファイルに対してアクセスが増えれば増えるほど、そのファイルを持っているノードが増えていくので帯域が逼迫することもないしサーバが落ちることもないというわけです。

※このファイルは画像などだけではなく、静的サイトの構成要素であるHTMLとCSS・JavaScriptファイルなども含まれ、SPAなどのWebアプリケーションをIPFS上でホストすることができます。

ゲートウェイが存在する場合

しかし、これまで述べてきたことは、クライアントが全て同等なIPFSのノードでありファイルを他のノードに再共有するという前提の上で成り立っています。
これは「P2P」の定義からすると「あたりまえ」なんですが、それがあたりまえでないパターンがあります。ゲートウェイを介する場合です。

https://docs.ipfs.io/concepts/ipfs-gateway/

ipfs-gatewayはIPFSネットワークの世界とHTTPの間にあるゲートウェイと考えてください。普通のブラウザはHTTPに対応していてIPFSには対応していませんが(Brave以外)、ゲートウェイを介せば接続できます。例えばこんな感じです。

https://ipfs.io/ipfs/Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u

ゲートウェイを介してつながる場合はクライアント(ブラウザ)はノードにはなりません。ただのサーバクライアント型のアーキテクチャで、サーバのバックグラウンドにデータ置き場としてIPFSネットワークを使っているにすぎません。そのためゲートウェイ自体はP2Pアークテクチャの恩恵はうけず、ネットワークが逼迫したら単純にゲートウェイに負荷がかかります。

これはいまのところ、そこまで大きな問題ではないです。ゲートウェイの負荷については他のゲートウェイにいくらでも切り替えられるし、もしくは自分でノードを立てても良いでしょう。

ただし、本来のコンセプトとは少し違ってしまっているとはいえるでしょう。またゲートウェイを立てるインセンティブがないので今後IPFSが活発に使われるようになると、問題が顕在化してくる可能性はあります。ブラウザがIPFSを採用すれば解決しますが、そうなる保証はありません。

理想をいえばファイルを閲覧するクライアント側にはそのファイルを持つインセンティブがあるのだから、そのままそのファイルを保持するノードとなるべきだと思います。

アプリケーション上にIPFSノードをのせその上に自分自身のデータをホストするというアイデア

実はゲートウェイのこちら側のブラウザが、IPFSノードになる方法があります。それはjs-ipfsを使うことです。

https://github.com/ipfs/js-ipfs

js-ipfsを使用すれば比較的簡単にブラウザ上の実行環境でIPFSノードを動かすことが可能です。

実装例はこちら
https://zenn.dev/ocknamo/articles/517c8b0de675e3

また先程チラッと触れたように、IPFS上にJavaScriptを含む静的サイトをホストさせることも可能です。

この2つを踏まえると、「IPFS上でホストされたWebアプリケーションそれ自体に自分自身をホストする」 ことも可能であるといえます。

前提条件として、共有されるファイルはそれ自体にjsの実行ファイルが含まれている必要があります。さらに、自分自身の情報を何らかの方法で知る必要があるため、自分の全てのファイルのパスをメタデータとして付与したり、CID(IPFS上のファイルパスのようなもの)を別の方法(外部のAPIなど)で取得するなどの必要があるでしょう。

アプリケーション上のノードは他のIPFS上のノードとつながるため、IPFSネットワーク上で帯域の負荷分散が起こります。また他のノードが全て落ちたとしても誰かがアプリを使用し続けていればアプリはホストされ続けることになります。
つまり理論上は、アクティブユーザが存在し続ければですが、アプリケーション提供者がホスティングのコストを負担しなくてもアプリを永遠に提供し続けることができてしまいます。[1]

以前別のところで、「IPFSとはいえホスティングのコストは誰かが負担しないといけないよ」という内容の記事を書いたのですが、セルフホスティングを使えば半永続的にコンテンツを保持できるようになるかもしれません。この場合コストはクライアントが(ネットワークと計算力という形で)負担しているわけですね。[2]
https://spotlight.soy/detail?article_id=eixemg1jt

サーバ代が心配な個人開発者的にも面白いコンセプトかなと思います。

配信の文脈で見ると

ここまで聞くと奇抜なアイデアのように感じられるかもしれませんが、Web配信の文脈で考えるとそれほどおかしな話ではないと考えています。

キャッシュを積極的に活用するWeb配信の典型的な構成を以下のようなものだとします。


CDNとオリジンのキャッシュを行なう場合の構成と保存される典型的なキャッシュの種類

CDN上のキャッシュとオリジンのゲートウェイキャッシュのデータは異なるクライアント間で再利用され共有されます。静的サイトであればアプリケーション全体をキャッシュすることもおそらく普通でしょう。一方で、あたりまえですが、クライアントのキャッシュはsharedキャッシュであっても他のクライアントと共有されることはありません。
しかし、今回のコンセプトのようにクライアントでIPFSノードを立てることができれば、キャッシュをクライアント同士で共有することができるようになります。つまりセルフホスティングとは単にクライアント同士が共有できるキャッシュの仕組み、と考えることもできます

Pros and Cons

最後に長所(Pros)と短所(Cons)を考えてみます。

  • Pros

    • IPFSネットワークへの負荷が抑えられる
    • (常にユーザがいれば)アプリをホストする必要がないかコストが低く抑えられる
    • アクセスが増えれば増えるほどレイテンシが低く抑えられる(おそらく。未検証)
  • Cons

    • 任意のタイミングで削除することができない

Prosはここまで書いてきたことのまとめになります。
Consですがキャッシュとして考えたときに任意のタイミングで削除できないというのは致命的な欠陥と言えるでしょう。キャッシュしてはいけない個人情報などのデータをコード上に載せてしまった場合にIPFS上から消すことができなくなるため、注意が必要です。

おわり

既にプロトタイプができているので次の記事で実装について解説する予定です。

<追記>
つづき
https://zenn.dev/ocknamo/articles/5c06f9df88121c

参考

Web配信の技術

脚注
  1. 現在のjs-ipfsは半中央集権なためWebRTC用のシグナリングサーバが落ちたら止まります。 ↩︎

  2. さすがに神奈川県警はこないと思う。多分。 ↩︎

Discussion