chore: full stack stability and migration fixes, plus react UI progress
Some checks failed
CI / podman-build (push) Has been cancelled
CI / rust (push) Has been cancelled

This commit is contained in:
2026-03-18 09:01:38 +02:00
parent 38cab8c246
commit a66d908eff
142 changed files with 12210 additions and 3402 deletions

View File

@@ -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
View 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"

View 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!"

View 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';