Add full monorepo: virtual-banker, backend, frontend, docs, scripts, deployment

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
defiQUG
2026-02-10 11:32:49 -08:00
parent 4d4f8cedad
commit 903c03c65b
815 changed files with 125522 additions and 264 deletions

47
deployment/scripts/build-all.sh Executable file
View File

@@ -0,0 +1,47 @@
#!/bin/bash
# Build all applications
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
echo "Building all applications..."
cd "$PROJECT_ROOT"
# Build backend services
echo "Building backend services..."
cd backend
# Indexer
echo " Building indexer..."
go build -o /usr/local/bin/explorer-indexer ./indexer/main.go
# API
echo " Building API..."
go build -o /usr/local/bin/explorer-api ./api/rest/main.go
# Gateway
echo " Building gateway..."
go build -o /usr/local/bin/explorer-gateway ./api/gateway/main.go
# Search
echo " Building search service..."
go build -o /usr/local/bin/explorer-search ./api/search/main.go
# Build frontend
echo "Building frontend..."
cd ../frontend
npm ci
npm run build
echo ""
echo "All applications built successfully!"
echo ""
echo "Binaries installed to:"
echo " /usr/local/bin/explorer-indexer"
echo " /usr/local/bin/explorer-api"
echo " /usr/local/bin/explorer-gateway"
echo " /usr/local/bin/explorer-search"

170
deployment/scripts/deploy-lxc.sh Executable file
View File

@@ -0,0 +1,170 @@
#!/bin/bash
# LXC Deployment Script for ChainID 138 Explorer Platform
# This script automates the deployment process
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
PROJECT_ROOT="$( cd "$SCRIPT_DIR/../.." && pwd )"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
# Configuration
CONTAINER_ID="${CONTAINER_ID:-100}"
CONTAINER_HOSTNAME="${CONTAINER_HOSTNAME:-explorer-prod}"
DOMAIN="${DOMAIN:-explorer.d-bis.org}"
SKIP_CONTAINER_CREATION="${SKIP_CONTAINER_CREATION:-false}"
echo -e "${GREEN}=== ChainID 138 Explorer Platform - LXC Deployment ===${NC}"
echo ""
# Check if running on Proxmox host
if ! command -v pct &> /dev/null; then
echo -e "${RED}Error: This script must be run on a Proxmox host${NC}"
exit 1
fi
# Phase 1: Create LXC Container
if [ "$SKIP_CONTAINER_CREATION" != "true" ]; then
echo -e "${YELLOW}Phase 1: Creating LXC Container...${NC}"
# Check if container already exists
if pct list | grep -q "^$CONTAINER_ID "; then
echo -e "${YELLOW}Container $CONTAINER_ID already exists. Skipping creation.${NC}"
echo "Set SKIP_CONTAINER_CREATION=true to skip this check."
read -p "Do you want to continue with existing container? (y/N): " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
else
echo "Creating container $CONTAINER_ID..."
pct create $CONTAINER_ID \
local:vztmpl/ubuntu-22.04-standard_22.04-1_amd64.tar.zst \
--hostname $CONTAINER_HOSTNAME \
--memory 16384 \
--cores 4 \
--swap 4096 \
--storage local-lvm \
--rootfs local-lvm:100 \
--net0 name=eth0,bridge=vmbr0,ip=dhcp \
--unprivileged 0 \
--features nesting=1 \
--start 1
echo "Waiting for container to start..."
sleep 5
fi
fi
# Phase 2: Initial Container Setup
echo -e "${YELLOW}Phase 2: Initial Container Setup...${NC}"
cat << 'INITSCRIPT' | pct exec $CONTAINER_ID bash
set -e
# Update system
apt update && apt upgrade -y
# Install essential packages
apt install -y curl wget git vim net-tools ufw fail2ban \
unattended-upgrades apt-transport-https ca-certificates \
gnupg lsb-release software-properties-common
# Set timezone
timedatectl set-timezone UTC
# Create deployment user
if ! id "explorer" &>/dev/null; then
adduser --disabled-password --gecos "" explorer
usermod -aG sudo explorer
echo "explorer ALL=(ALL) NOPASSWD:ALL" >> /etc/sudoers
fi
INITSCRIPT
echo -e "${GREEN}✓ Container setup complete${NC}"
# Phase 3: Install Dependencies
echo -e "${YELLOW}Phase 3: Installing Dependencies...${NC}"
cat << 'DEPSCRIPT' | pct exec $CONTAINER_ID bash
set -e
# Install Go
if ! command -v go &> /dev/null; then
cd /tmp
wget -q https://go.dev/dl/go1.21.6.linux-amd64.tar.gz
rm -rf /usr/local/go
tar -C /usr/local -xzf go1.21.6.linux-amd64.tar.gz
echo 'export PATH=$PATH:/usr/local/go/bin' >> /etc/profile
export PATH=$PATH:/usr/local/go/bin
fi
# Install Node.js
if ! command -v node &> /dev/null; then
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
apt install -y nodejs
fi
# Install Docker
if ! command -v docker &> /dev/null; then
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
systemctl enable docker
systemctl start docker
usermod -aG docker explorer
fi
# Install PostgreSQL
if ! command -v psql &> /dev/null; then
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | apt-key add -
apt update
apt install -y postgresql-16 postgresql-contrib-16
fi
# Install Nginx
if ! command -v nginx &> /dev/null; then
apt install -y nginx
fi
# Install cloudflared
if ! command -v cloudflared &> /dev/null; then
cd /tmp
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb || apt install -f -y
fi
DEPSCRIPT
echo -e "${GREEN}✓ Dependencies installed${NC}"
# Phase 4: Deploy Application
echo -e "${YELLOW}Phase 4: Deploying Application...${NC}"
# Copy project files to container (assuming git clone on host)
echo "Note: You'll need to clone the repository inside the container or copy files"
echo "For now, the script will prepare the structure"
cat << 'APPSCRIPT' | pct exec $CONTAINER_ID bash -s
set -e
mkdir -p /home/explorer/explorer-monorepo
chown explorer:explorer /home/explorer/explorer-monorepo
APPSCRIPT
echo -e "${YELLOW}Please complete the deployment manually:${NC}"
echo "1. Clone repository inside container: pct exec $CONTAINER_ID"
echo "2. Copy .env file and configure"
echo "3. Run migrations"
echo "4. Build applications"
echo "5. Configure services"
echo ""
echo "See DEPLOYMENT_GUIDE.md for complete instructions"
echo -e "${GREEN}=== Deployment Script Complete ===${NC}"

