2026-02-10 11:32:49 -08:00
#!/bin/bash
# Script to fix Blockscout initialization issues in VMID 5000
# Fixes: Database migrations, static assets, and proper startup
set -euo pipefail
VMID = 5000
echo "=========================================="
echo "Blockscout Initialization Fix for VMID 5000"
echo "=========================================="
echo ""
echo "This script fixes:"
echo " 1. Database migrations (creates missing tables)"
echo " 2. Static assets (builds and digests assets)"
echo " 3. Proper Blockscout startup command"
2026-04-07 23:22:12 -07:00
echo " 4. Public API stability under indexer load"
2026-02-10 11:32:49 -08:00
echo ""
cat << 'COMMANDS'
# ============================================================
# COMMANDS FOR ROOT USER IN VMID 5000
# ============================================================
# Run these commands from Proxmox host: pct exec 5000 -- bash
# Or if inside VMID 5000, run directly
# ============================================================
# ============================================================
# STEP 1: Check Current Status
# ============================================================
echo "=== Checking Blockscout Status ==="
docker ps -a | grep blockscout
docker logs blockscout 2>& 1 | tail -20
# ============================================================
# STEP 2: Access Blockscout Container
# ============================================================
# Find Blockscout container name
BLOCKSCOUT_CONTAINER = $( docker ps -a | grep blockscout | grep -v postgres | awk '{print $1}' | head -1)
if [ -z " $BLOCKSCOUT_CONTAINER " ] ; then
echo "ERROR: Blockscout container not found"
exit 1
fi
echo " Blockscout container: $BLOCKSCOUT_CONTAINER "
# ============================================================
# STEP 3: Run Database Migrations
# ============================================================
echo ""
echo "=== Running Database Migrations ==="
# Run migrations inside Blockscout container
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "Explorer.Release.migrate()" || \
docker exec -it $BLOCKSCOUT_CONTAINER mix ecto.migrate || \
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout migrate
# Verify migrations
echo ""
echo "=== Verifying Migrations ==="
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "
case Explorer.Repo.query( \" SELECT COUNT( *) FROM information_schema.tables WHERE table_schema = 'public' \" ) do
{ :ok, %{ rows: [ [ count] ] } } -> IO.puts( \" Tables in database: #{count}\")
error -> IO.puts( \" Error checking tables: #{inspect(error)}\")
end
"
# Check for critical tables
echo ""
echo "=== Checking Critical Tables ==="
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "
tables = [ \" blocks\" , \" transactions\" , \" migrations_status\" , \" addresses\" , \" smart_contracts\" ]
for table <- tables do
case Explorer.Repo.query( \" SELECT 1 FROM information_schema.tables WHERE table_name = '\#{table}' \" ) do
{ :ok, %{ rows: [ ] } } -> IO.puts( \" ❌ Table '\#{table}' MISSING\" )
{ :ok, %{ rows: [ _] } } -> IO.puts( \" ✅ Table '\#{table}' exists\" )
error -> IO.puts( \" ⚠️ Error checking '\#{table}' : #{inspect(error)}\")
end
end
"
# ============================================================
# STEP 4: Build and Digest Static Assets
# ============================================================
echo ""
echo "=== Building Static Assets ==="
# Build assets
docker exec -it $BLOCKSCOUT_CONTAINER mix phx.digest || \
docker exec -it $BLOCKSCOUT_CONTAINER npm run deploy || \
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "Mix.Tasks.Phx.Digest.run([])"
# Verify assets
echo ""
echo "=== Verifying Assets ==="
docker exec -it $BLOCKSCOUT_CONTAINER ls -la priv/static/cache_manifest.json || \
docker exec -it $BLOCKSCOUT_CONTAINER find priv/static -name "cache_manifest.json" || \
echo "⚠️ cache_manifest.json not found - assets may need manual build"
# ============================================================
# STEP 5: Fix Docker Compose Configuration
# ============================================================
echo ""
echo "=== Updating Docker Compose Configuration ==="
# Check current docker-compose.yml
BLOCKSCOUT_DIR = "/opt/blockscout"
if [ -f " $BLOCKSCOUT_DIR /docker-compose.yml " ] ; then
echo " Found docker-compose.yml at $BLOCKSCOUT_DIR "
# Backup original
cp " $BLOCKSCOUT_DIR /docker-compose.yml " " $BLOCKSCOUT_DIR /docker-compose.yml.backup "
2026-04-07 23:22:12 -07:00
# Update command to explicitly start Blockscout, use the local Docker-network
# Postgres path, and apply safer DB pool defaults.
2026-02-10 11:32:49 -08:00
sed -i 's|command:.*|command: bin/blockscout start|g' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/blockscout:/a\ command: bin/blockscout start' " $BLOCKSCOUT_DIR /docker-compose.yml "
2026-04-07 23:22:12 -07:00
grep -q 'DATABASE_URL=' " $BLOCKSCOUT_DIR /docker-compose.yml " && \
sed -i 's#DATABASE_URL=.*#DATABASE_URL=postgresql://blockscout:blockscout@postgres:5432/blockscout?sslmode=disable#' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/environment:/a\ - DATABASE_URL=postgresql://blockscout:blockscout@postgres:5432/blockscout?sslmode=disable' " $BLOCKSCOUT_DIR /docker-compose.yml "
grep -q 'POOL_SIZE=' " $BLOCKSCOUT_DIR /docker-compose.yml " && \
sed -i 's/POOL_SIZE=.*/POOL_SIZE=50/' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/SECRET_KEY_BASE=/a\ - POOL_SIZE=50' " $BLOCKSCOUT_DIR /docker-compose.yml "
grep -q 'POOL_SIZE_API=' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/POOL_SIZE=50/a\ - POOL_SIZE_API=50' " $BLOCKSCOUT_DIR /docker-compose.yml "
grep -q 'DATABASE_QUEUE_TARGET=' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/POOL_SIZE_API=50/a\ - DATABASE_QUEUE_TARGET=5s' " $BLOCKSCOUT_DIR /docker-compose.yml "
grep -q 'INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER=' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/DATABASE_QUEUE_TARGET=5s/a\ - INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER=true' " $BLOCKSCOUT_DIR /docker-compose.yml "
grep -q 'ECTO_USE_SSL=' " $BLOCKSCOUT_DIR /docker-compose.yml " && \
sed -i 's/ECTO_USE_SSL=.*/ECTO_USE_SSL=false/' " $BLOCKSCOUT_DIR /docker-compose.yml " || \
sed -i '/INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER=true/a\ - ECTO_USE_SSL=false' " $BLOCKSCOUT_DIR /docker-compose.yml "
2026-02-10 11:32:49 -08:00
echo "✅ Updated docker-compose.yml"
else
echo " ⚠️ docker-compose.yml not found at $BLOCKSCOUT_DIR "
echo "You may need to update it manually to include:"
echo " command: bin/blockscout start"
2026-04-07 23:22:12 -07:00
echo " POOL_SIZE=50"
echo " POOL_SIZE_API=50"
echo " DATABASE_QUEUE_TARGET=5s"
echo " INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER=true"
echo " ECTO_USE_SSL=false"
echo " DATABASE_URL=postgresql://blockscout:blockscout@postgres:5432/blockscout?sslmode=disable"
2026-02-10 11:32:49 -08:00
fi
# ============================================================
# STEP 6: Restart Blockscout with Proper Command
# ============================================================
echo ""
echo "=== Restarting Blockscout ==="
# Stop current container
docker stop $BLOCKSCOUT_CONTAINER 2>/dev/null || true
docker rm $BLOCKSCOUT_CONTAINER 2>/dev/null || true
# Restart using docker-compose (if available)
if [ -f " $BLOCKSCOUT_DIR /docker-compose.yml " ] ; then
cd " $BLOCKSCOUT_DIR "
2026-04-07 23:22:12 -07:00
docker compose up -d blockscout || docker-compose up -d blockscout
2026-02-10 11:32:49 -08:00
else
# Manual start with correct command
echo "Starting Blockscout manually..."
2026-04-07 23:22:12 -07:00
EXTRA_ENV_FILE = ( )
if [ -f " $BLOCKSCOUT_DIR /.env " ] ; then
EXTRA_ENV_FILE += ( --env-file " $BLOCKSCOUT_DIR /.env " )
else
echo " ⚠️ $BLOCKSCOUT_DIR /.env not found; relying on explicit fallback env only "
fi
2026-02-10 11:32:49 -08:00
docker run -d \
--name blockscout \
2026-04-07 23:22:12 -07:00
--restart unless-stopped \
--network blockscout_blockscout-network \
" ${ EXTRA_ENV_FILE [@] } " \
2026-02-10 11:32:49 -08:00
-p 4000:4000 \
2026-04-07 23:22:12 -07:00
-e DATABASE_URL = postgresql://blockscout:blockscout@postgres:5432/blockscout?sslmode= disable \
-e POOL_SIZE = 50 \
-e POOL_SIZE_API = 50 \
-e DATABASE_QUEUE_TARGET = 5s \
-e INDEXER_DISABLE_PENDING_TRANSACTIONS_FETCHER = true \
-e ECTO_USE_SSL = false \
2026-02-10 11:32:49 -08:00
blockscout/blockscout:latest \
bin/blockscout start
fi
# Wait for startup
echo "Waiting for Blockscout to start..."
sleep 10
# Check status
echo ""
echo "=== Checking Blockscout Status ==="
docker ps | grep blockscout
docker logs blockscout 2>& 1 | tail -30
# ============================================================
# STEP 7: Verify Everything is Working
# ============================================================
echo ""
echo "=== Final Verification ==="
# Check if container is running
if docker ps | grep -q blockscout; then
echo "✅ Blockscout container is running"
else
echo "❌ Blockscout container is not running"
echo "Check logs: docker logs blockscout"
exit 1
fi
# Check database tables
echo ""
echo "Checking database tables..."
docker exec -it $BLOCKSCOUT_CONTAINER bin/blockscout eval "
tables = [ \" blocks\" , \" transactions\" , \" migrations_status\" ]
missing = [ ]
for table <- tables do
case Explorer.Repo.query( \" SELECT 1 FROM information_schema.tables WHERE table_name = '\#{table}' \" ) do
{ :ok, %{ rows: [ ] } } -> missing = missing ++ [ table]
_ -> :ok
end
end
if length( missing) > 0 do
IO.puts( \" ❌ Missing tables: #{inspect(missing)}\")
else
IO.puts( \" ✅ All critical tables exist\" )
end
" 2>/dev/null || echo " ⚠️ Could not verify tables ( container may still be starting) "
# Check assets
echo ""
echo "Checking static assets..."
if docker exec -it $BLOCKSCOUT_CONTAINER test -f priv/static/cache_manifest.json 2>/dev/null; then
echo "✅ cache_manifest.json exists"
else
echo "⚠️ cache_manifest.json not found - assets may need manual build"
fi
echo ""
echo "=========================================="
echo "✅ Blockscout initialization complete!"
echo "=========================================="
echo ""
echo "If issues persist, check logs:"
echo " docker logs blockscout"
echo ""
echo "To access Blockscout console:"
echo " docker exec -it blockscout bin/blockscout remote"
echo ""
COMMANDS
echo ""
echo "=========================================="
echo "Alternative: One-Line Migration Command"
echo "=========================================="
echo ""
echo "If you just need to run migrations quickly:"
echo ""
echo "pct exec 5000 -- bash -c 'BLOCKSCOUT_CONTAINER=\$(docker ps -a | grep blockscout | grep -v postgres | awk \"{print \\\$1}\" | head -1); docker exec -it \$BLOCKSCOUT_CONTAINER bin/blockscout eval \"Explorer.Release.migrate()\"'"
echo ""