IPFS 静态网站部署指南

与四年前写博客 在 IPFS 上部署静态博客 时相比,现在 IPFS 更加成熟了,也多了很多相关的服务,也考虑到原来的博文现在看来有点繁琐且过时,所以这次进行了重构并添加了周边服务的介绍。

1. 安装 IPFS

1
2
3
4
5
6
# 安装 IPFS,此处使用 brew 为例
brew install ipfs
# 初始化,生成本地公私钥,默认配置等
ipfs init
# 保持 IPFS 运行
ipfs daemon

2. IPFS 本地访问静态页面

一般我们的静态页面都包含一个 index.html,放在 public 文件夹中,现在将 public 文件夹添加到 IPFS 中

1
ipfs add -r public

产生如下输入,表明添加成功

1
2
3
4
5
added QmT47uvcmBktejvAmKgEUwZjCUZQpvmdd2ZxgT5LsfmjFJ public/content-hash.js
added QmXeszC4BUxYc9kX2RA3hTLXUJYhh6qSGvs7qcHJq9XmkE public/index.html
added QmW3bcW7H3j1jxutqrLWZ959wF5Qj3iD1VgnK3Vm46cbH2 public/my-decoder.js
added QmdkSpWEaZFM6iPGbtDqkd6bukw7BijNkxaG5a7L5vYoRL public
187.86 KiB / 187.86 KiB [=======================================================] 100.00%

使用 public 目录的 CID 通过本地 IPFS Gateway 便可访问这个简单的网页 http://localhost:8080/ipfs/QmdkSpWEaZFM6iPGbtDqkd6bukw7BijNkxaG5a7L5vYoRL

3. 借助 IPNS 保持链接不变

如果现在我们的网页发生一些变更,则变更后的 public 目录 CID 会发生变化,导致网页访问地址发生变化,否则就只能访问旧版本的网页,IPNS 就用于解决这个问题。

通过以下命令将 public 目录的 CID 发布(绑定)到当前节点的 PeerID(节点公钥的哈希)。

1
ipfs name publish QmdkSpWEaZFM6iPGbtDqkd6bukw7BijNkxaG5a7L5vYoRL

输出如下,k51q…jzot 便是 PeerID。

1
Published to k51qzi5uqu5dgcop6koxxjmjg6ul5u14g5up8xsyxdarr21r6s1565qie6jzot: /ipfs/QmdkSpWEaZFM6iPGbtDqkd6bukw7BijNkxaG5a7L5vYoRL

现在我们可以通过 http://localhost:8080/ipns/k51qzi5uqu5dgcop6koxxjmjg6ul5u14g5up8xsyxdarr21r6s1565qie6jzot 访问简单网页(每个节点因为私钥不同,所以 PeerID 也不同,你需要改变链接中的 PeerID 部分再尝试访问),之后如果网页有所变更,只要再次 name publish 操作便仍然可以使用此链接访问变更后的网页。

4. 绑定域名缩短访问链接

目前的访问链接很长,我们可以把 ipns 绑定到自己拥有的域名来缩短访问链接,以托管在 cloudflare 的本站域名 velih.de 为例,在 DNS 管理中添加一条 TXT 记录,Name 配置为 _dnslink.你的子域名名称,直接使用一级域名则配置为 _dnslink,Content 配置为 dnslink=/ipns/你的IPNS

1
TXT _dnslink.enstool.velih.de dnslink=/ipns/k51qzi5uqu5dgcop6koxxjmjg6ul5u14g5up8xsyxdarr21r6s1565qie6jzot

现在我们可以直接通过 http://localhost:8080/ipns/enstool.velih.de 来访问简单网页了。然后我们将本地 Gateway 地址替换为公共 Gateway 列表中的域名实现公网访问了,比如:

5. 域名直接访问

再进一步,继续为域名添加一条 CNAME 记录,Name 配置为你的子域名名称,一级域名则设置为 @,Content 配置为一个公共的或者自建的 Gateway,我这里将 enstool 这个子域名绑定到了 Cloudflare 提供的公共 Gateway cf-ipfs.com

1
CNAME enstool.velih.de cf-ipfs.com

此时,可以直接通过 https://enstool.velih.de 进行访问了。

6. 去中心化域名访问:以 ENS 为例

域名存在一些中心化的问题,比如注册机构是中心化的,DNS 的解析是中心化的,去中心化域名提供了另一种选择。

EIP-1557 中 ENS 开始支持 ContentHash,IPNS 就是可以配置的 ContentHash 的一种。只要为 ENS 配置上 IPNS 便可以连接 ENS 与存在 IPFS 中的内容了。

velih.eth 为例,在该 ENS 的管理界面,点击 ADD/EDIT RECORD,选择添加 Content,值设置为 /ipns/你的IPNS,注意这一步会产生一笔交易,一定要确定填写的内容的正确性,Save 保存后再点击下方 Confirm 确认,与钱包交互签名交易,交易确认后便可以通过以下方式使用 ENS 访问网站了:

