Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
mmahut committed Jan 6, 2024
0 parents commit 40644b8
Show file tree
Hide file tree
Showing 16 changed files with 1,093 additions and 0 deletions.
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NETWORK=preprod
Binary file added .github/assets/demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.env
docker-compose.yml
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "cardano-configurations"]
path = cardano-configurations
url = https://github.com/input-output-hk/cardano-configurations
674 changes: 674 additions & 0 deletions LICENSE

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Blockfrost bootstrap

Blockfrost bootstrap is a toolkit that helps you to deploy a Blockfrost cluster in minutes.

<p align="center">
<a href="#key-features">Key Features</a> •
<a href="#Installation">Installation</a> •
<a href="#usage">How To Use</a> •
<a href="#contributing">Contributing</a>
</p>

## Key Features

A ready to go Blockfrost instance.

- Cardano Node
- Cardano Db Sync with Postgres database
- Cardano Submit API
- Ogmios
- Sprinkle some Blockfrost Backend on top of it

## Installation

The bootstrap cluster is supposed to be a development tool and we do not recommend using it as a production deployment. It's at your
own risk.

You need to have `docker` and `docker-compose` installed on your system. We recommend at least 64GB of memory.

```bash
# Clone this repository
$ git clone --recurse-submodules https://github.com/blockfrost/blockfrost-bootstrap

# Go into the repository
$ cd blockfrost-bootstrap

# Run the bootstrap script
$ ./blockfrost-bootstrap
Usage: ./blockfrost-bootstrap {init|start|stop|status|height|destroy}

init Initialize an blockfrost bootstrap cluster
start Start the cluster
stop Stop the cluster
status Get status of an initialized cluster
height Get current height of the cluster
destroy Destroy the current cluster
```

## Usage

### Initializing your cluster

![Blockfrost bootstrap](.github/assets/demo.gif)

### Starting and stopping your cluster

Use the `start` and `stop` commands.

```
$ ./blockfrost-bootstrap stop
Stopping blockfrost-bootstrap_cardano-submit-api_1 ... done
Stopping blockfrost-bootstrap_postgres_1 ... done
Stopping blockfrost-bootstrap_blockfrost-backend-ryo_1 ... done
Stopping blockfrost-bootstrap_cardano-db-sync_1 ... done
Stopping blockfrost-bootstrap_ogmios_1 ... done
Stopping blockfrost-bootstrap_cardano-node_1 ... done
$
```

### Status of the cluster

You can view the current status of your cluster using the `status` command.

```
$ ./blockfrost-bootstrap status
NAMES CONTAINER ID STATUS PORTS
blockfrost-bootstrap_cardano-submit-api_1 d07dd8b5aada Up 34 seconds (healthy) 0.0.0.0:8090->8090/tcp, :::8090->8090/tcp
blockfrost-bootstrap_postgres_1 ee48c946b6b7 Up 34 seconds (healthy) 0.0.0.0:5432->5432/tcp, :::5432->5432/tcp
blockfrost-bootstrap_blockfrost-backend-ryo_1 76294d3e2861 Up 34 seconds (health: starting) 0.0.0.0:3000->3000/tcp, :::3000->3000/tcp
blockfrost-bootstrap_cardano-db-sync_1 cadae3918431 Up 34 seconds
blockfrost-bootstrap_ogmios_1 cb625defb5c1 Up 34 seconds (healthy) 0.0.0.0:1337->1337/tcp, :::1337->1337/tcp
blockfrost-bootstrap_cardano-node_1 c9682a6a1510 Up 35 seconds (healthy)
$
```

## Contributing

Contributions do this repository are welcome. If you would like to contribute, please open a pull request to this repository and someone will review
it as soon as possible.
182 changes: 182 additions & 0 deletions blockfrost-bootstrap
Original file line number Diff line number Diff line change
@@ -0,0 +1,182 @@
#!/usr/bin/env bash

if ! command -v docker &> /dev/null
then
echo "ERROR: docker could not be found, please install it."
echo "Visit https://docs.docker.com/get-docker/ for more information."
exit 1
fi

if ! command -v docker-compose &> /dev/null
then
echo "ERROR: docker-compose could not be found, please install it."
echo "Visit https://docs.docker.com/compose/install/ for more information."
exit 1
fi