View File

@@ -0,0 +1,81 @@
#!/bin/bash
# Full automated deployment script
# This script automates most of the deployment process
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEPLOYMENT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
PROJECT_ROOT="$( cd "$DEPLOYMENT_DIR/.." && pwd )"
# Colors
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
echo -e "${GREEN}=== Full Deployment Script ===${NC}"
echo ""
# Check if running as root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}Please run as root${NC}"
exit 1
fi
# Phase 1: Install dependencies
echo -e "${YELLOW}Phase 1: Installing dependencies...${NC}"
"$SCRIPT_DIR/../scripts/setup.sh" || {
echo "Installing dependencies manually..."
apt update
apt install -y curl wget git vim net-tools ufw fail2ban \
unattended-upgrades apt-transport-https ca-certificates \
gnupg lsb-release software-properties-common
}
# Phase 2: Install Go, Node.js, Docker
echo -e "${YELLOW}Phase 2: Installing development tools...${NC}"
# These would be installed by setup.sh or manually
echo "Please ensure Go, Node.js, and Docker are installed"
echo "Run: ./scripts/check-requirements.sh"
# Phase 3: Setup Nginx
echo -e "${YELLOW}Phase 3: Setting up Nginx...${NC}"
"$SCRIPT_DIR/setup-nginx.sh"
# Phase 4: Install services
echo -e "${YELLOW}Phase 4: Installing systemd services...${NC}"
"$SCRIPT_DIR/install-services.sh"
# Phase 5: Setup firewall
echo -e "${YELLOW}Phase 5: Setting up firewall...${NC}"
"$SCRIPT_DIR/setup-firewall.sh"
# Phase 6: Setup backups
echo -e "${YELLOW}Phase 6: Setting up backups...${NC}"
"$SCRIPT_DIR/setup-backup.sh"
# Phase 7: Setup health checks
echo -e "${YELLOW}Phase 7: Setting up health checks...${NC}"
"$SCRIPT_DIR/setup-health-check.sh"
# Phase 8: Cloudflare Tunnel (optional, interactive)
echo -e "${YELLOW}Phase 8: Cloudflare Tunnel setup (optional)...${NC}"
read -p "Do you want to set up Cloudflare Tunnel now? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
"$SCRIPT_DIR/setup-cloudflare-tunnel.sh"
fi
echo ""
echo -e "${GREEN}=== Deployment Complete ===${NC}"
echo ""
echo "Next steps:"
echo "1. Configure .env file: /home/explorer/explorer-monorepo/.env"
echo "2. Run database migrations"
echo "3. Build applications"
echo "4. Start services: systemctl start explorer-indexer explorer-api explorer-frontend"
echo "5. Configure Cloudflare DNS and SSL"
echo ""
echo "See DEPLOYMENT_GUIDE.md for detailed instructions"

