Decentralized Website

How to host a personal website on IPFS

Image courtesy of ipfs.io, CC BY 3.0

The website you are reading can be completely used without a running backend on a server. Such a website is known as static.

Static websites deliver all the content and logic (JavaScript) to the browser. All the interaction, such as search or clicking on internal links, is happening through the JS scripts included. While this sounds like a layman would expect it to, this is far from the current state of the internet.

In the early days, many websites only consisted of static HTML sites. Today, many modern websites rely on a running centralized backend server. This enables dynamic experiences but also leads to link rot, where specific websites (and their URLs) have a limited lifespan. Many people experienced the sight of dead links at least once and this problem is expected to grow with an ageing internet.

Content-Addressable Storage

A recent push to decentralize the internet again lead to technologies such as content-addressable storage.

Normal URLs on the internet such as https://lpfann.me/ are arbitrarily chosen words and have no relation to the actual content.

Content-addressing uses a mathematical hash function to compress the contents of a website into a short string called a hash. The great thing about hash functions is that they most likely produce a unique output and as such a unique address.

This allows use cases where people can serve and exchange content just based on a content hash. An example for an application of this is IPFS (Interplanetary Filesystem).

IPFS introduced an address scheme for content and also the exchange of information using peer to peer networking without a central server. People using the IPFS application automatically act as servers for other peers when they have information another node needs.

This enables a more robust and decentralized web without the need of a big central server or a content distribution network.

To host a website using IPFS we need it to be static.

Making a website static

This website is built using Hugo which already produces static output. It is only important to enable relativeURLs to work with the IPFS addressing.

We are also using the Academic theme for Hugo. Academic uses several external font and JavaScript resources to enhance the content presentation. While hosting a IPFS-website with references to non-IPFS resources is perfectly possible, it is not completely decentralized.

Luckily the Academic theme also provides a downloader tool, which saves all external assets inside the website folder.

At the time of writing the main downloader does not support all assets yet, but an open pull request added support for most of the missing things. Another thing missing were the fonts, which originally came from Googles Font CDN which we downloaded manually.

Now we have a complete website running on local fonts and JavaScript assets1. As such you could download the website files and kill the internet connection and you would have the same experience.

Hosting an IPFS website

If we would use IPFS to hash our website we would get a content hash like this:

/ipfs/QmSPZuY3K1XieH7M9zh4qs9MEGFf4GZdBv3STaiJpBaC6o

Now somebody else could retrieve the website using his own IPFS client directly or using one of the available browser plugins.

Draft of this blog post hashed and pinned to local IPFS node.
Draft of this blog post hashed and pinned to local IPFS node.

For somebody else to retrieve the files of the website we would have to keep a IPFS node running or ask somebody else to keep it cached (pinned).

There are so called pinning services (e.g. Pinata) which provide this service. Another project is Filecoin which is built on top of IPFS. It provides monetary incentive using a type of Blockchain to reward nodes to keep IPFS files pinned.

In the last few days we looked for ways to automatically pin this website when new content is added to the git repository. Just yesterday Textile announced dynamic buckets working on top of IPFS. While not the main focus of their blogpost, they also presented new GitHub Actions which automatically deploy content to their free bucket hosting. We extended their scripts on the demo site based on Gatsby to work with Hugo.
GitHub Action building and pushing files to Textile bucket
GitHub Action building and pushing files to Textile bucket
Now after every push and pull request, the GitHub Action compiles Hugo output and pushes it to a Textile bucket which is also pinned and works with IPFS.

Our website content is automatically available under a content hash after every change and push to the repository.

DNS

To let people know that a site is available with IPFS one can use DNSLinks. These are TXT records attached to DNS domains which hint at the IPFS resource available. IPFS browser extensions can detect these records and automatically use IPFS for content retrieval when coming to such a site.

The scripts from Textile also included an updater for DNS records which post the IPFS hash to Cloudflare DNS service. This script updates the DNSLink after every manual release.

Ethereum Name Service (ENS)

To have a completely decentralized solution one can use technologies like ENS which is an alternative to the DNS system.

Our website is also available under the ENS domain https://pfannschmidt.eth or via the transition link https://pfannschmidt.eth.link/ which uses the eth.link service to allow browsers without ENS support to visit the site.

For now, we update the IPFS hash stored in ENS manually, but we could automate this in the future.

Backwards Compatibility.

IPFS is still in its early stages. Most popular browsers do not support the protocol which is necessary to reach the majority of web users.

Until that changes one additionally needs to host websites the traditional way using web servers and DNS. One can use Cloudflares IPFS gateway and DNS solution to automatically serve IPFS content over normal HTTP.

For now this Blog is hosted by Netlify for non-IPFS enabled visitors.

Summary

Overall this process is still very much a complicated and hard thing. While IPFS and its ecosystem is steadily improving there is still a lot to do.

Luckily new services such as fleek Terminal.co are coming up which provide end to end decentralized hosting solutions.

Update

We now tried out fleek which makes it a lot easier to deploy a static site to IPFS. They automatically build your site from your GitHub repository, pin it on IPFS and also handle your DNSLinks such that people know you also provide a content hash.


  1. We have one2 external reference left which provides our visitor counting script. Missing it would not influence the usability negatively for the visitors. (You could argue it would improve the experience 😉) ↩︎

  2. After publishing this article we added a new commenting system. While it is self hosted, it is not decentralized. Apparently, that is still a non-trivial thing to do. ↩︎

Lukas Pfannschmidt
Lukas Pfannschmidt
Sr. Machine Learning Engineer

My expertise now encompasses advanced areas in machine learning and backend system optimization. My work in backend optimization, particularly in managing large-scale data efficiently, aligns with key optimization metrics like cost, quality, and speed. I also contribute to improving overall system reliability and observability, significantly reducing error rates and establishing critical technical metrics. These endeavors complement my previous research interests in high-performance computing.