The Decentralized Web: Develop and Publish a Website
In the last part, we will get our hands dirty and play with IPFS to publish a website. If you want to dig deeper into IPFS later, please have a look at the official documentation hosted on IPFS.
You can use IPFS Desktop and the IPFS Daemon with the same data, but not run them at the same time. You need to stop the one to use the other. But you can use the IPFS commands to interact with a running IPFS Desktop service.
Installation
To install IPFS Desktop, you download the binary for your operating system (Mac, Windows, or Linux/FreeBSD).
If you want to use Brave, you can navigate to the browser settings and activate in the IPFS section the IPFS Companion. You can click on the My Node button to open the Web UI. You can change the IPFS Node type in the settings of the companion to use the external node from the IPFS Desktop installation. I haven’t figured out yet if it’s possible to use the command-line tool to access the native Brave IPFS node.
To follow along with the tutorial, we use the command-line tool. You can install IPFS via Homebrew on a Mac:
$ brew install ipfs
For other options, like the M1 install, please look at the installation instructions.
IPFS Web UI
If you installed IPFS Desktop, you’ll see the Web UI inside a window which can be accessed through the app itself. You can open it through the My Node button of the companion extension, or by using the URL shown to you when you start the command-line daemon.
The interface has navigation with multiple items: Status, Files, Explore, Peers, and Settings.
Status is a monitor of incoming and outgoing traffic of your IPFS node. Files show all your hosted and pinned files and folders. Explore is an advanced tool to explore hashes. Peers shows a world map with nearby peers. Settings allows configuring language, public gateway, API address, and other things. The CLI-Tutor-Mode is a useful thing for beginners. It shows next to each command in the graphical interface the accompanied terminal command.
Initializing the Repository
If you didn’t install the IPFS Desktop, you’ll need to initialize the IPFS repository before the first start:
$ ipfs init
Exploring Files
You can explore objects in your repository with the ipfs cat
command, for example:
$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
Or contents of folders with the ipfs ls
command:
$ ipfs ls /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/
Start the Node
To run the node on the command line, you have to start the daemon:
$ ipfs daemon
If the IPFS Desktop app is running, you’ll get an error that tells you, another process is already using the repository:
Error: lock /Users/username/.ipfs/repo.lock: someone else has the lock
Add your First File
Create your first file and add it to the repository:
$ echo "Hello World" > hello-world.txt
$ ipfs add hello-world.txt
With the same ipfs cat
command from above, but using the hash of the hello-world.txt
file, you can see its contents.
Create a Simple Webpage
We will create now a simple webpage:
$ cd ~
$ mkdir simple-webpage
$ cd simple-webpage
We download an image of a cute cat from IPFS:
$ ipfs cat QmW2WQi7j6c7UgJTarActp7tDNikE4B2qXtFCfLPdsgaTQ/cat.jpg > cat.jpg
Create a new file named index.html
inside the folder and paste this basic HTML inside:
<!doctype html>
<html>
<head>
<title>Nice Kitty</title>
</head>
<body>
<center>
<h1>Nice Kitty</h1>
<img src="cat.jpg" />
</center>
</body>
</html>
We’ll now add this folder and all its content (-r
for recursively) to IPFS:
$ cd ..
$ ipfs add -r simple-webpage/
You’ll see an output like this, but with different hashes:
added Qmd286K6pohQcTKYqnS1YhWrCiS4gz7Xi34sdwMe9USZ7u simple-webpage/cat.jpg
added QmY3ayxXcXMs7qdDvPy7QKcVQ492JBNyC9Zf3jp1LrQRCA simple-webpage/index.html
added QmNa1YdawLNeD2fumihKGxuna4GqAws2QsvRsMjzpY2mM2 simple-webpage
433.02 KiB / 433.02 KiB [==========================================] 100.00%
You can see your website now by opening the following URL in Brave:
https://ipfs.io/ipfs/<website-hash>
It should work in other browsers because this URL is using a gateway, but it might be slow or take a while until the file is available.
In Brave, you’ll see a button in your URL bar to open it directly in IPFS (without a gateway). This will change the bar to show an IPFS icon and the IPFS address.
Publishing to IPNS
Each time you change something with your website, you’ll get new hashes for the changed files and folders affected, which makes it hard to always serve your recent version to the world. This is where IPNS (the InterPlanetary Name System) comes into play. You create an IPNS hash that is tied to your Peer ID.
We publish now our website to IPNS:
$ ipfs name publish <website-hash>
You’ll get an output like this:
Published to <your-peer-id>: /ipfs/<website-hash>
This peer ID is now available by accessing it in your browser:
https://ipfs.io/ipns/<your-peer-id>
In Brave, you can directly access it with the ipns://
protocol (it might take a few seconds, until it’s available):
ipfs://<your-peer-id>
You can check where the IPNS is pointing by using this command:
$ ipfs name resolve <your-peer-id>
If you change your website, add it again to the IPFS repository, and publish it again, you’ll see the updated content at that address.
Use a New IPNS Name Key Pair
To publish multiple projects at fixed URLs, you’ll need to generate a new key pair:
$ ipfs key gen <some-name>
You can see your keys with this command:
$ ipfs key list
self
<some-name>
You can publish to a different IPNS name by adding another key pair to the publish command:
$ ipfs name publish --key=<some-name> <website-hash>
MFS – Mutable File System
If you open the IPFS Web UI and navigate to the Files section, you might wonder why it’s empty.
The reason is that files in IPFS are content-addressed and immutable. You can’t overwrite them, create a new version. The hashes in your repository get additionally cleaned up automatically (unless they are pinned) when the cache is full, or you run the cleaning task (garbage collection) manually:
$ ipfs repo gc
If you add a file with ipfs add
it will automatically be pinned.
MFS helps to make working with files more comfortable. We can now copy our website to the MFS:
$ ipfs files cp /ipfs/<website-hash> /simple-website
This will create a new folder at the root of the Mutable File System and copy the contents of the website to it. If you reload the Files section of the IPFS Web UI, you’ll see the folder, see its contents, and hashes. You would use MFS for projects you plan to keep track of and have them stay around longer.
You can use a row of UNIX-like commands to create a folder, write files, and copy and move files on MFS. Furthermore, you can find all commands starting with ipfs files
in the Command-line reference. This command would create a new file inside a folder:
echo "Hello, World" | ipfs files write --create --parents /my-new-folder/hello-world.txt
Pinning
If you share content on a decentralized, distributed network, it will be available, if at least one node serves it. If you’re the only node on the network and turn off your computer, the data won’t be accessible.
Pinning services solve this problem for you, they allow pinning CID’s to keep them online. I tried Pinata because they offer 1 GB of storage for free.
Hosting IPFS Content With a Domain
There are plenty of different options to serve content with a human-readable name. You could register an ENS name, and connect it to your latest CID, buy a domain at Unstoppable Domains, or use a service like Fleek, to name a few options.
I use Fleek because I just wanted to play around with IPFS, and they offer free hosting. I connected the GitHub repository of my website with Fleek and automatically deploy my website on each push to IPFS. Not only that, but I deploy it currently to a subdomain by adding a CNAME record in my DNS settings, but have bought an Unstoppable Domain.
Conclusion
I’m happy with how the decentralized internet is progressing and even though it feels bumpy and like the early days of the internet. A lot of tinkering, and trying out new ideas and technologies, but it is this feeling that makes me hopeful that we witness the beginning of something new.
I hope we will be able to bring back the control of the internet to the masses and give control of data to the individual.
We need to stop malicious and greedy big tech oligarchs and authoritarian politicians from infringing on our rights to life, liberty, and the pursuit of happiness.