Host a decentralised application with IPFS and AWS
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:
- Part 1: Create and deploy a Solidity contract to Avalanche with Hardhat
- Part 2: create an Avalanche dApp with Ethers, Metamask and React
- Part 4: Link a domain to a dApp hosted on IPFS
👉 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 pair
and 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-gcJan 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:
- Install IPFS: https://docs.ipfs.io/install/
- Pinning with IPFS: https://docs.ipfs.io/concepts/persistence/
- IPFS implementation in GO: https://github.com/ipfs/go-ipfs
- Host a website on IPFS: https://docs.ipfs.io/how-to/websites-on-ipfs/multipage-website
Join Coinmonks Telegram Channel and Youtube Channel learn about crypto trading and investing
Also, Read
- How to Swap Crypto on Uniswap? | A-Ads Review
- WazirX vs CoinDCX vs Bitbns | BlockFi vs CoinLoan vs Nexo
- LocalBitcoins Review | Cryptocurrency Savings Accounts
- What is Margin Trading | Dollar-Cost Averaging
- Uphold Card Review | Trust Wallet vs MetaMask
- Exness Review | MoonXBT Vs Bitget Vs Bingbon
- How to Start Earning Passive Income With Crypto Lending
- BigONE Exchange Review | Grid Trading Bot
- Anny Trade Review | CoinSpot Review
- 10 Best Crypto Exchange in Singapore | Buy AXS
- Best Crypto to Invest in India | WazirX P2P
- 7 Best Zero Fee Crypto Exchange Platforms
- Best Online Casinos | Futures Trading Bots
- Decentralized Exchanges | Bitbns FIP | Bingbon Review
- 10 Best Places to Buy Crypto with Credit Card