From 9cbfe96d44e924f326bb3b5fec3c9a6ced21cb43 Mon Sep 17 00:00:00 2001 From: Vivek Teega Date: Tue, 2 Jul 2024 15:17:58 +0530 Subject: [PATCH] Structure set in place for Docker compose based deployment --- .env.example | 10 +++++ .gitignore | 1 + Dockerfile | 16 ++++---- README.md | 15 ++++++- docker-compose.yml | 45 +++++++++++++++++++++ entrypoint.sh | 98 +++++++++++++++++++++++++++++++++++++++++++++- instructions | 18 +++++++++ 7 files changed, 193 insertions(+), 10 deletions(-) create mode 100644 .env.example create mode 100644 .gitignore create mode 100644 docker-compose.yml create mode 100644 instructions diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..fa07bfb --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +BACKEND_IMAGE=vivekteega/blockbook:1.0.0 +FRONTEND_IMAGE=vivekteega/blockbook:1.0.0 +BACKEND_CONTAINER_NAME=blockbook-backend +FRONTEND_CONTAINER_NAME=blockbook-frontend +BACKEND_BOOTSTRAP_FILE=/path/to/your/bootstrap-blockbook-flo-mainnet-backend.tar.gz +FRONTEND_BOOTSTRAP_FILE=/path/to/your/bootstrap-blockbook-flo-mainnet-frontend.tar.gz +BACKEND_PORT_1=38366 +BACKEND_PORT_2=8066 +FRONTEND_PORT_1=9166 +FRONTEND_PORT_2=9066 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2eea525 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env \ No newline at end of file diff --git a/Dockerfile b/Dockerfile index f398b95..fdcae7c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,15 +2,17 @@ FROM ubuntu:22.04 # Backend COPY ./deb-files/backend-flo_0.15.1.1-satoshilabs-1_amd64.deb /opt/backend.deb - -RUN apt update && apt install -y /opt/backend.deb -WORKDIR /opt/coins/nodes/flo -RUN sed -i 's/daemon=1/daemon=0/' /opt/coins/nodes/flo/flo.conf - -# Frontend COPY ./deb-files/blockbook-flo_0.4.0_amd64.deb /opt/blockbook.deb -RUN apt update && apt install -y /opt/blockbook.deb +RUN apt update && apt install -y /opt/backend.deb /opt/blockbook.deb curl && \ + sed -i 's/daemon=1/daemon=0/' /opt/coins/nodes/flo/flo.conf && \ + sed -i '/rpcport=8066/a rpcallowip=0.0.0.0/0' /opt/coins/nodes/flo/flo.conf && \ + echo "addnode=ramanujam.ranchimall.net" >> /opt/coins/nodes/flo/flo.conf && \ + echo "addnode=turing.ranchimall.net" >> /opt/coins/nodes/flo/flo.conf && \ + echo "addnode=stevejobs.ranchimall.net" >> /opt/coins/nodes/flo/flo.conf && \ + echo "addnode=brahmagupta.ranchimall.net" >> /opt/coins/nodes/flo/flo.conf && \ + echo "addnode=feynman.ranchimall.net" >> /opt/coins/nodes/flo/flo.conf + WORKDIR /opt/coins/blockbook/flo # Execution diff --git a/README.md b/README.md index 6fb20cb..66a261f 100644 --- a/README.md +++ b/README.md @@ -8,10 +8,16 @@ - [ ] Figure out if multiple volume path need to be mounted - [ ] See if creating a new network for both the containers will be a good option. +## Quickstart +To run the services using this file, run the following command in the same directory: + +``` +sudo docker-compose up -d +``` + ## Building and running blockbook image ``` -docker build -f Dockerfile -t vivekteega/blockbook:1.0.0 . docker volume create blockbook @@ -23,12 +29,19 @@ docker run -it --name blockbook-backend --mount source=blockbook,target=/opt -p # Run backend in daemon mode for production docker run -d --name blockbook-backend --mount source=blockbook,target=/opt -p 38366:38366 -p 8066:8066 --network=blockbook vivekteega/blockbook:1.0.0 backend +# Run backend in daemon mode for production with Bootstrap +docker run -d --name blockbook-backend --mount source=blockbook,target=/opt -p 38366:38366 -p 8066:8066 --network=blockbook --env BOOTSTRAP_URL=https://bootstrap.ranchimall.net/blockbook-flo-backend1.tar.gz vivekteega/blockbook:1.0.0 backend + # Run frontend in "it" mode for testing docker run -it --name blockbook-frontend --mount source=blockbook,target=/opt -p 9166:9166 -p 9066:9066 --network=blockbook vivekteega/blockbook:1.0.0 frontend 172.20.0.2 # Run frontend in daemon mode for production docker run -d --name blockbook-frontend --mount source=blockbook,target=/opt -p 9166:9166 -p 9066:9066 --network=blockbook vivekteega/blockbook:1.0.0 frontend 172.20.0.2 + +# Bootstrap +docker run -d --name blockbook-frontend --mount source=blockbook,target=/opt -p 9166:9166 -p 9066:9066 --network=blockbook --env BOOTSTRAP_URL=https://bootstrap.ranchimall.net/blockbook-flo-frontend.tar.gz vivekteega/blockbook:1.0.0 frontend 172.20.0.2 + ``` ## Building & running backend image diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..da16422 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,45 @@ +version: '3.8' + +services: + blockbook-backend: + image: ${BACKEND_IMAGE} + container_name: ${BACKEND_CONTAINER_NAME} + networks: + - blockbook + volumes: + - blockbook:/opt + - ${BACKEND_BOOTSTRAP_FILE:-/dev/null}:/local-bootstrap/bootstrap-blockbook-flo-mainnet-backend.tar.gz # Use /dev/null if no file + ports: + - "${BACKEND_PORT_1}:38366" + - "${BACKEND_PORT_2}:8066" + command: backend + environment: + - BOOTSTRAP_FILE=/local-bootstrap/bootstrap-blockbook-flo-mainnet-backend.tar.gz + - BOOTSTRAP_URL=${BOOTSTRAP_URL:-} # Set to empty string if not provided + + blockbook-frontend: + image: ${FRONTEND_IMAGE} + container_name: ${FRONTEND_CONTAINER_NAME} + networks: + - blockbook + volumes: + - blockbook:/opt + - ${FRONTEND_BOOTSTRAP_FILE:-/dev/null}:/local-bootstrap/bootstrap-blockbook-flo-mainnet-frontend.tar.gz # Use /dev/null if no file + ports: + - "${FRONTEND_PORT_1}:9166" + - "${FRONTEND_PORT_2}:9066" + depends_on: + - blockbook-backend + entrypoint: /bin/sh -c + command: > + "/opt/entrypoint.sh frontend $(getent hosts blockbook-backend | awk '{ print $1 }')" + environment: + - BOOTSTRAP_FILE=/local-bootstrap/bootstrap-blockbook-flo-mainnet-frontend.tar.gz + - BOOTSTRAP_URL=${BOOTSTRAP_URL:-} # Set to empty string if not provided + +volumes: + blockbook: + +networks: + blockbook: + driver: bridge diff --git a/entrypoint.sh b/entrypoint.sh index fdbaf6b..c5b4fb9 100644 --- a/entrypoint.sh +++ b/entrypoint.sh @@ -1,17 +1,97 @@ #!/bin/sh set -e +# Paths for frontend bootstrap files +FRONTEND_BOOTSTRAP_URL_FILE="/opt/coins/data/flo/blockbook/bootstrap-url.txt" +FRONTEND_BOOTSTRAP_FILE_HASH_FILE="/opt/coins/data/flo/blockbook/bootstrap-file-hash.txt" + +# Paths for backend bootstrap files +BACKEND_BOOTSTRAP_URL_FILE="/opt/coins/data/flo/backend/bootstrap-url.txt" +BACKEND_BOOTSTRAP_FILE_HASH_FILE="/opt/coins/data/flo/backend/bootstrap-file-hash.txt" + +# Function to calculate the hash of a file +calculate_file_hash() { + local file=$1 + sha256sum "$file" | awk '{print $1}' +} + # Function to update config file update_config_file() { local config_path=$1 local new_ip=$2 if [ -n "$new_ip" ]; then echo "Updating config file: $config_path with IP: $new_ip" - # Replace IP address in the config file - sed -i "s/127.0.0.1/$new_ip/g" "$config_path" + if ! sed -i "s/127.0.0.1/$new_ip/g" "$config_path"; then + echo "Failed to update config file: $config_path" + exit 1 + fi fi } +# Function to handle bootstrap from URL +handle_bootstrap_url() { + local bootstrap_url=$1 + local destination_dir=$2 + local url_file=$3 + local bootstrap_file=$4 + + if [ -z "$bootstrap_url" ]; then + echo "No bootstrap URL provided, skipping download." + return + fi + + if [ -f "$url_file" ]; then + local existing_url + existing_url=$(cat "$url_file") + if [ "$existing_url" = "$bootstrap_url" ]; then + echo "Bootstrap URL already processed, skipping download and extraction." + return + fi + fi + + echo "Downloading bootstrap file from: $bootstrap_url" + curl -L -o "/tmp/$bootstrap_file" "$bootstrap_url" + echo "Cleaning and extracting bootstrap file to: $destination_dir" + mkdir -p "$destination_dir" + rm -rf "$destination_dir"/* + tar -xzvf "/tmp/$bootstrap_file" -C "$destination_dir" + rm "/tmp/$bootstrap_file" + + echo "$bootstrap_url" > "$url_file" +} + +# Function to handle bootstrap from file +handle_bootstrap_file() { + local bootstrap_file=$1 + local destination_dir=$2 + local hash_file=$3 + + if [ -z "$bootstrap_file" ] || [ ! -f "$bootstrap_file" ]; then + echo "No valid bootstrap file provided, skipping extraction." + return + fi + + local new_hash + new_hash=$(calculate_file_hash "$bootstrap_file") + + if [ -f "$hash_file" ]; then + local existing_hash + existing_hash=$(cat "$hash_file") + if [ "$existing_hash" = "$new_hash" ]; then + echo "Bootstrap file already processed, skipping extraction." + return + fi + fi + + echo "Using bootstrap file: $bootstrap_file" + echo "Cleaning and extracting bootstrap file to: $destination_dir" + mkdir -p "$destination_dir" + rm -rf "$destination_dir"/* + tar -xzf "$bootstrap_file" -C "$destination_dir" + + echo "$new_hash" > "$hash_file" +} + case "$1" in "frontend") if [ -z "$2" ]; then @@ -20,12 +100,26 @@ case "$1" in fi new_ip=$2 echo "Running frontend command with IP: $new_ip" + + if [ -n "$BOOTSTRAP_FILE" ] && [ -f "$BOOTSTRAP_FILE" ]; then + handle_bootstrap_file "$BOOTSTRAP_FILE" "/opt/coins/data/flo/blockbook" "$FRONTEND_BOOTSTRAP_FILE_HASH_FILE" + elif [ -n "$BOOTSTRAP_URL" ]; then + handle_bootstrap_url "$BOOTSTRAP_URL" "/opt/coins/data/flo/blockbook" "$FRONTEND_BOOTSTRAP_URL_FILE" "bootstrap-frontend.tar.gz" + fi + update_config_file "/opt/coins/blockbook/flo/config/blockchaincfg.json" "$new_ip" cd /opt/coins/blockbook/flo exec /opt/coins/blockbook/flo/bin/blockbook -blockchaincfg=/opt/coins/blockbook/flo/config/blockchaincfg.json -datadir=/opt/coins/data/flo/blockbook/db -sync -internal=:9066 -public=:9166 -certfile=/opt/coins/blockbook/flo/cert/blockbook -explorer= -log_dir=/opt/coins/blockbook/flo/logs -dbcache=1073741824 ;; "backend") echo "Running backend command" + + if [ -n "$BOOTSTRAP_FILE" ] && [ -f "$BOOTSTRAP_FILE" ]; then + handle_bootstrap_file "$BOOTSTRAP_FILE" "/opt/coins/data/flo/backend" "$BACKEND_BOOTSTRAP_FILE_HASH_FILE" + elif [ -n "$BOOTSTRAP_URL" ]; then + handle_bootstrap_url "$BOOTSTRAP_URL" "/opt/coins/data/flo/backend" "$BACKEND_BOOTSTRAP_URL_FILE" "bootstrap-backend.tar.gz" + fi + cd /opt/coins/nodes/flo exec /opt/coins/nodes/flo/bin/flod -datadir=/opt/coins/data/flo/backend -conf=/opt/coins/nodes/flo/flo.conf -pid=/run/flo/flo.pid ;; diff --git a/instructions b/instructions new file mode 100644 index 0000000..e437b25 --- /dev/null +++ b/instructions @@ -0,0 +1,18 @@ +sudo docker volume create blockbook + +sudo docker network create blockbook + +# Run backend in daemon mode for production +docker run -d --name blockbook-backend --mount source=blockbook,target=/opt -p 38366:38366 -p 8066:8066 --network=blockbook vivekteega/blockbook:1.0.0 backend + +# Run backend in daemon mode for production with Bootstrap +docker run -d --name blockbook-backend --mount source=blockbook,target=/opt -p 38366:38366 -p 8066:8066 --network=blockbook --env BOOTSTRAP_URL=https://bootstrap.ranchimall.net/blockbook-flo-backend1.tar.gz vivekteega/blockbook:1.0.0 backend + +# Find the IP address of blockbook-backend container +ip_backend_container + +# Run frontend in daemon mode for production +docker run -d --name blockbook-frontend --mount source=blockbook,target=/opt -p 9166:9166 -p 9066:9066 --network=blockbook vivekteega/blockbook:1.0.0 frontend $ip_backend_container + +# Run frontend in daemon mode for production with Bootstrap +docker run -d --name blockbook-frontend --mount source=blockbook,target=/opt -p 9166:9166 -p 9066:9066 --network=blockbook --env BOOTSTRAP_URL=https://bootstrap.ranchimall.net/blockbook-flo-frontend.tar.gz vivekteega/blockbook:1.0.0 frontend $ip_backend_container \ No newline at end of file