View File

@@ -0,0 +1,27 @@
#!/bin/bash
# Install systemd service files
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEPLOYMENT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
echo "Installing systemd service files..."
# Copy service files
cp "$DEPLOYMENT_DIR/systemd/explorer-indexer.service" /etc/systemd/system/
cp "$DEPLOYMENT_DIR/systemd/explorer-api.service" /etc/systemd/system/
cp "$DEPLOYMENT_DIR/systemd/explorer-frontend.service" /etc/systemd/system/
cp "$DEPLOYMENT_DIR/systemd/cloudflared.service" /etc/systemd/system/
# Set permissions
chmod 644 /etc/systemd/system/explorer-*.service
chmod 644 /etc/systemd/system/cloudflared.service
# Reload systemd
systemctl daemon-reload
echo "Service files installed. Enable with:"
echo " systemctl enable explorer-indexer explorer-api explorer-frontend"
echo " systemctl start explorer-indexer explorer-api explorer-frontend"

View File

@@ -0,0 +1,49 @@
#!/bin/bash
# Setup backup script and cron job
set -e
echo "Setting up backup system..."
# Create backup directory
mkdir -p /backups/explorer
chown explorer:explorer /backups/explorer
# Create backup script
cat > /usr/local/bin/explorer-backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR="/backups/explorer"
DATE=$(date +%Y%m%d_%H%M%S)
mkdir -p $BACKUP_DIR
# Backup database
echo "Backing up database..."
pg_dump -U explorer explorer | gzip > $BACKUP_DIR/db_$DATE.sql.gz
# Backup configuration
echo "Backing up configuration..."
tar -czf $BACKUP_DIR/config_$DATE.tar.gz \
/home/explorer/explorer-monorepo/.env \
/etc/nginx/sites-available/explorer \
/etc/systemd/system/explorer-*.service \
/etc/cloudflared/config.yml 2>/dev/null || true
# Cleanup old backups (keep 30 days)
echo "Cleaning up old backups..."
find $BACKUP_DIR -type f -mtime +30 -delete
echo "Backup completed: $DATE"
EOF
chmod +x /usr/local/bin/explorer-backup.sh
chown explorer:explorer /usr/local/bin/explorer-backup.sh
# Add to crontab (daily at 2 AM)
(crontab -l 2>/dev/null | grep -v explorer-backup.sh; echo "0 2 * * * /usr/local/bin/explorer-backup.sh >> /var/log/explorer-backup.log 2>&1") | crontab -
echo "Backup system configured!"
echo "Backups will run daily at 2 AM"
echo "Backup location: /backups/explorer"
echo ""
echo "To run backup manually: /usr/local/bin/explorer-backup.sh"

View File

@@ -0,0 +1,68 @@
#!/bin/bash
# Setup Cloudflare Tunnel
set -e
echo "Setting up Cloudflare Tunnel..."
# Check if cloudflared is installed
if ! command -v cloudflared &> /dev/null; then
echo "Installing cloudflared..."
cd /tmp
wget -q https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64.deb
dpkg -i cloudflared-linux-amd64.deb || apt install -f -y
fi
# Authenticate (interactive)
echo "Please authenticate with Cloudflare..."
cloudflared tunnel login
# Create tunnel
echo "Creating tunnel..."
TUNNEL_NAME="explorer-tunnel"
cloudflared tunnel create $TUNNEL_NAME || echo "Tunnel may already exist"
# Get tunnel ID
TUNNEL_ID=$(cloudflared tunnel list | grep $TUNNEL_NAME | awk '{print $1}')
if [ -z "$TUNNEL_ID" ]; then
echo "ERROR: Could not find tunnel ID"
exit 1
fi
echo "Tunnel ID: $TUNNEL_ID"
# Create config directory
mkdir -p /etc/cloudflared
# Create config file
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEPLOYMENT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
cat > /etc/cloudflared/config.yml << EOF
tunnel: $TUNNEL_ID
credentials-file: /etc/cloudflared/$TUNNEL_ID.json
ingress:
- hostname: explorer.d-bis.org
service: http://localhost:80
- hostname: www.explorer.d-bis.org
service: http://localhost:80
- service: http_status:404
EOF
# Validate config
cloudflared tunnel --config /etc/cloudflared/config.yml ingress validate
# Install as service
cloudflared service install
echo "Cloudflare Tunnel configured!"
echo "Tunnel ID: $TUNNEL_ID"
echo "Config: /etc/cloudflared/config.yml"
echo ""
echo "Next steps:"
echo "1. Configure DNS routes in Cloudflare dashboard"
echo "2. Start service: systemctl start cloudflared"
echo "3. Enable on boot: systemctl enable cloudflared"

