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.


To be able to run this project you need to first install the following programs:

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-testnet

Inside this folder we are going to clone two repositories:

We are going to start by cloning the gochain-local repo.

git clone https://github.com/icon-project/gochain-local.git

Now we clone the gochain-local-decentralize repo.

git clone https://github.com/icon-community/gochain-local-decentralize.git

After cloning the gochain-local-decentralize repo, go inside the folder and install the dependencies.

cd ~/custom-testnet/gochain-local-decentralize
npm install

Our 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 files

To finish up the setting up process lets create a Makefile in our project root folder (~/custom-testnet):

touch ~/custom-testnet/Makefile

And add the following content to that Makefile

    @echo "Run 'make start' or 'make stop' to run the docker commands"
    @sudo docker compose -f ./gochain-local/compose-multi.yml up -d
    @(cd ./gochain-local-decentralize && node ./index.js)
    @sudo docker compose -f ./gochain-local/compose-multi.yml down
reboot: start stop

Now 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 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.service

You can then run the following command to make sure that the nginx service is up and running correctly:

sudo systemctl status nginx.service

After 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

Further Resources