init () {
if [ -f ./docker-compose.yml ]; then
echo "ERROR: ☝ Your cluster is already initialized."
echo "Run \"$0 status\" or \"$0 destroy\"."
echo
exit 1
fi

clear
echo -e "\e[1m"
echo " Welcome to Blockfrost bootstrap!"
echo -e "\e[0m"
echo "We're going to initialize a new Blockfrost Bootstrap cluster for you."
echo
echo "🯄 But first - which network are you looking for?"
select network in "mainnet" "preview" "preprod"; do
case $network in
mainnet ) export NETWORK=mainnet;break;;
preview ) export NETWORK=preview;break;;
preprod ) export NETWORK=preprod;break;;
esac
done
echo "NETWORK=$NETWORK" > .env
echo
echo "The blockfrost cluster consists of the Cardano blockchain node, the Cardano DB Sync,"
echo "PostgreSQL database and the Blockfrost backend, but there are"
echo "other components that you might find useful. Please refer to the documentation"
echo -e "available at \e[33mhttp://github.com/blockfrost/blockfrost-bootstrap\e[39m to find out more about"
echo "each of these components."
echo
echo "🯄 Do you wish to initialize the Cardano Submit API?"
select yn1 in "Yes" "No"; do
case $yn1 in
Yes ) export INIT_SUBMIT_API=true;break;;
No ) export INIT_SUBMIT_API=false;break;;
* ) echo "Invalid choice.";
esac
done
echo
echo "🯄 Do you wish to initialize Ogmios?"
select yn2 in "Yes" "No"; do
case $yn2 in
Yes ) export INIT_OGMIOS=true;break;;
No ) export INIT_OGMIOS=false;break;;
* ) echo "Invalid choice.";
esac
done
cat compose/common.yml compose/cardano-db-sync.yml compose/blockfrost-backend-ryo.yml > docker-compose.yml
if $INIT_SUBMIT_API; then cat compose/cardano-submit-api.yml >> docker-compose.yml; fi;
if $INIT_OGMIOS; then cat compose/ogmios.yml >> docker-compose.yml; fi;
echo >> docker-compose.yml
echo "# Generated on $(date) by blockfrost-bootstrap" >> docker-compose.yml
echo

echo "Congratulations! Your cluster has been initialized. Pick up"
echo "a good book, brew some coffee, this might take some time."
echo
echo "Press Enter to Continue."
read -n 1
docker-compose up -d --remove-orphans
echo
echo
echo "All is done now. It might take some time to sync. Execute $0 height to see the progress."
}

start () {
docker-compose start
}

stop () {
docker-compose stop
}

status () {
DOCKER_COMPOSE_PS=$(docker ps -a --format 'table {{.Names}}\t{{.ID}}\t{{.Status}}\t{{.Ports}}');
echo "$DOCKER_COMPOSE_PS" | grep -E 'blockfrost|NAME'
echo

}

height () {
source .env && declare -A net_map; net_map=( ["mainnet"]="--mainnet" ["preview"]="--testnet-magic 2" ["preprod"]="--testnet-magic 1" ); export MAGIC=${net_map[${NETWORK:-mainnet}]}
NODE_HEIGHT=$(docker exec -t $(docker ps --format '{{.Names}}' | grep blockfrost | grep 'cardano-node' | head -n 1) /bin/cardano-cli query tip $MAGIC | jq -r .block)
DBSYNC_HEIGHT=$(docker exec $(docker ps --format '{{.Names}}' | grep blockfrost | grep 'postgres' | head -n 1) psql -qtA -U postgres cexplorer -c 'select block_no from block order by id desc limit 1;')
BLOCKFROST_HEIGHT=$(curl -s localhost:3000/blocks/latest | jq -r .height)
echo -e "\e[1mCurrent blockchain heights\e[0m"
echo
echo "Cardano node: $NODE_HEIGHT"
echo "Cardano DB Sync: $DBSYNC_HEIGHT"
echo "Blockfrost backend: $BLOCKFROST_HEIGHT"
echo
[ $(($NODE_HEIGHT > $DBSYNC_HEIGHT ? $NODE_HEIGHT - $DBSYNC_HEIGHT : $DBSYNC_HEIGHT - $NODE_HEIGHT)) -ge 10 -o $(($NODE_HEIGHT > $BLOCKFROST_HEIGHT ? $NODE_HEIGHT - $BLOCKFROST_HEIGHT : $BLOCKFROST_HEIGHT - $NODE_HEIGHT)) -ge 10 -o $(($DBSYNC_HEIGHT > $BLOCKFROST_HEIGHT ? $DBSYNC_HEIGHT - $BLOCKFROST_HEIGHT : $BLOCKFROST_HEIGHT - $DBSYNC_HEIGHT)) -ge 10 ] && echo -e "\e[31mYour cluster is out of sync, by more than 10 blocks.\e[0m" || echo -e "\e[32mYour cluster appears in sync.\e[0m"
}

