During the development phase of your new project in the ICON Ecosystem, depending on the requirements of your project and the tests you might need to run during development, it might be necessary to create your own testnet, some of the reasons for this might be:
- You need amounts of ICX bigger than the ones that can be obtained via the faucets in the current testnet.
- You need to have one or more main validators in the testnet for doing specific tasks like creating network proposals.
In these cases where using one of the existing testnet is not the best approach, you can setup your own custom testnet by running a multi-node local network on a server and configuring access to the server with a reverse proxy like nginx.
Prerequisites
To be able to run this project you need to first install the following programs:
dockeranddocker compose. Installation steps (opens in a new tab).nodejs. Installation steps (opens in a new tab).nginx. Installation steps (opens in a new tab).
Creating and decentralizing the network
The first thing we are going to do is organize our project. We are going to be working on a folder named custom-testnet located in the home folder.
cd ~
mkdir custom-testnet
cd ~/custom-testnetInside this folder we are going to clone two repositories:
- gochain-local (opens in a new tab): A repo with a set of scripts to create and run gochain docker containers as a local network.
- gochain-local-decentralize (opens in a new tab): A script to decentralize a local network created with the
gochain-localrepo.
We are going to start by cloning the gochain-local repo.
git clone https://github.com/icon-project/gochain-local.gitNow we clone the gochain-local-decentralize repo.
git clone https://github.com/icon-community/gochain-local-decentralize.gitAfter cloning the gochain-local-decentralize repo, go inside the folder and install the dependencies.
cd ~/custom-testnet/gochain-local-decentralize
npm installOur custom-testnet project folder should look like this right now:
$ tree -L 2
.
βββ gochain-local
βΒ Β βββ README.md
βΒ Β βββ compose-multi.yml
βΒ Β βββ compose-single.yml
βΒ Β βββ data
βΒ Β βββ run_gochain.sh
βΒ Β βββ tracker
βββ gochain-local-decentralize
βββ README.md
βββ index.js
βββ package-lock.json
βββ package.json
βββ src
βββ wallets
6 directories, 8 filesTo finish up the setting up process lets create a Makefile in our project root folder (~/custom-testnet):
touch ~/custom-testnet/MakefileAnd add the following content to that Makefile
info:
@echo "Run 'make start' or 'make stop' to run the docker commands"
start:
@sudo docker compose -f ./gochain-local/compose-multi.yml up -d
@(cd ./gochain-local-decentralize && node ./index.js)
stop:
@sudo docker compose -f ./gochain-local/compose-multi.yml down
reboot: start stopNow the custom-testnet is ready. To run the testnet we just need to move inside the ~/custom-testnet and run the command make start and to stop it run the command make stop.
Setting up access to the network
At this point you have a local multi node network already decentralized that you can access locally at http://localhost:9080 or from the outside of your server (previosly verifying that the 9080 port is open) with http://IP_ADDRESS:9080.
To improve this access point we can use nginx as a reverse proxy.
If you followed the prerequisites section you already have nginx installed, so the first thing to do is open the /etc/nginx/nginx.conf file, and edit it to have the following data:
events {}
http {
upstream local_cluster {
zone upstreams 64k;
server 127.0.0.1:9080 max_fails=1 fail_timeout=2s;
keepalive 2;
}
server {
listen 80;
# server_name www.example.com; # in the case you have a domain name
location /admin {
proxy_set_header Host $host;
proxy_pass http://local_cluster/admin;
proxy_next_upstream error timeout http_500;
}
location /api {
proxy_set_header Host $host;
proxy_pass http://local_cluster/api;
proxy_next_upstream error timeout http_500;
}
}
}Restart the nginx service by running:
sudo systemctl restart nginx.serviceYou can then run the following command to make sure that the nginx service is up and running correctly:
sudo systemctl status nginx.serviceAfter finishing the configuration process now you can access your node using the default http port (80) like so:
curl -X POST --data '{"jsonrpc": "2.0", "id": 1, "method": "icx_call", "params": {"to": "cx0000000000000000000000000000000000000000", "dataType": "call", "data": {"method": "getPReps", "params": {"startRanking": "0x1"}}}}' http://localhost:9080/api/v3