Getting started with Cardano GraphQL
Cardano GraphQL
As its name suggests the Cardano GraphQL project adds support for the GraphQL query language to the Cardano ecosystem.
Services
The Cardano GraphQL project includes the following services:
- PostgreSQL
- Cardano Node Ogmios
- Cardano DB Sync Extended
- Hasura
- Cardano GraphQL
Getting Started
The project includes an example docker-compose.yml. However, before you start it is important that you understand the interdependencies between each of the project's services.
For example, you need to sync the Cardano Node with the blockchain before you use Cardano DB Sync Extended to restore a snapshot (see: Cardano DB Sync rolling back to genesis).
docker-compose-cardano-node.yml:
version: "3.8"
services:
cardano-node-ogmios:
image: cardanosolutions/cardano-node-ogmios:${CARDANO_NODE_OGMIOS_VERSION:-v5.1.0}-${NETWORK:-mainnet}
restart: on-failure
container_name: cardano-node-ogmios
ports:
- ${OGMIOS_PORT:-1337}:1337
volumes:
- node-db:/db
- node-ipc:/ipc
logging:
driver: "json-file"
options:
max-size: "400k"
max-file: "20"
volumes:
node-db:
node-ipc:
Pull and run Cardano Node Ogmios:
export NETWORK=mainnet && \
docker-compose -f docker-compose-cardano-node.yml up -d
After 24 hours or so you can bring down the service:
docker-compose down
Tip: Cardano Node does not need to be at the tip of the blockchain it just needs to be past the last block in the snapshot (e.g., db-sync-snapshot-schema-12-block-6451499-x86_64.tgz) you want to restore. So keep an eye on the logs:
docker container logs -f --tail 10 cardano-node-ogmios
Now you are ready to pull and run all the Cardano GraphQL services and restore a snapshot:
export NETWORK=mainnet && \
export RESTORE_SNAPSHOT=/snapshots/db-sync-snapshot-schema-12-block-6451499-x86_64.tgz && \
docker-compose up -d
docker-compose.yml:
version: "3.8"
services:
postgres:
image: postgres:${POSTGRES_VERSION:-11.5-alpine}
restart: on-failure
container_name: postgres
environment:
- POSTGRES_LOGGING=true
- POSTGRES_DB_FILE=/run/secrets/postgres_db
- POSTGRES_PASSWORD_FILE=/run/secrets/postgres_password
- POSTGRES_USER_FILE=/run/secrets/postgres_user
ports:
- ${POSTGRES_PORT:-5432}:5432
secrets:
- postgres_db
- postgres_password
- postgres_user
shm_size: '2gb'
volumes:
- postgres-data:/var/lib/postgresql/data
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
cardano-node-ogmios:
image: cardanosolutions/cardano-node-ogmios:${CARDANO_NODE_OGMIOS_VERSION:-v5.1.0}-${NETWORK:-mainnet}
restart: on-failure
container_name: cardano-node-ogmios
ports:
- ${OGMIOS_PORT:-1337}:1337
volumes:
- node-db:/db
- node-ipc:/ipc
logging:
driver: "json-file"
options:
max-size: "400k"
max-file: "20"
cardano-db-sync-extended:
working_dir: /var/lib/cdbsync
image: inputoutput/cardano-db-sync:${CARDANO_DB_SYNC_VERSION:-12.0.0}
command: [
"--config", "/config/cardano-db-sync/config.json",
"--socket-path", "/node-ipc/node.socket"
]
restart: on-failure
container_name: cardano-db-sync-extended
environment:
- EXTENDED=true
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- RESTORE_SNAPSHOT=${RESTORE_SNAPSHOT:-}
- RESTORE_RECREATE_DB=N
secrets:
- postgres_password
- postgres_user
- postgres_db
volumes:
- ./config/network/${NETWORK:-mainnet}:/config
- db-sync-data:/var/lib/cdbsync
- db-sync-tmp:/tmp
- node-ipc:/node-ipc
- ./snapshots:/snapshots
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
depends_on:
- cardano-node-ogmios
- postgres
hasura:
image: inputoutput/cardano-graphql-hasura:${CARDANO_GRAPHQL_VERSION:-6.2.0}
restart: on-failure
container_name: hasura
ports:
- ${HASURA_PORT:-8090}:8080
environment:
- HASURA_GRAPHQL_ENABLE_CONSOLE=true
- HASURA_GRAPHQL_CORS_DOMAIN=http://localhost:9695
secrets:
- postgres_db
- postgres_password
- postgres_user
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
depends_on:
- postgres
cardano-graphql:
build:
context: ./services/cardano-graphql
dockerfile: Dockerfile
restart: on-failure
container_name: cardano-graphql
environment:
- SLEEP=${SLEEP:-3600}
- ALLOW_INTROSPECTION=true
- CACHE_ENABLED=true
- LOGGER_MIN_SEVERITY=${LOGGER_MIN_SEVERITY:-info}
- PROMETHEUS_METRICS=true
- TRACING=true
expose:
- ${API_PORT:-3100}
ports:
- ${API_PORT:-3100}:3100
secrets:
- postgres_db
- postgres_password
- postgres_user
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
depends_on:
- postgres
prometheus:
image: prom/prometheus:latest
command:
- '--config.file=/etc/prometheus/prometheus.yml'
- '--web.enable-lifecycle'
container_name: prometheus
ports:
- ${PROMETHEUS_PORT:-9090}:9090
volumes:
- ./prometheus:/etc/prometheus
- prometheus-data:/var/lib/prometheus/data
depends_on:
- cardano-graphql
grafana:
image: grafana/grafana-oss:latest
container_name: grafana
ports:
- ${GRAFANA_PORT:-3000}:3000
volumes:
- ./grafana/provisioning:/etc/grafana/provisioning
depends_on:
- prometheus
secrets:
postgres_db:
file: ./placeholder-secrets/postgres_db
postgres_password:
file: ./placeholder-secrets/postgres_password
postgres_user:
file: ./placeholder-secrets/postgres_user
volumes:
db-sync-data:
db-sync-tmp:
node-db:
node-ipc:
postgres-data:
prometheus-data:
Navigate to the GraphQL Playground: http://localhost:3100/graphql
Query the epoch dataset:
{ cardanoDbMeta { initialized syncPercentage }}
Wait for initialized to be true to ensure the epoch dataset is complete.
Query the full dataset:
{ cardano { tip { number slotNo epoch { number } } } }
Cardano GraphQL
I added an ENTRYPOINT to the cardano-graphql build so that it would wait (it might need to sleep for a hour or more depending on the size of the snapshot) for the snapshot to be restored before it tries to add any new (Hasura) views to PostgreSQL.
docker-entrypoint.sh
#!/bin/sh
# Abort on any error
set -e
sleep "$SLEEP"
# Run the main container command
exec "$@"
Dockerfile
FROM inputoutput/cardano-graphql:6.2.0-mainnet
COPY docker-entrypoint.sh docker-entrypoint.sh
RUN chmod +x ./docker-entrypoint.sh
ENTRYPOINT ["./docker-entrypoint.sh"]
CMD ["node", "index.js"]
Docker Desktop for Mac
When I first tried to restore a snapshot I paid close attention to the logs:
docker container logs -f --tail 10 cardano-db-sync-extended
I encountered the following issue:
psql:/tmp/db-sync-snapshot-hc6bN9lE7U/db-sync-snapshot-schema-12-block-6451499-x86_64.sql:238416086: ERROR: could not extend file "base/16384/214298": No space left on device
HINT: Check free disk space.
psql:/tmp/db-sync-snapshot-hc6bN9lE7U/db-sync-snapshot-schema-12-block-6451499-x86_64.sql:238416150: ERROR: could not write block 35045 of temporary file: No space left on device
CONTEXT: parallel worker
To address this issue I had to remove all containers, networks, images and volumes:
docker system prune --all
Remove the Docker.raw (see: ERROR: No space left on device) file:
sudo rm /Users/<user>/Library/Containers/com.docker.docker/Data/vms/0/data/Docker.raw
And increase the default Disk image size:
References:
- Cardano GraphQL GitHub Issues: Can't perform query while syncing
- Cardano DB Sync GitHub Issues: db-sync makes a rollback after using RESTORE_SNAPSHOT
- Cardano DB Sync GitHub Issues: cardano-db-sync rolling back to genesis
- Cardano Ouroboros Network GitHub Issues: Introduce a blocking version of MsgFindIntersection for a specific blockNo