destroy () {

if [ ! -f ./docker-compose.yml ]; then
echo "Could not find an existing configuration."
echo "Run \"$0 init\" to create a new cluster."
echo
exit 1
fi
echo "Here be dragons!"
echo
echo "Do you REALLY want to DESTROY your current cluster?"
select yn1 in "Yes" "No"; do
case $yn1 in
Yes ) break;;
No ) exit;;
* ) echo "Invalid choice.";
esac
done
echo
docker-compose rm -s
rm docker-compose.yml
echo
DANGLING_VOLUMES=$(docker volume ls --format '{{.Name}}'|grep blockfrost)
echo
echo "The following volumes have been left after the cluster:"
echo
echo "$DANGLING_VOLUMES"
echo
echo "Do you REALLY want to DESTROY your current cluster volumes? You will lose all data."
select yn1 in "Yes" "No"; do
case $yn1 in
Yes ) break;;
No ) exit;;
* ) echo "Invalid choice.";
esac
done
echo
echo "$DANGLING_VOLUMES" | xargs -r docker volume rm
echo "All gone."
}

case "$1" in
init)
init
;;

start)
start
;;
stop)
stop
;;
status)
status
;;
height)
height
;;
destroy)
destroy
;;
*)
echo "Usage: $0 {init|start|stop|status|height|destroy}"
echo
echo " init Initialize an blockfrost bootstrap cluster"
echo " start Start the cluster"
echo " stop Stop the cluster"
echo " status Get status of an initialized cluster"
echo " height Get current height of the cluster"
echo " destroy Destroy the current cluster"
exit 1
esac
1 change: 1 addition & 0 deletions cardano-configurations
Submodule cardano-configurations added at 21249e
26 changes: 26 additions & 0 deletions compose/blockfrost-backend-ryo.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
blockfrost-backend-ryo:
image: blockfrost/backend-ryo:${BLOCKFROST_BACKEND_VERSION:-latest}
environment:
- BLOCKFROST_CONFIG_NETWORK=${NETWORK:-mainnet}
- BLOCKFROST_CONFIG_SERVER_LISTEN_ADDRESS=0.0.0.0
- BLOCKFROST_CONFIG_SERVER_PORT=${BLOCKFROST_CONFIG_SERVER_PORT:-3000}
- BLOCKFROST_CONFIG_SERVER_DEBUG=${BLOCKFROST_CONFIG_SERVER_DEBUG:-true}
- BLOCKFROST_CONFIG_DBSYNC_HOST=postgres
- BLOCKFROST_CONFIG_DBSYNC_USER=postgres
- BLOCKFROST_CONFIG_DBSYNC_DATABASE=cexplorer
- BLOCKFROST_CONFIG_DBSYNC_PASSWORD=REGENERATEME
- BLOCKFROST_CONFIG_TOKEN_REGISTRY_URL=https://tokens.cardano.org
logging:
driver: "json-file"
restart: on-failure
healthcheck:
test: ["CMD-SHELL", "curl -f 0.0.0.0:3000/blocks/latest || exit 1"]
interval: 10s
timeout: 5s
retries: 5
ports:
- ${BLOCKFROST_CONFIG_SERVER_PORT:-3000}:${BLOCKFROST_CONFIG_SERVER_PORT:-3000}
secrets:
- postgres_password
- postgres_user
- postgres_db
45 changes: 45 additions & 0 deletions compose/cardano-db-sync.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
postgres:
image: postgres:14-alpine
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
secrets:
- postgres_password
- postgres_user
- postgres_db
ports:
- ${POSTGRES_PORT:-5432}:5432
volumes:
- blockfrost-postgres:/var/lib/postgresql/data
restart: on-failure
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
command: ${POSTGRES_ARGS:--c maintenance_work_mem=1GB -c max_parallel_maintenance_workers=4}
logging:
driver: "json-file"

cardano-db-sync:
image: inputoutput/cardano-db-sync:${CARDANO_DB_SYNC_VERSION:-latest}
environment:
- DISABLE_LEDGER=${DISABLE_LEDGER}
- NETWORK=${NETWORK:-mainnet}
- POSTGRES_HOST=postgres
- POSTGRES_PORT=5432
- RESTORE_SNAPSHOT=${RESTORE_SNAPSHOT:-}
- RESTORE_RECREATE_DB=N
- EXTRA_DB_SYNC_ARGS=${EXTRA_DB_SYNC_ARGS:-}
secrets:
- postgres_password
- postgres_user
- postgres_db
volumes:
- cardano-db-sync-data:/var/lib/cexplorer
- cardano-node-ipc:/node-ipc
restart: on-failure
logging:
driver: "json-file"
18 changes: 18 additions & 0 deletions compose/cardano-submit-api.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cardano-submit-api:
image: inputoutput/cardano-submit-api:${CARDANO_SUBMIT_API_VERSION:-latest}
environment:
- NETWORK=${NETWORK:-mainnet}
depends_on:
- cardano-node
volumes:
- cardano-node-ipc:/node-ipc
ports:
- 8090:8090
restart: on-failure
logging:
driver: "json-file"
healthcheck:
test: ["CMD-SHELL", "true &>/dev/null </dev/tcp/127.0.0.1/8090"]
interval: 10s
timeout: 10s
retries: 5
Loading

0 comments on commit 40644b8

Please sign in to comment.