Patrick D. Elliott

Decentralize your personal website

October 22, 2018 Tags: decentralization, tech, ipfs, dat

Like many academics and developers, my personal website is a static site1 hosted by GitHub pages, aliased to my personal domain. In fact, you can see the entire source for the site, including drafts for any posts I might happen to be working on here. As I started getting interested in the decentralized web2, I decided to experiment with publishing this site via contemporary peer-to-peer protocols - which means, of course, this site will persist regardless of what happens to GitHub’s central servers.

Dat and IPFS are two of the most prominent protocols at the heart of the decentralization movement, which aims to develop alternatives to huge cloud-based companies like google and facebook, and return power and control over information to the user by abandoning the traditional client/server archiecture. In a decentralized world, in principle there are only peers.

Dat and IPFS (which stands for Inter-Planetary File System) have relatively similar aims – they both provide a protocol and tooling for sharing content-addressable information between peers, with no single point of failure. Dat was originally developed as a means for scientists to share large datasets, but the ecosystem has however grown quite a bit beyond this initial remit – see, e.g., the Beaker Browser. IPFS on the other hand was pretty much always intended as a distributed alternative to the web, and there’s already an extension to integrate modern browsers with the IPFS protocol. There are of course other technologies on the scene, such as scuttlebutt (which I’ll probably write about some other time), and Tim Berners-Lee’s new solid platform, but for now dat and IPFS seem the most mature.

This post is a record of how I publish my homepage via IPFS at and dat at dat:// There wasn’t any real necessity to publish this site on the decentralized web - after all, the number of users who are going to visit this page via dat/ipfs is probably vanishingly small – but I thought it would be a fun experiment, and an opportunity to learn a little more about emerging peer-to-peer technologies, which I think are independently quite exciting.


First, I’ll talk through how I publish my site on the IPFS network to /ipns/ via DNSLink.

Running an IPFS node locally

Before doing anything else, I needed to install ipfs, initialize the repository, and start the ipfs daemon - you can follow the instructions here.4 After starting the ipfs daemon, you can check whether or not you’re connected to the network by running ipfs swarm peers, which should return the ipfs addresses of your peers.

Publishing on IPFS

First, you need to retrieve the peer ID of your locally running ipfs node, by running the following command:

peerid=$(ipfs id -f"<id>")

On my local machine, the source for my website can be found at ~GitHub/ I ran the following commands, which adds the website to IPFS and retrieves the hash of the directory root:

dirhash=$(ipfs add -r $(siteloc)/ | grep $(siteloc)$ | cut -d" " -f2)

Finally, we publish the directory to our node’s ipns entry by running the following command:

ipfs name publish $dirhash

It should now be possible to access the site via, e.g., a public gateway such as Even without running an IPFS node, you can access my site over the IPFS network by navigating to


Before talking about dat, a little background: what got me started with this whole endeavour was an (in hindsight, overly ambitious) attempt to migrate this site from GitHub pages to a personal web server, and publish to both and dat:// via homebase. I managed to get this working after jumping through quite a few hoops, but found that homebase wouldn’t reliably sync with my website’s dat repository, and the whole setup required too much manual intervention to be really worthwhile. I’ll take another look at homebase once it’s a bit more mature.

In the meantime, I decided that a much more manageable solution would be to continue to host my site at, while simultaneously syncing it with a dat repository pinned at - dat://

Installing dat

The first step is to install the dat cli tool, by following the instructions here.

Creating a dat repository

Next, we want to turn our published site into a dat repo. Ordinarily, this would be as simple as running dat init in relevant directory, but things are a bit more complicated with a static website - ordinarily, my site gets built into $HOME/GitHub/, but every time the site gets rebuilt, this entire directory gets wiped, including any metadata generated by dat. This would mean I’d effectively have to initialize a new dat repo with a new hash every time the site gets rebuilt, and we don’t want that.

Instead, I did the following: first, I built the site and copied it into $HOME/dat/ I then navigated to this directory and ran dat init to create the dat repository. Next, I went to and followed the instructions there to pin my dat repo to dat:// I then navigated to the local and run dat share --watch false to share the dat repo to the pinning service for the first time.

Whenever I want to update the dat repo and sync with hashbase, I run a script called deploy-dat, from my site’s git repo. This wipes everything from the local dat repo, except for the dat metadata, and copies in the newly built site, before syncing with the pinning service.

find ~/dat/ -mindepth 1 -maxdepth 1 \! \( -name .dat -o -name dat.json \) -exec rm -rf '{}' \;
cp -a ~/GitHub/ ~/dat/
cd ~/dat/
dat sync --watch false


homepage of the InterPlanetary Filesystem
the IPFS browser extension
use this to access the IPFS network via a modern browser.
Dat Project
homepage of the dat project
Beaker Browser
a browser for the decentralized web, supporting both dat and IPFS.
An alternative tool for publishing on the decentralized web, by the beaker devs.

  1. I build my site using the excellent haskell static-site generator hakyll.↩︎

  2. See also: distributed web, immutable web, permanent web, etc.↩︎

  3. You can substitute with any public IPFS gateway here, such as↩︎

  4. On the off-chance you happen to be another NixOS user, this is as simple as adding the following line to your configuration.nix!

    services.enable.ifps = true;