Host a decentralised application with IPFS and AWS

Alexander Lechner
Coinmonks
8 min readJan 17, 2022

--

A quick step-by-step guide on how to host a dApp (on Avalanche) with IPFS and AWS EC2

This article is part 3 of a series on how to build a dApp on Avalanche. Check out the other parts here:

👉 TLDR: this article explains how to run an IPFS node yourself. If you don’t want to do that but still want to host your files in a decentralised way, you can alternatively use a pinning service like Pinata, Eternum or Fleek.

Used software versions:

  • nodejs: v16.13.0
  • go-ipfs: v0.11.0
  • ubuntu server: 20.04 LTS

Step 1: create and launch an AWS EC2 instance

Log into the AWS management console and click on Services > Compute > EC2. There click on Launch instances.

To keep things simple we’re going to use an Ubuntu AMI. In the search bar search for Ubuntu and select the most recent version. If you’re planning to use the free tier provided by AWS (free for the first year), pay attention that the AMI contains the tag Free tier eligible:

On the next page you can select the instance type, this defines the resources available for your service. Again we’re choosing what’s available with the free tier and select t2.micro.

Now jump over a couple of steps (we’ll use the default values) and click on Configure Security Group. There we’ll open up ports 8080 and 4001–4002:

Next press Review and Launch. This will skip a couple of steps (configuration, storage etc.) but we’re going to stick to the defaults anyway.

Then click onLaunch. This opens dialog to create a key new pair. Select create a new key pairand download the file, we’ll need the key pair file in the next step to connect to our instance via SSH. Then click onLaunch Instances.

Step 2: connect to your instance

Let’s now connect to the created instance. Once the instance launched, we have different options.

Option 1: connect from the AWS console. For this, all we need to do is to click on the instance id and press Connect.

Option 2: connect via SSH from your machine. For this we first need to give the right permissions to the key pair we downloaded in the previous step:

$ chmod 400 ipfs-key-pair.cer

Now you can connect via SSH using the Public DNS (IPv4) shown on the dashboard:

$ ssh -i ipfs-key-pair.cer ubuntu@ec2-x-x-x-x.xx-xxxx-x.compute.amazonaws.com

Step 3: install IPFS

We are now connected to our EC2 instance and are ready to install IPFS. Let’s get the latest version of go-ipfs from the distribution site:

$ wget https://dist.ipfs.io/go-ipfs/v0.11.0/go-ipfs_v0.11.0_linux-amd64.tar.gz
$ tar xvfz go-ipfs_v0.11.0_linux-amd64.tar.gz
$ rm go-ipfs_v0.11.0_linux-amd64.tar.gz

Now let’s install it:

$ sudo ./go-ipfs/install.sh
Moved ./go-ipfs/ipfs to /usr/local/bin

You can check that the installation was successful by running:

$ ipfs version
ipfs version 0.11.0

You can find a more detailed installation guide for different platforms in the official IPFS documentation.

Step 4: initialise the IPFS repository

Let’s now setup the folder for the IPFS repo. In this tutorial we’re going to use /home/ubuntu/ipfs/data but you can use whatever path you want.

So first we create the folder:

$ mkdir /home/ubuntu/ipfs/data

Then we add the path to your bash profile and reload it:

$ echo 'export IPFS_PATH=/home/ubuntu/ipfs/data' >> ~/.profile
$ source ~/.profile

Now let’s initialise the IPFS repository:

$ ipfs init --profile server
generating ED25519 keypair...done
peer identity: 12D3KooWQC89gZAV45WbL4ecTofnacJkq6ptQfEFWzcBsu71ED8F
initializing IPFS node at /home/ubuntu/ipfs/data
to get started, enter:
ipfs cat /ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc/readme2022-01-14T10:23:19.179Z ERROR provider.queue queue/queue.go:124 Failed to enqueue cid: leveldb: closed

If you get the error log at the end don’t worry. According to this thread it doesn’t have any effect on the installation.

Background: we’re running the initialisation with the server profile, so IPFS doesn’t try to discover local nodes (which would result in a lot of internal traffic).

Finally we’ll update the IPFS configuration to restrict the storage used (per default our instance only has 8GB available in total). We’ll also open the gateway on port 8080 to make it possible to access and view our files.

$ ipfs config Datastore.StorageMax 2GB
$ ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080

Step 5: setup IPFS daemon

We want IPFS to start automatically whenever our EC2 instance starts up. To do this up we need to use the systemctl service.

Let’s create the file /lib/systemd/system/ipfs.service:

$ sudo nano /lib/systemd/system/ipfs.service

Now we’re going to add this startup configuration to the file:

[Unit]
Description=ipfs daemon
[Service]
ExecStart=/usr/local/bin/ipfs daemon --enable-gc
Restart=always
User=ubuntu
Group=ubuntu
Environment="IPFS_PATH=/home/ubuntu/ipfs/data"
[Install]
WantedBy=multi-user.target

Save the file and restart the systemctl daemon so it finds new service:

$ sudo systemctl daemon-reload
$ sudo systemctl enable ipfs.service

Now we can start the service and check the health:

$ sudo systemctl start ipfs
$ sudo systemctl status ipfs

You should now see the IPFS status similar to this:

