Publishing my website to IPFS

I have successfully mirrored my website on the Interplanetary File System (IPFS).

Assuming the Interplanetary Naming System continues to work, you should be able to access the site via https://ipfs.io/ipns/dgendill.com. As of this writing, I've added a DNS Record that links my domain name to the IPFS hash as "TXT dnslink=ipfs/QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs".

I've also pinned the website using https://pinata.cloud so my website should be available even when I'm not running my local IPFS node. In the future I plan to use the Pinata API to automatically pin content after I release an update.

Here are a couple notes about the process...

First, it's very important that all links and assets on the website use relative links. You can't assume that the content of the site will be on a particular domain name. Until the browser natively support IPFS, the website needs to assume all assets are relative. Internal links need to start with "./" or "../..". The same is true for JavaScript and CSS assets.


I followed this tutorial and this one for the publishing process.

To summarize that process, I installed IPFS on my computer and started the IPFS daemon.

ipfs daemon

I now had a IPFS node running on my computer. I was now ready to publish content to the network.

I use Hakyll as my website's static-site generator. All of my static assets are put in the "_site" folder after I ran the build script. So I ran the following command to add (and pin) the files to my local IPFS node.

ipfs add -r _site/

This will output a list of all the files uploaded to the network and their associated hash identifiers. The last item in the list is the hash of the root folder. In my case the site's root was "QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs". That is the "Content ID" of the current version of my website's homepage. So if I updated the homepage, this hash will change in the future.

(What follows I'm not sure I did correctly...)

If I want to access my IPFS website using the same identifier I need to the create a link to the latest version of my site. For that I can use IPNS. My understanding is that IPNS is sort of like DNS for the IPFS network. It lets you create an alias that points to any content you want. I ran the following command to publish the latest version of my website...

ipfs name publish QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs

This command took a minute or two to run. When it was done it said "Published to QmTCFwvw2mQ2mnP8EPks322z2gaCz1CoXvAW18hAuHKh2T: /ipfs/QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs"

In the message above, the Peer ID is "QmTCFwvw2mQ2mnP8EPks322z2gaCz1CoXvAW18hAuHKh2T" and the Content ID is "QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs". My PeerID will never change so I should always be able to access my website at /ipns/QmTCFwvw2mQ2mnP8EPks322z2gaCz1CoXvAW18hAuHKh2T (I've found this not to be true).

I added the Peer ID to a dnslink TXT record "dnslink=/ipns/QmTCFwvw2mQ2mnP8EPks322z2gaCz1CoXvAW18hAuHKh2T" on my domain. This will tell an IPFS enabled browser that the content on my domain can be accessed from the content pointed to by the IPNS ID QmTCFwvw2mQ2mnP8EPks322z2gaCz1CoXvAW18hAuHKh2T. If I wanted to, I could also point the dnslink record to the IPFS ID QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs by setting "dnslink=ipfs/QmXy8URB1JDosrtd9jNPxprjuuHAFF2dsRoNYSoUo35yqs" but that would mean my domain would always point to that particular version of my website. By pointing to the IPNS ID I'll be sure that I'm always serving the most recent content.

I should note I did not have long-term success using the IPNS address. That address would only work occasionally and after a day or two would not work. In the end I pointed the dnslink record to the IPFS address.

In the future when I need to change site content I can rerun the following commands...

ipfs add -r _site/
ipfs name publish <new site hash>