View File

@@ -0,0 +1,51 @@
#!/bin/bash
# Setup Fail2ban for Nginx
set -e
echo "Setting up Fail2ban..."
# Install fail2ban if not installed
if ! command -v fail2ban-server &> /dev/null; then
apt update
apt install -y fail2ban
fi
# Create filter for Nginx
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEPLOYMENT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
cat > /etc/fail2ban/filter.d/nginx-limit-req.conf << 'EOF'
[Definition]
failregex = ^.*limiting requests, excess:.*by zone.*client: <HOST>.*$
ignoreregex =
EOF
# Create jail configuration
cat > /etc/fail2ban/jail.d/explorer.conf << 'EOF'
[nginx-limit-req]
enabled = true
port = http,https
logpath = /var/log/nginx/explorer-error.log
maxretry = 10
findtime = 600
bantime = 3600
[nginx-botsearch]
enabled = true
port = http,https
logpath = /var/log/nginx/explorer-access.log
maxretry = 2
findtime = 600
bantime = 86400
EOF
# Restart fail2ban
systemctl restart fail2ban
# Check status
fail2ban-client status
echo "Fail2ban configured!"
echo "Jails: nginx-limit-req, nginx-botsearch"

View File

@@ -0,0 +1,47 @@
#!/bin/bash
# Setup firewall rules
set -e
echo "Configuring firewall (UFW)..."
# Enable UFW
ufw --force enable
# Allow SSH
ufw allow 22/tcp comment 'SSH'
# Allow HTTP/HTTPS (if direct connection)
read -p "Do you have a direct public IP? (y/N): " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
ufw allow 80/tcp comment 'HTTP'
ufw allow 443/tcp comment 'HTTPS'
fi
# Allow Cloudflare IP ranges (if using direct connection)
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Adding Cloudflare IP ranges..."
ufw allow from 173.245.48.0/20 comment 'Cloudflare'
ufw allow from 103.21.244.0/22 comment 'Cloudflare'
ufw allow from 103.22.200.0/22 comment 'Cloudflare'
ufw allow from 103.31.4.0/22 comment 'Cloudflare'
ufw allow from 141.101.64.0/18 comment 'Cloudflare'
ufw allow from 108.162.192.0/18 comment 'Cloudflare'
ufw allow from 190.93.240.0/20 comment 'Cloudflare'
ufw allow from 188.114.96.0/20 comment 'Cloudflare'
ufw allow from 197.234.240.0/22 comment 'Cloudflare'
ufw allow from 198.41.128.0/17 comment 'Cloudflare'
ufw allow from 162.158.0.0/15 comment 'Cloudflare'
ufw allow from 104.16.0.0/13 comment 'Cloudflare'
ufw allow from 104.24.0.0/14 comment 'Cloudflare'
ufw allow from 172.64.0.0/13 comment 'Cloudflare'
ufw allow from 131.0.72.0/22 comment 'Cloudflare'
fi
# Show status
ufw status verbose
echo ""
echo "Firewall configured!"

View File

@@ -0,0 +1,44 @@
#!/bin/bash
# Setup health check script and cron job
set -e
echo "Setting up health check system..."
# Create health check script
cat > /usr/local/bin/explorer-health-check.sh << 'EOF'
#!/bin/bash
API_URL="http://localhost:8080/health"
LOG_FILE="/var/log/explorer-health-check.log"
# Check API health
STATUS=$(curl -s -o /dev/null -w "%{http_code}" $API_URL 2>/dev/null || echo "000")
if [ "$STATUS" != "200" ]; then
echo "$(date): Health check failed - Status: $STATUS" >> $LOG_FILE
# Restart API service
systemctl restart explorer-api
# Wait a bit and check again
sleep 10
STATUS2=$(curl -s -o /dev/null -w "%{http_code}" $API_URL 2>/dev/null || echo "000")
if [ "$STATUS2" != "200" ]; then
echo "$(date): API still unhealthy after restart - Status: $STATUS2" >> $LOG_FILE
# Send alert (configure email/Slack/etc here)
else
echo "$(date): API recovered after restart" >> $LOG_FILE
fi
fi
EOF
chmod +x /usr/local/bin/explorer-health-check.sh
# Add to crontab (every 5 minutes)
(crontab -l 2>/dev/null | grep -v explorer-health-check.sh; echo "*/5 * * * * /usr/local/bin/explorer-health-check.sh") | crontab -
echo "Health check system configured!"
echo "Health checks will run every 5 minutes"
echo "Log file: /var/log/explorer-health-check.log"