另一种常用的 ContentHash 是 IPFS 的 CID,格式为 /ipfs/cid 或者 ipfs://cid。这种方式问题在于之前提到的,每次网页变更都需要重新配置一次,也就是需要产生一笔花费手续费的交易,因此适合不怎么变更的内容。不过 Ethereum 创始人 Vitalik 的博客 ENS vitalik.eth 就使用的这种形式。每次 Vitalik 发布新的文章后都会通过交易变更 IPFS CID,比如 Vitalik 发布 2022 年最后一篇文章后便执行交易,以变更 vitalik.eth 的 ContentHash 为 0xe301017012208007f6b5b03e0aa1d1829c568ce4f52e177058448b73ad8d831228931925900f,通过 Content Hash Decoder 工具可以转换得到实际内容为 /ipfs/QmWxRwMg3bHyJxfAuPnUky2yNgNt51qmZqC99Ffenjxa94,便是此时博客根目录的 IPFS CID。



CID 作为 ContentHash 的方式对大部分人来说有些“昂贵”,特别是 Ethereum GasPrice 比较高的时候,但是对于 Vitalik 来说可能没有那么贵,而且可以省去运行 IPFS 节点维护 IPNS(见 可用性优化)私钥的麻烦,而且有大量的第三方主动帮忙 Pin Vitalik 的博客。所以对他来说是更优的选择。

另外 .bit、HNS 这些去中心化域名也支持类似的方式进行配置访问。

7. 可用性优化

我们引入了 IPNS 来优化访问链接,但是 IPNS 的默认传输广播机制是通过 DHT 进行的,对等节点会在 24 小时后遗忘 IPNS 记录。因此自己的 IPFS 节点会默认每 4 小时周期性地重新发布 IPNS 以防对等节点遗忘。所以一旦我们本地运行的 IPFS 实例关机超过 24 小时,那上面通过 IPNS 的几种访问方式便会失效。而且对等节点,比如上面公共 Gateway 的节点,在我们访问简单网页后,可能会缓存简单网页一段时间,但是 IPFS 的垃圾回收机制过不了多久就会删除一段时间内没被访问的对象。所以当我们的 IPFS 实例停机更长时间而且我们放在 IPFS 的文件没有很大热度,这些文件就会被网络遗忘,最初通过 CID 直接访问的方式也就失效了。以下几个方式可以优化可用性:

7.1. 云服务器运行 IPFS 实例

部署在本地计算机的节点难免会关机,将节点部署到云服务器会比本地计算机运行得更稳定。具体步骤可以参考我的另一篇博客 IPFS Gateway 部署指南。部署完成后你还需要将自己的文件上传到 Gateway,可以手动操作、自己构建简单的脚本通过 Gateway API 上传,如果相关文件托管在 Github,那也可以借助 Upload to IPFS 这个 Github Action 实现自动化上传。当然别忘了在域名中配置 IPNS。

如果你有更高可用性要求,可以尝试 IPFS Cluster 部署 IPFS 节点集群。

7.2. 4everland、Fleek & Pinner

4everland 提供了比较完善且方便的部署体验,支持从 IPFS CID 或者 Github 直接导入原始文件,分配 IPNS 并自动发布,也支持绑定 ENS。Fleek 功能类似。但是这些平台都一定程度上以牺牲去中心化为代价,比如 IPNS 对应的私钥便由平台创建,存在安全风险。与自己部署相比,有些类似将资产托管在交易所与自己创建钱包管理资产的区别。

相较上面两个提供完善的部署服务,还有一些只是提供文件托管服务,称为 Pinner,比如 InfuraPinataWeb3 Storage 等。借助 ipfs-deploy 工具可以方便地将静态页面托管到这些服务,部署到 IPFS,ipfs-deploy 也可以辅助完成传统域名的 DNSLink IPFS CID 配置,但不支持 IPNS 和 ENS。

7.3. Planet

Planet 是一个基于 IPFS 和 ENS 的免费且开源的工具用于创建,托管和关注去中心化 Web 内容。借助 Planet 客户端可以完成上文大部分工作。每一个关注你 Planet 的用户都会帮忙 Pin 一份你的内容,这样你的内容可用性就会变高。当然如果你初来乍到或者久久没有得到多人的关注,那想要自己的 Planet 能持久被访问,要不就一直保持 Planet 客户端运行,要不还是得借助自部署的 IPFS 节点或者 Pinner 以保持可用性。对于一个不喜欢上文中这么多复杂操作的普通用户而言,Planet 肯定是最优的选择。

Reference

  1. EIP-1577: contenthash field for ENS
  2. IPNS (InterPlanetary Name System) and Mutability | IPFS Docs
  3. DNSLink Standard
  4. CID Inspector | IPFS

Powered by Hexo and Hiker

Copyright © 2018 - 2024 Velih's Blog All Rights Reserved.

Velih Dzen 保留所有权利