● ipfs.service - ipfs daemon
Loaded: loaded (/lib/systemd/system/ipfs.service; enabled; vendor preset: enabled)
Active: active (running) since Fri 2022-01-14 11:26:20 UTC; 3s ago
Main PID: 17712 (ipfs)
Tasks: 7 (limit: 1147)
Memory: 50.4M
CGroup: /system.slice/ipfs.service
└─17712 /usr/local/bin/ipfs daemon --enable-gc
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm listening on /p2p-circuit
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm announcing /ip4/127.0.0.1/tcp/4001
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm announcing /ip4/127.0.0.1/udp/4001/quic
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm announcing /ip4/18.192.213.16/tcp/4001
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm announcing /ip6/::1/tcp/4001
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Swarm announcing /ip6/::1/udp/4001/quic
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: API server listening on /ip4/127.0.0.1/tcp/5001
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: WebUI: http://127.0.0.1:5001/webui
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Gateway (readonly) server listening on /ip4/0.0.0.0/tcp/8080
Jan 14 11:26:21 ip-172-31-19-228 ipfs[17712]: Daemon is ready

Now we can try to fetch an IPFS document using the public DNS of your service. Open this link in your browser:

http://ec2-xx-xxx-xxx-xx.xx-xxxx-x.compute.amazonaws.com:8080/ipfs/QmQPeNsJPyVWPFDVHb77w8G42Fvo15z4bG2X8D2GhfbSXc

You should see a document like this:

If you get an exception instead, double check that you opened up port 8080 for TCP traffic on your instance and that you enabled the IPFS gateway (in the command line type ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080 and sudo systemctl restart ipfs).

Step 6: build dApp

If you have your own dApp simply build your app and skip this step.

If you didn’t already, check out Tutorial 1 and Tutorial 2 of this series, which explains how to create a dApp from scratch. If you’re not interested, you can alternatively just check out the final code from this repo https://github.com/lechneal/solidity-hello-world-dapp on your local machine:

$ git clone https://github.com/lechneal/solidity-hello-world-dapp my-awesome-contract

In order to load all resources correctly when hosted on IPFS, we want the generated files to use relative paths. To do that we’ll add the line "homepage": "./", to the file my-awesome-contract/frontend/package.json:

{
"name": "frontend",
"version": "0.1.0",
"homepage": "./",
...
}

Then let’s build the app with:

$ cd my-awesome-contract/frontend
$ npm install
$ npm run build

This will generate all files in the folder my-awesome-contract/frontend/build/. This is the folder we want to host with IPFS.

Step 7: upload files

To upload our files we’ll use scp. Run the following command on your local machine, but adjust the path to your keypair, the path to your build files and the host address of your EC2 instance:

$ scp -i path/to/your/keypair/ipfs-key-pair.cer -r ./build ubuntu@ec2-xx-xxx-xxx-xx.xx-xxxx-x.compute.amazonaws.com:/home/ubuntu/dapp

This will upload all build files to your EC2 instance into the folder /home/ubuntu/dapp.

Step 8: add and pin files with IPFS

Again connect to your EC2 instance either via the AWS management console or via SSH. Once connected you should be able to see the uploaded build files:

$ ls /home/ubuntu/dapp
asset-manifest.json favicon.ico index.html logo192.png logo512.png manifest.json robots.txt static

Let’s now add the whole folder to IPFS:

$ ipfs add -r /home/ubuntu/dapp
added Qmer3X6Y5xtWvZ5qxRZcjJtexwdkApgexwp3StY5hE6abk dapp/asset-manifest.json
added QmcFc6EPhavNSfdjG8byaxxV6KtHZvnDwYXLHvyJQPp3uN dapp/favicon.ico
added QmeAXYf4ehZkXFWnofgtLsh8wx2jUcD51Eg8Ak4dkdbhJ2 dapp/index.html
...
added QmSbWfAidZ4Aqg48K3WjfFiSRKg1RDTQR9Jd6kKRLPSnQU dapp/static/css
added QmYuQ7ZmCM9ZrznKB9SeJSQCjU6SncVBWXi9MM5pFSixcu dapp/static/js
added QmSQZCa31phWCpwGdWTSE2zJLxuWnZVdqawp1mYQ2jwZcA dapp/static
added QmYupNAG5sb6nhgYp5LFzDAW9Tn9kHRQwbLrbKBbbDneAp dapp

You can see the whole folder was added to IPFS. All files are pinned automatically (so they won’t be deleted during the next garbage collection).

🍾🍾🍾 That’s it 🍾🍾🍾
You should now be able to load the whole dApp by using the hash of your dApp folder (last line of the command line output):

added QmYupNAG5sb6nhgYp5LFzDAW9Tn9kHRQwbLrbKBbbDneAp dapp

You can access your dApp from your IPFS gateway by opening this link in your browser:

http://ec2-xx-xxx-xxx-xx.xx-xxxx-x.compute.amazonaws.com:8080/ipfs/QmYupNAG5sb6nhgYp5LFzDAW9Tn9kHRQwbLrbKBbbDneAp

Or you can access your dApp through the ipfs.io gateway using this link (though this might take substantially longer):

https://ipfs.io/ipfs/QmYupNAG5sb6nhgYp5LFzDAW9Tn9kHRQwbLrbKBbbDneAp

The End

That’s all for this tutorial, you successfully hosted a dApp on your own IPFS node. In an upcoming tutorial we’ll investigate how to connect your dApp with a distributed domain name.

Resources & Links:

Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing

Also, Read

--

--