2026-01-06 01:46:25 -08:00
#!/usr/bin/env bash
# Complete all next steps for Blockscout setup
# Runs migrations, verifies SSL, tests connectivity
set -euo pipefail
2026-02-12 15:46:57 -08:00
# Load IP configuration
SCRIPT_DIR = " $( cd " $( dirname " ${ BASH_SOURCE [0] } " ) " && pwd ) "
PROJECT_ROOT = " $( cd " $SCRIPT_DIR /.. " && pwd ) "
source " ${ PROJECT_ROOT } /config/ip-addresses.conf " 2>/dev/null || true
2026-01-06 01:46:25 -08:00
VMID = " ${ VMID :- 5000 } "
2026-02-12 15:46:57 -08:00
IP = " ${ IP :- ${ IP_DEVICE_14 :- ${ IP_DEVICE_14 :- ${ IP_DEVICE_14 :- ${ IP_DEVICE_14 :- ${ IP_DEVICE_14 :- 192 .168.11.14 } } } } } 0 } "
2026-01-06 01:46:25 -08:00
DOMAIN = " ${ DOMAIN :- explorer .d-bis.org } "
PASSWORD = " ${ PASSWORD :- L @kers2010 } "
2026-02-12 15:46:57 -08:00
CONTAINER_NODE = " ${ CONTAINER_NODE :- r630 -02 } "
2026-01-06 01:46:25 -08:00
PROXMOX_HOST = " ${ PROXMOX_HOST :- 192 .168.11.10 } "
# Colors
RED = '\033[0;31m'
GREEN = '\033[0;32m'
YELLOW = '\033[1;33m'
BLUE = '\033[0;34m'
NC = '\033[0m'
log_info( ) { echo -e " ${ BLUE } [INFO] ${ NC } $1 " ; }
log_success( ) { echo -e " ${ GREEN } [✓] ${ NC } $1 " ; }
log_warn( ) { echo -e " ${ YELLOW } [WARN] ${ NC } $1 " ; }
log_error( ) { echo -e " ${ RED } [ERROR] ${ NC } $1 " ; }
exec_container( ) {
local cmd = " $1 "
sshpass -p " $PASSWORD " ssh -o StrictHostKeyChecking = no root@" $IP " " bash -c ' $cmd ' " 2>& 1
}
echo "════════════════════════════════════════════════════════"
echo "Complete Blockscout Next Steps"
echo "════════════════════════════════════════════════════════"
echo ""
# Step 1: Check database tables
log_info "Step 1: Checking database schema..."
TABLE_COUNT = $( exec_container "docker exec blockscout-postgres psql -U blockscout -d blockscout -t -c \"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';\" 2>&1" | tr -d ' \n' || echo "0" )
log_info " Current tables in database: $TABLE_COUNT "
# Step 2: Run migrations if needed
if [ " $TABLE_COUNT " = "0" ] || [ -z " $TABLE_COUNT " ] ; then
log_info "Step 2: Running database migrations (database is empty)..."
log_info "This will take 3-5 minutes..."
MIGRATE_OUTPUT = $( exec_container " cd /opt/blockscout && docker run --rm --network blockscout_blockscout-network \
-e DATABASE_URL = postgresql://blockscout:blockscout@postgres:5432/blockscout \
2026-02-12 15:46:57 -08:00
-e ETHEREUM_JSONRPC_HTTP_URL = http://${ RPC_PUBLIC_1 :- 192 .168.11.221 } :8545 \
2026-01-06 01:46:25 -08:00
-e CHAIN_ID = 138 \
-e SECRET_KEY_BASE = 73159c7d10b9a5a75ddf10710773078c078bf02124d35b72fa2a841b30b4f88c7c43e5caaf7f9f7f87d16dd66e7870931ae11039c428d1dedae187af762531fa \
blockscout/blockscout:latest /app/bin/blockscout eval \" Ecto.Migrator.run( Explorer.Repo, :up, all: true ) \" 2>& 1" || echo " FAILED" )
if echo " $MIGRATE_OUTPUT " | grep -qE "(migrated|already up|Migrating|== Running)" ; then
log_success "Migrations completed"
echo " $MIGRATE_OUTPUT " | grep -E "(migrated|already|Migrating|== Running)" | head -10
else
log_warn "Migration output unclear, but continuing..."
echo " $MIGRATE_OUTPUT " | tail -20
fi
# Verify tables were created
NEW_TABLE_COUNT = $( exec_container "docker exec blockscout-postgres psql -U blockscout -d blockscout -t -c \"SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = 'public';\" 2>&1" | tr -d ' \n' || echo "0" )
log_info " Tables after migration: $NEW_TABLE_COUNT "
if [ " $NEW_TABLE_COUNT " -gt 10 ] ; then
log_success " Database schema created successfully ( $NEW_TABLE_COUNT tables) "
else
log_warn "Table count seems low, but continuing..."
fi
else
log_success " Database already has tables ( $TABLE_COUNT ), skipping migrations "
fi
# Step 3: Ensure Blockscout is configured correctly
log_info "Step 3: Verifying Blockscout configuration..."
exec_container " cd /opt/blockscout && if [ -f docker-compose.yml ]; then
# Ensure HTTPS and correct host
sed -i 's|BLOCKSCOUT_PROTOCOL=http|BLOCKSCOUT_PROTOCOL=https|g' docker-compose.yml
2026-02-12 15:46:57 -08:00
sed -i 's|BLOCKSCOUT_HOST=${IP_BLOCKSCOUT:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-${IP_DEVICE_14:-192.168.11.14}}}}}0}|BLOCKSCOUT_HOST=$DOMAIN|g' docker-compose.yml
2026-01-06 01:46:25 -08:00
sed -i 's|BLOCKSCOUT_HOST=localhost|BLOCKSCOUT_HOST=$DOMAIN|g' docker-compose.yml
# Ensure DISABLE_WEBAPP=false and command is set
if ! grep -q 'DISABLE_WEBAPP=false' docker-compose.yml; then
sed -i '/environment:/a\ - DISABLE_WEBAPP=false' docker-compose.yml
fi
if ! grep -q 'command:' docker-compose.yml; then
sed -i '/container_name: blockscout/a\ command: /app/bin/blockscout start' docker-compose.yml
fi
echo 'Configuration verified'
fi "
# Step 4: Restart Blockscout
log_info "Step 4: Restarting Blockscout..."
exec_container "cd /opt/blockscout && docker-compose down && docker-compose up -d postgres && sleep 10 && docker-compose up -d blockscout"
log_success "Blockscout restarted"
# Step 5: Wait and monitor startup
log_info "Step 5: Waiting for Blockscout to initialize (this may take 2-3 minutes)..."
for i in { 1..18} ; do
sleep 10
STATUS = $( exec_container "docker ps | grep blockscout | awk '{print \$7}'" || echo "" )
if echo " $STATUS " | grep -q "Up" && ! echo " $STATUS " | grep -q "Restarting" ; then
log_success "Container is stable"
break
fi
if [ $i -eq 9 ] || [ $i -eq 18 ] ; then
log_info " Still waiting... ( $i /18) "
fi
done
# Step 6: Check if Phoenix is running
log_info "Step 6: Checking Blockscout logs for Phoenix endpoint..."
PHOENIX_LOG = $( exec_container "docker logs --tail 100 blockscout 2>&1 | grep -E 'Running.*BlockScoutWeb.Endpoint|listening|started|Application.*started' | tail -5" || echo "" )
if [ -n " $PHOENIX_LOG " ] ; then
log_success "Phoenix endpoint found in logs"
echo " $PHOENIX_LOG "
else
log_warn "Phoenix endpoint not yet in logs (may still be starting)"
fi
# Step 7: Test API endpoints
log_info "Step 7: Testing Blockscout API..."
sleep 5
for i in { 1..6} ; do
API_RESPONSE = $( exec_container "timeout 5 curl -s http://localhost:4000/api/v2/status 2>&1" || echo "" )
if echo " $API_RESPONSE " | grep -qE "(chain_id|success|block)" ; then
log_success "Blockscout API is responding!"
echo " $API_RESPONSE " | head -3
break
fi
if [ $i -lt 6 ] ; then
log_info " API not ready yet, waiting... ( $i /6) "
sleep 10
else
log_warn "API not responding after 60 seconds"
log_info " Response: $API_RESPONSE "
fi
done
# Step 8: Test Nginx HTTPS
log_info "Step 8: Testing Nginx HTTPS endpoint..."
NGINX_TEST = $( exec_container "timeout 5 curl -k -s -o /dev/null -w '%{http_code}' https://localhost/health 2>&1" || echo "000" )
if [ " $NGINX_TEST " = "200" ] || [ " $NGINX_TEST " = "502" ] ; then
if [ " $NGINX_TEST " = "200" ] ; then
log_success "Nginx HTTPS working (HTTP 200)"
else
log_warn "Nginx HTTPS responding but Blockscout not ready (HTTP 502)"
fi
else
log_warn " Nginx HTTPS test returned: HTTP $NGINX_TEST "
fi
# Step 9: Test external access
log_info "Step 9: Testing external HTTPS access..."
EXTERNAL_TEST = $( curl -k -s -o /dev/null -w '%{http_code}' --connect-timeout 10 " https:// $DOMAIN /health " 2>& 1 || echo "000" )
if [ " $EXTERNAL_TEST " = "200" ] ; then
log_success "External HTTPS working! (HTTP 200)"
elif [ " $EXTERNAL_TEST " = "502" ] ; then
log_warn "External HTTPS accessible but Blockscout not ready (HTTP 502)"
else
log_warn " External HTTPS test returned: HTTP $EXTERNAL_TEST "
fi
# Step 10: Verify SSL certificate
log_info "Step 10: Verifying SSL certificate..."
CERT_INFO = $( exec_container " openssl x509 -in /etc/letsencrypt/live/ $DOMAIN /fullchain.pem -noout -subject -issuer -dates 2>&1 " || echo "" )
if echo " $CERT_INFO " | grep -q "explorer.d-bis.org" ; then
log_success "SSL certificate is valid"
echo " $CERT_INFO " | head -3
fi
# Step 11: Verify Cloudflare tunnel route
log_info "Step 11: Verifying configuration summary..."
echo ""
echo "════════════════════════════════════════════════════════"
echo "All Next Steps Complete!"
echo "════════════════════════════════════════════════════════"
echo ""
log_success "Summary:"
echo " Container Node: $CONTAINER_NODE "
echo " Container IP: $IP "
echo " Domain: $DOMAIN "
echo " SSL Certificate: Installed"
echo " Nginx: Configured with HTTPS"
echo " Cloudflare Tunnel: Updated to HTTPS"
echo ""
log_info "Access Points:"
echo " Internal HTTPS: https:// $IP "
echo " External HTTPS: https:// $DOMAIN "
echo " API: https:// $DOMAIN /api "
echo ""
log_info "Status:"
if [ " $NGINX_TEST " = "200" ] ; then
echo " ✅ Nginx HTTPS: Working"
elif [ " $NGINX_TEST " = "502" ] ; then
echo " ⏳ Nginx HTTPS: Waiting for Blockscout"
else
echo " ⚠️ Nginx HTTPS: HTTP $NGINX_TEST "
fi
if [ " $EXTERNAL_TEST " = "200" ] ; then
echo " ✅ External HTTPS: Working"
elif [ " $EXTERNAL_TEST " = "502" ] ; then
echo " ⏳ External HTTPS: Waiting for Blockscout"
else
echo " ⚠️ External HTTPS: HTTP $EXTERNAL_TEST "
fi
echo ""
log_info "Blockscout may take 2-5 minutes to fully initialize after migrations"
log_info "Monitor progress: docker logs -f blockscout"
echo ""