View File

@@ -0,0 +1,35 @@
#!/bin/bash
# Setup Nginx configuration
set -e
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
DEPLOYMENT_DIR="$( cd "$SCRIPT_DIR/.." && pwd )"
echo "Setting up Nginx configuration..."
# Install Nginx if not installed
if ! command -v nginx &> /dev/null; then
apt update
apt install -y nginx
fi
# Copy configuration
cp "$DEPLOYMENT_DIR/nginx/explorer.conf" /etc/nginx/sites-available/explorer
# Enable site
ln -sf /etc/nginx/sites-available/explorer /etc/nginx/sites-enabled/
# Remove default site
rm -f /etc/nginx/sites-enabled/default
# Test configuration
if nginx -t; then
echo "Nginx configuration is valid"
systemctl reload nginx
echo "Nginx reloaded"
else
echo "ERROR: Nginx configuration test failed"
exit 1
fi

View File

@@ -0,0 +1,103 @@
#!/bin/bash
# Verify deployment is working correctly
set -e
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${GREEN}=== Deployment Verification ===${NC}"
echo ""
ERRORS=0
# Check services
echo "Checking services..."
for service in explorer-indexer explorer-api explorer-frontend nginx postgresql; do
if systemctl is-active --quiet $service; then
echo -e "${GREEN}${NC} $service is running"
else
echo -e "${RED}${NC} $service is not running"
ERRORS=$((ERRORS + 1))
fi
done
# Check API
echo ""
echo "Checking API..."
if curl -s http://localhost:8080/health | grep -q "healthy"; then
echo -e "${GREEN}${NC} API is healthy"
else
echo -e "${RED}${NC} API health check failed"
ERRORS=$((ERRORS + 1))
fi
# Check Frontend
echo ""
echo "Checking Frontend..."
if curl -s http://localhost:3000 | grep -q "Explorer"; then
echo -e "${GREEN}${NC} Frontend is responding"
else
echo -e "${RED}${NC} Frontend check failed"
ERRORS=$((ERRORS + 1))
fi
# Check Nginx
echo ""
echo "Checking Nginx..."
if curl -s http://localhost/api/health | grep -q "healthy"; then
echo -e "${GREEN}${NC} Nginx proxy is working"
else
echo -e "${RED}${NC} Nginx proxy check failed"
ERRORS=$((ERRORS + 1))
fi
# Check Database
echo ""
echo "Checking Database..."
if sudo -u postgres psql -d explorer -c "SELECT 1;" > /dev/null 2>&1; then
echo -e "${GREEN}${NC} Database is accessible"
else
echo -e "${RED}${NC} Database check failed"
ERRORS=$((ERRORS + 1))
fi
# Check Elasticsearch
echo ""
echo "Checking Elasticsearch..."
if curl -s http://localhost:9200 | grep -q "cluster_name"; then
echo -e "${GREEN}${NC} Elasticsearch is running"
else
echo -e "${YELLOW}${NC} Elasticsearch check failed (may not be critical)"
fi
# Check Redis
echo ""
echo "Checking Redis..."
if redis-cli ping 2>/dev/null | grep -q "PONG"; then
echo -e "${GREEN}${NC} Redis is running"
else
echo -e "${YELLOW}${NC} Redis check failed (may not be critical)"
fi
# Check Cloudflare Tunnel (if installed)
echo ""
echo "Checking Cloudflare Tunnel..."
if systemctl is-active --quiet cloudflared 2>/dev/null; then
echo -e "${GREEN}${NC} Cloudflare Tunnel is running"
else
echo -e "${YELLOW}${NC} Cloudflare Tunnel not running (optional)"
fi
# Summary
echo ""
if [ $ERRORS -eq 0 ]; then
echo -e "${GREEN}✓ All critical checks passed!${NC}"
exit 0
else
echo -e "${RED}$ERRORS critical check(s) failed${NC}"
exit 1
fi