What is IPFS and how to set up your own node on a CentOS VPS

Published on Jan 19, 2022

To learn more about IPFS — aka the InterPlanetary File System — I set up a virtual host on Linode (love these guys, I use them in all my Linux classes). Nothing fancy here, just create your now VPS on your favourite platform and login as root. From there, we'll install IPFS and get to work.

I used snaps to quickly get up and running. Follow the instructions here to install the go-ipfs implementation of ipfs in just a couple of commands.

What is IPFS?

IPFS stands for InterPlanetary File System and it can be described as a decentralized system for storing, hosting and accessing files like images, video, websites and any other data you can think of. Instead of hosting your files with a central provider like Amazon or Google, think of hosting your files at many random locations not controlled by a single company. It's what the cool kids use to store NFT images these days without the risk of getting rug pulled. A rug pull is what happens when you buy and NFT with an image that is hosted on let's say google, after which the image is swapped out for something different like a rug :).

It works a bit like BitTorrent because IPFS can split your files into chuncks hosted on many different individual IPFS nodes (anyone can run an IPFS node) making it censorship proof and decentralized. Because the content is uniquely stored and based on a unique hash, there is no way for a scammer to change the contents of the image for example, without also having to change the hash. Let's see how that all works.

Getting started with IPFS

The first thing you'll want to do after installing IPFS is checking if you can access the CLI-tool. Make sure you switch to a normal (non-root) user account before interacting with IPFS. IPFS doesn't need root privileges to interact with so you can use a normal user account.

[goodbytes@ipfs-demo root]$ ipfs version
ipfs version 0.11.0

Before we can use IPFS the first time, we'll need to initialize the repository that will contain our internal data and settings. We can initialize IPFS easily with the ipfs init command, but because we are running this node in a data center, we'll use the server profile which will prevent IPFS from creating lots of internal traffic trying to discover other local nodes as stated in the docs.

[goodbytes@ipfs-demo root]$ ipfs init --profile server
generating ED25519 keypair...done
initializing IPFS node at /home/goodbytes/snap/ipfs/common
to get started, enter:

    ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme

When you run the ipfs cat command shown in the output it will show you the contents of the readme file for the given directory hash.

[goodbytes@ipfs-demo common]$ ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme
Hello and Welcome to IPFS!

██╗██████╗ ███████╗███████╗
██║██╔══██╗██╔════╝██╔════╝
██║██████╔╝█████╗  ███████╗
██║██╔═══╝ ██╔══╝  ╚════██║
██║██║     ██║     ███████║
╚═╝╚═╝     ╚═╝     ╚══════╝

If you're seeing this, you have successfully installed
IPFS and are now interfacing with the ipfs merkledag!

In order to add a simple text file to our IPFS node, do the following.

First, create a local text file containing any text you like.

[goodbytes@ipfs-demo ~]$ echo "Is this the future?" > future.txt

Add the file to your IPFS storage:

[goodbytes@ipfs-demo ~]$ ipfs add future.txt
added QmWkTeBtDCVj1jD8LeFAdUYGifTqDoSnTDwyJhfZ9NNKyu future.txt

Now that you added a file to your filesystem, you can verify this worked by reading the contents via ipfs cat.

[goodbytes@ipfs-demo root]$ ipfs cat QmWkTeBtDCVj1jD8LeFAdUYGifTqDoSnTDwyJhfZ9NNKyu
Is this the future?

Accessing your files via the browser

In order to be able to access your files via the browser or to let anyone else access your files, you'll need to run an IPFS daemon. Doing so will announce to the IPFS network that your node will be joining the swarm of nodes hosting the files you choose to host. 

Make sure you open up the required ports on your firewall or others won't be able to access your files via IPFS. You can see what ports are used in your config file over at ~/snap/ipfs/common/config.

Ports we definitely need are:

  • 4001: Communicate with other nodes (join the swarm)
  • 8080: Gateway server (allow browser access to your files)

In CentOS, open up these ports like so:

// run as root
firewall-cmd --zone=public --add-port=4001/tcp --permanent
firewall-cmd --zone=public --add-port=8080/tcp --permanent
systemctl reload firewalld
[root@ipfs-demo ~]# firewall-cmd --zone=public --permanent --list-ports
// 4001/tcp 8080/tcp

Now that these are running, kick off your IPFS daemon and see if we can access our files.

[goodbytes@ipfs-demo common]$ ipfs daemon
Initializing daemon...
...
Daemon is ready

Now you will be able to access your file by talking to any IPFS gateway. let's try that out by loading the hash from our file we added earlier. I'll be using the official IPFS gateway to access my text file by surfing to https://ipfs.io/ipfs/QmWkTeBtDCVj1jD8LeFAdUYGifTqDoSnTDwyJhfZ9NNKyu. Make sure you replace the hash with your own hash if you want to try this out.

As you can see in the screenshot below, we can you any other public IPFS gateway such as gateway.pinata.cloud/ipfs/ to access the same file. No matter what Gateway you are using, you will be redirected to our own node which has the file in storage.

Please also note that by the time you read this article, I may have removed my IPFS node and the file will not be available anymore. Typically, IPFS Gateways will cache a file for some time but they will delete them when they are not pinned. Pinning is locking the file and preventing it from ever being deleted from your IPFS-node.

Setting up your own IPFS Gateway

Right now you are able to use your daemon to request any kind of file but you will probably notice that you can't use your node as a Gateway yet. That is because our Gateway is currently listening on 127.0.0.1 only which of course is not publicly accessible. 

Edit you config in ~/snap/ipfs/common/config and look for the line containing your "Gateway" IP and port. Change the ip to 0.0.0.0 and restart your daemon.

[goodbytes@ipfs-demo ~]$ nano ~/snap/ipfs/common/config
// look for this line: 
// "Gateway": "/ip4/127.0.0.1/tcp/8080"
// change into: 
// "Gateway": "/ip4/0.0.0.0/tcp/8080"

When you restart your ipfs daemon command, you will see that one of your last lines in the output mentions that your Gateway is listening on 0.0.0.0 port 8080.

Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080

Now, instead of using any of the popular gateways, try using your own node by browsing to the following URL structure: http://ip:8080/ipfs/hash

You can even try it with one of the images I pinned on pinata.cloud, which is a popular IPFS hosting platform. Try this hash: QmNR3eQxMn1bcQDKCmmbjSGd4xcSk6dG1Q2sLcsoNSQLSh — it should display an NFT image I'm giving my students when they complete one of my blockchain classes or workshops as a fun souvenir.

Where to go from here

Now that I'm more familiar with how IPFS works and can be set up, I'm thinking of doing the following later on:

  • use SSH port forwarding to safely acces the IPFS WebUI dashboard to monitor your node's traffic
  • enable the API-capabilities of IPFS — which are built-in — in order to build an app on top of that that uploads and pins images
  • dive deeper into IPFS to allow other people to authenticate and use my node to upload files
  • learn more about how I can pin files on multiple nodes to keep them online forever
  • explore Filecoin which combines IPFS with crypto to create an incentive-based decentralized storage platform

I hope you learned a thing or two from this blog post, I sure did while writing it up.

If you are interested in learning more about web3 in general you may want to read my Ethernaut walkthroughs. They give you an understanding of security issues you'll encounter when writing Solidity smart contracts on Ethereum.

No comments? But that’s like a Gin & Tonic without the ice?

I’ve removed the comments but you can shoot me a message on LinkedIn to keep the conversation going.