chore: full stack stability and migration fixes, plus react UI progress
This commit is contained in:
@@ -3,10 +3,10 @@
|
||||
|
||||
set -e
|
||||
|
||||
SERVER1_IP="10.0.0.1"
|
||||
SERVER2_IP="10.0.0.2"
|
||||
SERVER3_IP="10.0.0.3"
|
||||
SERVER4_IP="10.0.0.4"
|
||||
SERVER1_IP="10.0.1.1" # Manually override these if not using Terraform
|
||||
SERVER2_IP="10.0.1.2"
|
||||
SERVER3_IP="10.0.1.3"
|
||||
SERVER4_IP="10.0.1.4"
|
||||
DEPLOY_PATH="/opt/madbase"
|
||||
|
||||
echo "🚀 Deploying MadBase 4-Server Architecture..."
|
||||
@@ -22,9 +22,13 @@ deploy_to_server() {
|
||||
|
||||
if [ -n "$env_file" ]; then
|
||||
scp $env_file root@$server_ip:$DEPLOY_PATH/.env
|
||||
ssh root@$server_ip "echo 'SERVER1_IP=10.0.1.1' >> $DEPLOY_PATH/.env"
|
||||
ssh root@$server_ip "echo 'SERVER2_IP=10.0.1.2' >> $DEPLOY_PATH/.env"
|
||||
ssh root@$server_ip "echo 'SERVER3_IP=10.0.1.3' >> $DEPLOY_PATH/.env"
|
||||
ssh root@$server_ip "echo 'SERVER4_IP=10.0.1.4' >> $DEPLOY_PATH/.env"
|
||||
fi
|
||||
|
||||
if [[ "$server_ip" =~ (10.0.0.2|10.0.0.3|10.0.0.4) ]]; then
|
||||
if [[ "$server_ip" =~ (10.0.1.2|10.0.1.3|10.0.1.4) ]]; then
|
||||
scp autobase-haproxy.cfg root@$server_ip:$DEPLOY_PATH/
|
||||
fi
|
||||
|
||||
@@ -32,44 +36,38 @@ deploy_to_server() {
|
||||
echo "✅ Files copied to $server_ip"
|
||||
}
|
||||
|
||||
echo "📡 Server 1: Control Plane"
|
||||
deploy_to_server $SERVER1_IP "docker-compose.4server.server1.yml" ""
|
||||
echo "📡 Server 1: Control Plane & Monitoring"
|
||||
deploy_to_server $SERVER1_IP "deploy/hetzner/server1.compose.yml" ".env"
|
||||
scp prometheus.yml root@$SERVER1_IP:$DEPLOY_PATH/
|
||||
echo ""
|
||||
|
||||
echo "🗄️ Server 2: Worker 1 + Autobase Node 1"
|
||||
deploy_to_server $SERVER2_IP "docker-compose.4server.server2.yml" "env/autobase.4server.server2.env"
|
||||
echo "🗄️ Server 2: Pillar Node 1 (DB + Worker + HAProxy)"
|
||||
deploy_to_server $SERVER2_IP "deploy/hetzner/server2.compose.yml" ".env"
|
||||
echo ""
|
||||
|
||||
echo "📊 Server 3: Workers 3,4 + Autobase Node 2"
|
||||
deploy_to_server $SERVER3_IP "docker-compose.4server.server3.yml" "env/autobase.4server.server3.env"
|
||||
echo "📊 Server 3: Pillar Node 2 (DB + Worker + Redis)"
|
||||
deploy_to_server $SERVER3_IP "deploy/hetzner/server3.compose.yml" ".env"
|
||||
echo ""
|
||||
|
||||
echo "🗄️ Server 4: Worker 5 + Autobase Node 3"
|
||||
deploy_to_server $SERVER4_IP "docker-compose.4server.server4.yml" "env/autobase.4server.server4.env"
|
||||
echo "🗄️ Server 4: Pillar Node 3 (DB + Worker)"
|
||||
deploy_to_server $SERVER4_IP "deploy/hetzner/server4.compose.yml" ".env"
|
||||
echo ""
|
||||
|
||||
echo "🔄 Starting Autobase cluster..."
|
||||
for server in $SERVER2_IP $SERVER3_IP $SERVER4_IP; do
|
||||
ssh root@$server "cd $DEPLOY_PATH && podman-compose up -d etcd patroni haproxy"
|
||||
echo "🛠️ Installing Systemd Self-Healing..."
|
||||
for server in $SERVER1_IP $SERVER2_IP $SERVER3_IP $SERVER4_IP; do
|
||||
scp deploy/hetzner/madbase.service root@$server:/etc/systemd/system/
|
||||
ssh root@$server "systemctl daemon-reload && systemctl enable madbase && systemctl restart madbase"
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo "⏳ Waiting for etcd cluster (30s)..."
|
||||
sleep 30
|
||||
|
||||
echo "🔍 Verifying Autobase cluster..."
|
||||
echo "🔍 Verifying Patroni cluster..."
|
||||
for server in $SERVER2_IP $SERVER3_IP $SERVER4_IP; do
|
||||
state=$(curl -s http://$server:8008/patroni/info | jq -r '.state // "unknown"')
|
||||
role=$(curl -s http://$server:8008/patroni/info | jq -r '.role // "unknown"')
|
||||
echo " $server: $state ($role)"
|
||||
role=$(curl -s http://$server:8008/patroni/role | jq -r '.' || echo "unknown")
|
||||
echo " $server role: $role"
|
||||
done
|
||||
echo ""
|
||||
|
||||
echo "🚀 Starting application services..."
|
||||
ssh root@$SERVER1_IP "cd $DEPLOY_PATH && podman-compose up -d"
|
||||
ssh root@$SERVER2_IP "cd $DEPLOY_PATH && podman-compose up -d worker1"
|
||||
ssh root@$SERVER3_IP "cd $DEPLOY_PATH && podman-compose up -d worker3 worker4 victoriametrics loki"
|
||||
ssh root@$SERVER4_IP "cd $DEPLOY_PATH && podman-compose up -d worker5"
|
||||
|
||||
echo ""
|
||||
echo "🎉 Deployment complete!"
|
||||
echo "🎉 Deployment complete and self-healing enabled!"
|
||||
|
||||
79
scripts/generate_jwt_keys.sh
Executable file
79
scripts/generate_jwt_keys.sh
Executable file
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Generating JWT keys from JWT_SECRET..."
|
||||
|
||||
# Load environment variables
|
||||
if [ -f .env ]; then
|
||||
export $(cat .env | grep -v '^#' | xargs)
|
||||
else
|
||||
echo "Error: .env file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate required environment variable
|
||||
if [ -z "$JWT_SECRET" ]; then
|
||||
echo "Error: JWT_SECRET not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using JWT_SECRET (first 8 chars): ${JWT_SECRET:0:8}..."
|
||||
echo "Using JWT_ISSUER: ${JWT_ISSUER:-madbase}..."
|
||||
|
||||
# Create a temporary TypeScript script to generate keys
|
||||
cat > /tmp/generate_keys.ts << 'EOF'
|
||||
import jwt from 'jsonwebtoken';
|
||||
|
||||
const secret = process.env.JWT_SECRET || '';
|
||||
const issuer = process.env.JWT_ISSUER || 'madbase';
|
||||
|
||||
if (!secret) {
|
||||
console.error('JWT_SECRET not provided');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const exp = Math.floor(Date.now() / 1000) + 60 * 60 * 24 * 7; // 7 days from now
|
||||
|
||||
const anonPayload = {
|
||||
sub: 'anon',
|
||||
role: 'anon',
|
||||
iss: issuer,
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: exp
|
||||
};
|
||||
|
||||
const servicePayload = {
|
||||
sub: 'service_role',
|
||||
role: 'service_role',
|
||||
iss: issuer,
|
||||
iat: Math.floor(Date.now() / 1000),
|
||||
exp: exp
|
||||
};
|
||||
|
||||
const anonKey = jwt.sign(anonPayload, secret, { algorithm: 'HS256' });
|
||||
const serviceKey = jwt.sign(servicePayload, secret, { algorithm: 'HS256' });
|
||||
|
||||
console.log('Generated Keys:');
|
||||
console.log(`MADBASE_ANON_KEY=${anonKey}`);
|
||||
console.log(`MADBASE_SERVICE_ROLE_KEY=${serviceKey}`);
|
||||
EOF
|
||||
|
||||
# Run the script using ts-node or node
|
||||
if command -v tsx &> /dev/null; then
|
||||
JWT_SECRET="$JWT_SECRET" JWT_ISSUER="${JWT_ISSUER:-madbase}" tsx /tmp/generate_keys.ts
|
||||
elif command -v ts-node &> /dev/null; then
|
||||
JWT_SECRET="$JWT_SECRET" JWT_ISSUER="${JWT_ISSUER:-madbase}" ts-node /tmp/generate_keys.ts
|
||||
else
|
||||
echo "Error: tsx or ts-node not found. Please install one of them:"
|
||||
echo " npm install -g tsx"
|
||||
echo " npm install -g ts-node"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Clean up
|
||||
rm /tmp/generate_keys.ts
|
||||
|
||||
echo ""
|
||||
echo "To update your .env file with these keys, run:"
|
||||
echo " scripts/generate_jwt_keys.sh | grep 'MADBASE_ANON_KEY=' | cut -d'=' -f2- | xargs -I {} sed -i '' 's/^MADBASE_ANON_KEY=.*/MADBASE_ANON_KEY={}/' .env"
|
||||
echo " scripts/generate_jwt_keys.sh | grep 'MADBASE_SERVICE_ROLE_KEY=' | cut -d'=' -f2- | xargs -I {} sed -i '' 's/^MADBASE_SERVICE_ROLE_KEY=.*/MADBASE_SERVICE_ROLE_KEY={}/' .env"
|
||||
61
scripts/setup_default_project.sh
Executable file
61
scripts/setup_default_project.sh
Executable file
@@ -0,0 +1,61 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
echo "Setting up default project in database..."
|
||||
|
||||
# Load environment variables
|
||||
if [ -f .env ]; then
|
||||
export $(cat .env | grep -v '^#' | xargs)
|
||||
else
|
||||
echo "Error: .env file not found"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Validate required environment variables
|
||||
if [ -z "$JWT_SECRET" ]; then
|
||||
echo "Error: JWT_SECRET not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$MADBASE_ANON_KEY" ]; then
|
||||
echo "Error: MADBASE_ANON_KEY not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$MADBASE_SERVICE_ROLE_KEY" ]; then
|
||||
echo "Error: MADBASE_SERVICE_ROLE_KEY not set"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Using JWT_SECRET (first 8 chars): ${JWT_SECRET:0:8}..."
|
||||
echo "Using JWT_ISSUER: ${JWT_ISSUER:-madbase}..."
|
||||
|
||||
# Connect to the control database and update the default project
|
||||
psql "${DATABASE_URL:-postgres://postgres:postgres@localhost:5432/postgres}" << EOF
|
||||
-- Update existing default project or insert if not exists
|
||||
INSERT INTO projects (name, jwt_secret, anon_key, service_role_key, created_at, updated_at)
|
||||
VALUES (
|
||||
'default',
|
||||
'$JWT_SECRET',
|
||||
'$MADBASE_ANON_KEY',
|
||||
'$MADBASE_SERVICE_ROLE_KEY',
|
||||
NOW(),
|
||||
NOW()
|
||||
)
|
||||
ON CONFLICT (name) DO UPDATE SET
|
||||
jwt_secret = EXCLUDED.jwt_secret,
|
||||
anon_key = EXCLUDED.anon_key,
|
||||
service_role_key = EXCLUDED.service_role_key,
|
||||
updated_at = NOW();
|
||||
|
||||
-- Verify the update
|
||||
SELECT name,
|
||||
substring(jwt_secret, 1, 8) || '...' as jwt_secret_preview,
|
||||
substring(anon_key, 1, 20) || '...' as anon_key_preview,
|
||||
substring(service_role_key, 1, 20) || '...' as service_role_key_preview
|
||||
FROM projects
|
||||
WHERE name = 'default';
|
||||
|
||||
EOF
|
||||
|
||||
echo "Default project setup complete!"
|
||||
26
scripts/setup_default_project.sql
Normal file
26
scripts/setup_default_project.sql
Normal file
@@ -0,0 +1,26 @@
|
||||
-- Setup default project with environment variables
|
||||
-- This script should be run after setting up the database
|
||||
|
||||
-- Update existing default project or insert if not exists
|
||||
INSERT INTO projects (name, jwt_secret, anon_key, service_role_key, created_at, updated_at)
|
||||
VALUES (
|
||||
'default',
|
||||
:'JWT_SECRET',
|
||||
:'MADBASE_ANON_KEY',
|
||||
:'MADBASE_SERVICE_ROLE_KEY',
|
||||
NOW(),
|
||||
NOW()
|
||||
)
|
||||
ON CONFLICT (name) DO UPDATE SET
|
||||
jwt_secret = EXCLUDED.jwt_secret,
|
||||
anon_key = EXCLUDED.anon_key,
|
||||
service_role_key = EXCLUDED.service_role_key,
|
||||
updated_at = NOW();
|
||||
|
||||
-- Verify the update
|
||||
SELECT name,
|
||||
substring(jwt_secret, 1, 8) || '...' as jwt_secret_preview,
|
||||
substring(anon_key, 1, 20) || '...' as anon_key_preview,
|
||||
substring(service_role_key, 1, 20) || '...' as service_role_key_preview
|
||||
FROM projects
|
||||
WHERE name = 'default';
|
||||
Reference in New Issue
Block a user