Dapp development with a local subgraph + Ganache setup
Local subgraph development for time savings and sanity
If you’re looking at adding a subgraph for your Dapp through the The Graph or have already done so but your development cycle involves deploying to a running test network in order to test your contracts and or subgraph changes, then you may want to consider running the stack locally.
Running a Truffle, Ganache & subgraph stack locally should speed up Dapp development as the results of your Dapp changes surface quicker. With faster deploy times, blocks being mined instantly, you should see faster data flow into your Dapp’s subgraph and by extension either its API or front-end.
There are a number of steps involved in setting up this local stack which we will walk through with you as well as some thoughts on how the process could be improved. The steps below follow the official Graph docs which can be found here.
The are 3 pre-requisites for this tutorial which is for you to have a local Ganache Ethereum blockchain, Docker installed and a subgraph project already initialised for your dapp.
There are 2 options when it comes to Ganache, an app with a nice UI and a CLI app which we can run from the terminal / command prompt. For the purposes of this tutorial, we’ll use the CLI. If you wish to use the app, just ensure that it’s configured with the same params as the CLI.
First order of business, install the CLI globally if you haven’t already:
npm install -g ganache-cli
Docker installation instructions: https://docs.docker.com/get-docker/
Creating a subgraph project: https://thegraph.com/docs/define-a-subgraph#create-a-subgraph-project
Step 1: Ganache and Required Parameters
ganache-cli installed, we can spin up a local chain with the following command:
ganache-cli -h 0.0.0.0
This should be all you need to get this stack going. By default, the host is normally
127.0.0.1 but by overriding this to
0.0.0.0 we bind the service to all interfaces which means that our local graph node, which runs in a docker container, will be able to talk to our local blockchain.
Due to regularly developing with
ganache-cli , I run the CLI with more options as follows:
ganache-cli -h 0.0.0.0 -m "MNEMONIC_HERE" -i 5777
The 2 extra options involve passing a mnemonic and chain ID respectively. This allows me to import the private keys of any account once into metamask and the chain ID allows me to have a static configuration for my local chain within metamask — the CLI tends to generate a new chain ID every time otherwise.
You’ll know if the CLI is running when the following is one of the last message printed to the console:
Listening on 0.0.0.0:8545
With that confirmed, you now need to migrate / deploy your contracts onto the local chain with the appropriate
truffle migrate command.
Step 2: Running a local Graph node
This bit can be a bit temperamental so bare with it — you may need a few attempts before getting this going.
The aim is to bring up a Graph node using a docker-compose file. The required docker-compose file can be found here.
If you’re a linux user (ignore the fact that macOS is UNIX-based if you’re a Mac user), you’ll need to run the additional
setup.sh script for the graph node to work properly.
The compose file will spin up 3 containers in total, one for the node, another for an IPFS node and a final Postgres container. Postgres is the persistence layer for your graph node and when spinning up this container, it will generate a
data/ directory. Data stored includes information about the blockchain i.e. block height etc. which is used to determine whether an event log has been parsed for example.
A common “Gotcha” — If you were to restart your local blockchain, your node’s DB would then become out of sync with the current state of your chain and you therefore would need to tear down your DB and start again.
The reason I’m boring you with all this information is to stop you from experiencing pain when you don’t understand why one day your local stack worked and then another, it didn’t. Fortunately, we developed a simple script to make spinning up a local node easy:
If you saved this script in the same directory as the docker-compose file and gave it execution privileges, you’ll find an easy, repeatable way of spinning up a graph node after starting a fresh blockchain.
Now, time to run the above script to kick things off!
All going well, the 3 containers should spin up happy (you may need to give it a minute or two to fully spin up). If everything is running correctly you should see the following being printed out repeatedly from your
This means that your Graph node is polling your chain for all the information it needs to operate. If this is not happening, check if something went wrong in spinning up the graph node by looking at the docker logs of the container being printed to the terminal. Alternatively, re-visit the above steps to see where you may have gone wrong.
Step 3: Deploying to your local Graph Node
If you’ve deployed a Rinkeby or mainnet subgraph, you’ll know that before deploying, you need to create a project through the dashboard. Locally, you still need to create a project to deploy to and the way in which you do it is via the following command:
Provided your Graph node is running and configured correctly, a project should have been created. This is a one-time only operation for every project, every time you start a local Graph node.
From here, you can simply deploy to the node. Again, there are local scripts you need to call rather than the ones you may be used to. For example:
yarn build && yarn deploy-local
Will build and locally deploy your subgraph to your local subgraph. A few things to note for the node to correctly work:
- The network for all of your contracts defined in your
subgraph.ymlfile must be
mainneteven though you are deploying to a local node. This will not interact with the main Ethereum network — it’s just the way that
subgraph.ymlneeds to be configured for your local node. I learnt the hard way…
- You will probably already have pre-empted this, but all of your contract addresses in the
subgraph.ymlfile need to match the deployment addresses from the migrations you ran against your local blockchain.
Those are the main gotchas that can throw you off.
Provided all went well, you should be told that deployment was successful and be given a http endpoint to allow you to query for entities. This will of course rely on data being on chain etc. which you can achieve by either running in further migrations making state changes or make state changes to your dapp via some snazzy UX you designed for a front-end (configuring metamask as described above)
By running a the full Ganache + subgraph stack locally, we open up the ability to iterate much faster thanks to faster local deploys, instant block confirmations etc. However, you can see (and have experienced) that there are a few pain points involved in getting the stack working. We made an attempt at improving the node start up sequence with our bash script, but there are still a number of hoops to jump through to get going. You could automate further by having a script that will spin up a local blockchain, migrate your contracts to that chain, start a graph node etc. and it is something we may consider to help our local development. However, there’s no getting away from the fact that the out of the box solution has it’s quirks and it’s a case of weighing up the time taken to set up the local stack vs maybe deploying to Rinkeby instead. Whatever your thoughts on this are, in general we love the Graph here at BlockRocket and have had more and more clients integrate this into their stack. It’ll be interesting to see how the Dapp stack continues to develop from this point onwards.
If you want to speak to us directly about how to leverage this and other Web 3 tools, please reach out to us using the links below.
Website — www.blockrocket.tech
Email — firstname.lastname@example.org
Twitter — @blockrockettech
Check out our community meetup for our up and coming events — Blockchain Manchester
If you enjoyed this post please show it some ❤️ and give it a clap of 50 👏👏👏 — Vincent