# 如何在ipfs上发布静态网站

> 2023.07.27 更新。IPFS访问还是太慢了，现本站已切换到 Hashnode(真香 ^-^)。 不过本文所述方法依然有效

[前文](https://chedan.io/build-site-with-hugo)提到我们用Hugo生成了一个静态网站， 并将它发布了IPFS之上。 本文将详细说明托管和发布过程。希望可以对你有些帮助。

## 什么是IPFS

引用官网的一句话：“A peer-to-peer hypermedia protocol, designed to make the web faster, safer, and more open.“

乍一看比较抽象，不过重申一下它的目标应该有助于理解这组协议。 它的目标是取代HTTP协议，构建分布式的、更好的Web。 它分别定义了在分布式Web环境中文件资源的存储、定位、传输等各个方面的协议， 使得分布式Web成为可能。

本文暂时不详细分析IPFS本身， 让我们先聚焦在主题之上： 如何在IPFS上发布静态网站。

## 文件托管

对于传统的静态网站，网站内容必须要上传到某个服务器之上。 默认情况下， 所有对此网站的访问请求都会落到这台服务器上。 当访问量大的时候， 这台服务器面临的运算和带宽压力都会很大。（虽然CDN等边缘计算技术会在某种程度上缓解此问题， 但并没有改变其中心化的本质）

与此相对， 在IPFS网络中一份内容可以有多个副本，可以自动分流不同地域的访客。 内容越流行副本就会越多。 这从根本上避免了“单点压力”。 不过对于非流行内容， 最初上传内容的节点可能成为全网唯一一个存有完整内容的节点。 如果此节点下线， 那么内容将无法访问。

基于以上原理，我们明白，简单地用 [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) 把内容上传到网络中并不能保证内容的随时可用。

我们需要一种服务，将内容放入其中之后，它可以保证内容一直在线， 供他人访问或复制。 这种服务并不需要承担所有访问流量， 但它需要承诺持续在线。 在IPFS世界中， 这种将文件“钉”在网络中的服务被称为"pin"。

虽然也可以自己搭建IPFS节点来完成上述任务，但对于个人网站这种简单场景， 更好的选择是使用现成的"pin"服务。

[Pinata](https://pinata.cloud/) 就是这样一个服务。 使用简便， 而且1G以下的存储容量是完全免费的。

注册Pinata之后， 访问 (https://pinata.cloud/pinataupload) 即可执行上传操作。 选择 “Upload Directory”后，可将Hugo生成的 `./public` 文件夹整体上传。

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285611461/df86410b-e105-487c-aab4-aa555ae9609d.png align="left")

上传成功以后将得到CID (即此文件夹在IPFS中的内容ID)。也可以在 (https://pinata.cloud/pinexplorer) 管理已上传的文件或文件夹

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285707381/76b5fbea-86f3-4deb-b28b-8882ff3a213a.png align="left")

这样，网站内容就算进入了IPFS网络，并且由Pinata保证在任意时刻都有至少一个在线复本可供访问和复制， 保证网站不下线。

## 访问网站

### 使用 IPFS Desktop 访问

上传成功以后， 就可以访问网站内容了。 最直接的方式是在 [IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) 中输入CID， 便可以直接看到文件夹的内容。

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285720033/7551f3ce-1bda-446f-890b-e33d9260a618.png align="left")

点击其中的HTML文件， 可以看到HTML源码。

### 通过公开IPFS Gateway 访问

对于一个网站来说，上述访问方式并不理想。我们希望在浏览器上访问网站内容，并且可以直接完成网页的渲染和呈现。 不过IPFS对此提供了一个优雅的解决办法： IPFS Gateway。IPFS Gateway 相当于传统web世界与IPFS世界的中介，通过它，用户可以用普通浏览器访问IPFS网络上的内容，只需知道文件的CID即可

目前网络上有很多正在运行的IPFS Gateway，可以在 [ipfs.io](https://ipfs.github.io/public-gateway-checker/) 查看公开的Gateway及其状态。除了IPFS官方维护的 Gateway， 目前最流行、最易用的是 [Cloudflare IPFS Gateway](https://cloudflare-ipfs.com/)。

### 结合DNSLink

IPFS Gateway 虽然在技术上完成了打通， 但还是不够理想。 我们希望网站跑在自己的域名之下。这需要用到另外一项与IPFS有关的技术：[DNSLink](https://docs.ipfs.io/guides/concepts/dnslink/)。 这项技术可以用DNS TXT记录把域名和IPFS 地址关联到一起。

我们知道IPFS中每一份内容都拥一个独立无二的CID，再结合DNSLink，IPFS内容与传统Web之间的桥梁就建立起来了。

在此， 我们以使用 Cloudflare IPFS Gateway为例说明如何配置DNS， 以便利用DNSLink技术让普通浏览器也可以访问网站内容。

要达成这个目标， 有两个步骤：

1. 修改dns，建立一个CNAME指向地址 `cloudflare-ipfs.com` 。以网站 `chedan.io` 为例，我将 `www.chedan.io` 设置为通过cloudflare 解析地址
    
2. 增加一条TXT类型的记录， `_dnslink.www` 指向地址为 `dnslink=/ipfs/{CID}`。 注意其中的`{CID}` 就是我们上传文件夹至IPFS时所得到的CID
    

完成这两步以后，DNS的配置如下图：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285739016/4ca42e8e-580e-4ceb-a9c3-1de9ff7d57ca.png align="left")

至此，个人网站就可以用常规浏览器来访问了: http://www.chedan.io

注：当网站内容发生改变时， 相关内容的CID已将发生变化。 这就需要更新相应的DNS记录。 不同的DNS服务商会提供不同API，虽然细节有差异但整体思路相同。本文不作展开说明

### 自动HTTPS保护

虽然可以访问， 但美中不足是此网站并没有HTTPS的保护。

说到这里就不得不赞一下Cloudflare, 它可以免费为它所服务的网站提供HTTPS保护。有了上述DNS配置以后， 生成和配置HTTPS证书都是自动的。 你需要作的只是访问 [Cloudflare IPFS Gateway](https://cloudflare-ipfs.com/)，在页面最底部文本框中输入想要保护的域名(在本例中即 `www.chedan.io`)， 等待最多90秒， 就会提示 "Certificate is live"。 这时再访问 https://www.chedan.io ， 会发现证书已经生效了

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285756740/c7b6e9a9-9f41-4a8e-ad81-a46d5e44b2a1.png align="left")

至此， 我们完成了将内容托管至IPFS， 并经由IPFS Gateway开放给传统浏览器的全部工作。

### 在浏览器中直接访问IPFS内容

虽然 IPFS Gateway 降低了普通用户访问IPFS难度，对推广分布式Web是有帮助的。 但是， 它经由集中Gateway中转的作法与分布式Web是目标是相违悖的。理想状况下， 我们希望浏览器可以原生支持IPFS协议， 使得用户可以浏览器直接访问IPFS网络，无需借助任何中心化的节点。

事实上很多人正在[这个方向](https://github.com/ipfs/in-web-browsers)作着努力， 在拥有浏览器原生支持之前， 我们可以先通过浏览器扩展来体验真正的分布式Web。 目前 [Firefox & Firefox Android](https://addons.mozilla.org/firefox/addon/ipfs-companion/) / [Chrome / Brave](https://chrome.google.com/webstore/detail/ipfs-companion/nibjojkomfdiaoajekhjakgkdhaomnch) 都已经有了IPFS扩展。他们拥有几个核心功能：

1. 识别IPFS地址，一旦发现是IPFS地址， 则重定向到本地gateway进行服务
    
2. 识别由 DNSLink 支持的URL， 自动完成重定向
    
3. 提供全局或站点级别的重定向开关，用于控制是否使用本地IPFS进行服务
    

其使用示例如下：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1716285777224/18ce4c38-c3a6-42e0-b16c-bce808212f30.gif align="left")

注：要正常使用这些扩展，需要先安装并在本地运行IPFS节点([IPFS Desktop](https://github.com/ipfs-shipyard/ipfs-desktop) 或 [IPFS 命令行工具](https://docs.ipfs.io/how-to/command-line-quick-start/#install-ipfs) 均可)。

安装扩展后再访问 https://www.chedan.io, 浏览器将自动重定向到 [http://www.chedan.io.ipns.localhost:8080](http://www.chedan.io.ipns.localhost:8080) ，并显示完全相同的内容。

虽然看起来没有差别，但其底层支撑结构已经完全不同。 此网址展现的内容是通过IPFS协议直接从IPFS网络中获取的， 绕过了集中化分布的节点， 真正实现了分布式Web。

随着IPFS和浏览器的发展，相信在不久的将来，浏览器将内置对IPFS的原生支持。

## 结论

IPFS 离我们并不遥远。 我们甚至现在就可以把自己的个人网站发布到IPFS之上。 通过 IPFS Gateway / DNSLink / IPFS Companion 等技术， 普通用户也可以方便地体验IPFS的独特魅力、感受分布式Web的乐趣。

## 参考

* [How to Easily Host a Website on IPFS](https://medium.com/pinata/how-to-easily-host-a-website-on-ipfs-9d842b5d6a01)
    
* [Cloudflare Distributed Web Developer Center](https://developers.cloudflare.com/distributed-web/)
    
* [IPFS Browser Update](https://blog.ipfs.io/2019-10-08-ipfs-browsers-update/)
