Deploying Eleventy to IPFS
Today saw an milestone achievement made with this blog! We completed our first automated deployment 😎. Naturally the only way to celebrate such an achievement is to share how it was done.
IPFS? #
IPFS is a p2p network, which acts as a distributed file system. It is developed by protocol labs. It is one of several products that form part of the decentralized web movement.
Hosting Content on IPFS #
The initial choice was to host an IPFS node. It's rather simple to bootstrap your own node, and publish to it. You can even do so on your local machine. There is a caveat if you take this approach; your content is only available when your local machine is online and connected to the network. Therefore I chose to set up an IPFS daemon, running on a low cost VPS. I installed the go-ipfs binary and set up as a systemd service[1] to keep it running.
The alternative is a third-party "pinning" service. There are a number available. They provide you with the IPFS hosting, and you upload your content using a web interface or API. I have now opted to switch from self-hosting to a service called Pinata. This means that you don't have to maintain an IPFS node, or pay a hosting bill to maintain it. If the site grows, you have to pay for storage.
Accessing IPFS Content #
IPFS is a file system. So how do our users gain access to the content that is being posted? In truth, I have no idea how people discover content published on IPFS alone. There is of course a search engine, but I wasn't able to find much of relevance on it at the time of writing.
Cloudflare IPFS gateway allows the site to operate from the domain root. This allows an IPFS deployed site to operate just like a regular website. The site only works on a top level domain, so it won't display properly on an IPFS HTTP gateway at present (try cloudflare-ipfs.com).
$ dig -t A alpha.oldr.uk
;; ANSWER SECTION:
alpha.oldr.uk. 68 IN CNAME cloudflare-ipfs.com.
cloudflare-ipfs.com. 300 IN A 104.18.253.167
cloudflare-ipfs.com. 300 IN A 104.18.254.167
cloudflare-ipfs.com. 300 IN A 104.18.255.167
cloudflare-ipfs.com. 300 IN A 104.18.64.168
cloudflare-ipfs.com. 300 IN A 104.18.252.167
IPFS supports a mutable linking system called IPNS (Interplanetary Naming Service). This allows you to create a "permanent" link to a resource which can be changed.
Deploying to IPFS #
As mentioned above, you can host on your own node or pin directly (or both).
Using a Node #
Deployment involves uploading to an IPFS node (or cluster). Using the command-line, you can deploy a directory and save it to IPNS using the following commands;
# Assuming your site is in a folder called "site" in the current working directory
$ ipfs add -r site
added Qmb4MR6U6Vxk28xDJVc1vxpsGAKpH7Rwt7HF9aaxG9vTzD site/index.htm
added QmWEpPCPzNJMMeGgvFb4sNx642ZoJowBwAtSr3sTeYeN3v site
22 B / 22 B [==============================================] 100.00%
Now it's possible to publish your pin to your IPFS node;
$ ipfs name publish QmWEpPCPzNJMMeGgvFb4sNx642ZoJowBwAtSr3sTeYeN3v
Published to QmdND4XcS6aYcTZxogeJMmVBxqDar4H1wh7AKwf2E1SYzn: /ipfs/QmWEpPCPzNJMMeGgvFb4sNx642ZoJowBwAtSr3sTeYeN3v
Which you can possibly view on the cloudflare gateway;
cloudflare-ipfs.com/ipns/QmdND4XcS6aYcTZxogeJMmVBxqDar4H1wh7AKwf2E1SYzn
Using a Pinning Service #
A popular tool for automated pinning is ipfs-deploy. It is a JavaScript zero-configuration tool, which will attempt to locate your site, pin it and update your DNS provider;
# Install ipfs globally
$ npm -g install ipfs-deploy
# then deploy your generated site
$ npx ipfs-deploy -p pinata site -d cloudflare
The documentation for the tool is pretty straight forward, but I plan on covering deployment in more detailed in a follow-up.
IPNS #
IPNS in turn supports a technology called DNSLink
. This feature allows you to create a DNS TXT
record linking to an IPFS URL, allowing IPNS to link a domain to a IPFS resource.
$ dig -t TXT _dnslink.alpha.oldr.uk
;; ANSWER SECTION:
_dnslink.alpha.oldr.uk. 120 IN TXT "dnslink=/ipfs/QmZ6R943z1QhNaeLrAM4QjftDRLgsyNBQwSGZe32AQfHYC"
Allows you to access a resource through an IPFS gateway like this;
cloudflare-ipfs.com/ipns/alpha.oldr.uk
Which you can try here. It may or may not load, depending on how distributed the current hash is in the network.
Why I won't be using IPFS yet #
Initial loading of the site after deployment is too slow in my opinion. This is due to the need to distribute and cache through the network. Sadly the HTTP gateway doesn't serve old content, so as soon as the dnslink record is updated the site can be inaccessible for a while afterward. The above is not a huge problem if you are using /ipfs
links directly.
You may also want to provide a mutable IPNS pointer to keep a consistent URL between deployments. This is currently slow to the point of being unusable. With DNSLink, you can either point to an immutable IPFS hash or a mutable IPNS hash.
I'm considering a second deployment target. This could allow the site to work both on IPFS gateway services and classical hosting.
Please don't use root, set up a dedicated service user] ↩︎