jarvis-assist/Claude outputs/deploy-jarvis.sh

383 lines
12 KiB
Bash

#!/bin/bash
set -e
echo "🤖 ============ JARVIS FULL DEPLOYMENT ============"
echo ""
# ============ COLORS ============
GREEN='\033[0;32m'
BLUE='\033[0;34m'
YELLOW='\033[1;33m'
RED='\033[0;31m'
NC='\033[0m'
# ============ CONFIGURATION ============
DOMAIN="${1:-jarvis.local}"
JARVIS_HOME="/home/jarvis-core/jarvis"
echo -e "${BLUE}📍 Setup Directory: $JARVIS_HOME${NC}"
echo -e "${BLUE}📍 Domain: $DOMAIN${NC}"
echo ""
# ============ 1. SYSTEM UPDATE ============
echo -e "${YELLOW}[1/9] System Update...${NC}"
sudo apt-get update -qq
sudo apt-get upgrade -y -qq
sudo apt-get install -y -qq curl wget git htop net-tools openssl python3-pip > /dev/null 2>&1
echo -e "${GREEN}✅ System updated${NC}"
# ============ 2. DOCKER INSTALLATION ============
echo -e "${YELLOW}[2/9] Installing Docker...${NC}"
if ! command -v docker &> /dev/null; then
curl -fsSL https://get.docker.com -o get-docker.sh > /dev/null 2>&1
bash get-docker.sh > /dev/null 2>&1
rm -f get-docker.sh
sudo usermod -aG docker jarvis-core
echo -e "${GREEN}✅ Docker installed${NC}"
else
echo -e "${GREEN}✅ Docker already installed${NC}"
fi
# ============ 3. DOCKER COMPOSE ============
echo -e "${YELLOW}[3/9] Installing Docker Compose...${NC}"
if ! command -v docker-compose &> /dev/null; then
COMPOSE_VERSION=$(curl -s https://api.github.com/repos/docker/compose/releases/latest | grep 'tag_name' | cut -d'"' -f4)
sudo curl -L "https://github.com/docker/compose/releases/download/${COMPOSE_VERSION}/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose > /dev/null 2>&1
sudo chmod +x /usr/local/bin/docker-compose
echo -e "${GREEN}✅ Docker Compose installed${NC}"
else
echo -e "${GREEN}✅ Docker Compose already installed${NC}"
fi
# ============ 4. PROJECT STRUCTURE ============
echo -e "${YELLOW}[4/9] Creating project structure...${NC}"
mkdir -p $JARVIS_HOME/{config,data,logs,api,web}
cd $JARVIS_HOME
mkdir -p data/{postgres,redis,milvus,etcd,ollama,n8n}
mkdir -p logs/{api,n8n,nginx}
echo -e "${GREEN}✅ Project structure created${NC}"
# ============ 5. DOCKER NETWORK ============
echo -e "${YELLOW}[5/9] Creating Docker network...${NC}"
docker network create jarvis-net 2>/dev/null || true
echo -e "${GREEN}✅ Docker network ready${NC}"
# ============ 6. DOCKER-COMPOSE.YML ============
echo -e "${YELLOW}[6/9] Writing docker-compose.yml...${NC}"
cat > docker-compose.yml << 'EOF'
version: '3.9'
services:
traefik:
image: traefik:v2.10
container_name: jarvis-traefik
command:
- "--api.insecure=true"
- "--providers.docker=true"
- "--providers.docker.exposedbydefault=false"
- "--entrypoints.web.address=:80"
- "--entrypoints.websecure.address=:443"
ports:
- "80:80"
- "443:443"
- "8080:8080"
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
networks:
- jarvis-net
restart: unless-stopped
postgres:
image: postgres:16-alpine
container_name: jarvis-postgres
environment:
POSTGRES_DB: jarvis
POSTGRES_USER: jarvis
POSTGRES_PASSWORD: ${DB_PASSWORD:-ChangeMe123!}
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-db.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
networks:
- jarvis-net
healthcheck:
test: ["CMD-SHELL", "pg_isready -U jarvis"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
redis:
image: redis:7-alpine
container_name: jarvis-redis
command: redis-server --appendonly yes
volumes:
- redis_data:/data
ports:
- "6379:6379"
networks:
- jarvis-net
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
restart: unless-stopped
milvus:
image: milvusdb/milvus:v0.4.0
container_name: jarvis-milvus
environment:
ETCD_ENDPOINTS: etcd:2379
COMMON_STORAGETYPE: local
volumes:
- milvus_data:/var/lib/milvus
ports:
- "19530:19530"
- "9091:9091"
depends_on:
etcd:
condition: service_healthy
networks:
- jarvis-net
restart: unless-stopped
etcd:
image: quay.io/coreos/etcd:v3.5.5
container_name: jarvis-etcd
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
- ETCD_AUTO_COMPACTION_RETENTION=1000
- ETCD_QUOTA_BACKEND_BYTES=4294967296
volumes:
- etcd_data:/etcd
ports:
- "2379:2379"
networks:
- jarvis-net
healthcheck:
test: ["CMD", "etcdctl", "endpoint", "health"]
interval: 10s
timeout: 5s
retries: 5
command: etcd -advertise-client-urls=http://127.0.0.1:2379 -listen-client-urls http://0.0.0.0:2379 --data-dir /etcd
restart: unless-stopped
ollama:
image: ollama/ollama:latest
container_name: jarvis-ollama
environment:
- OLLAMA_HOST=0.0.0.0:11434
volumes:
- ollama_data:/root/.ollama
ports:
- "11434:11434"
networks:
- jarvis-net
restart: unless-stopped
n8n:
image: n8n:latest
container_name: jarvis-n8n
environment:
- DB_TYPE=postgresdb
- DB_POSTGRESDB_HOST=postgres
- DB_POSTGRESDB_USER=jarvis
- DB_POSTGRESDB_PASSWORD=${DB_PASSWORD:-ChangeMe123!}
- DB_POSTGRESDB_DATABASE=n8n
- N8N_HOST=${DOMAIN:-localhost}
- N8N_PORT=5678
- WEBHOOK_TUNNEL_URL=http://n8n:5678/
- GENERIC_TIMEZONE=Europe/Berlin
volumes:
- n8n_data:/home/node/.n8n
ports:
- "5678:5678"
depends_on:
postgres:
condition: service_healthy
networks:
- jarvis-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.n8n.rule=Host(`n8n.${DOMAIN:-localhost}`)"
- "traefik.http.services.n8n.loadbalancer.server.port=5678"
restart: unless-stopped
jarvis-api:
image: python:3.11-slim
container_name: jarvis-api
working_dir: /app
command: >
bash -c "pip install -q -r requirements.txt &&
uvicorn main:app --host 0.0.0.0 --port 8000 --reload"
environment:
- DATABASE_URL=postgresql://jarvis:${DB_PASSWORD:-ChangeMe123!}@postgres:5432/jarvis
- REDIS_URL=redis://redis:6379
- MILVUS_HOST=milvus
- MILVUS_PORT=19530
- OLLAMA_HOST=http://ollama:11434
- CLAUDE_API_KEY=${CLAUDE_API_KEY:-}
- LOG_LEVEL=info
volumes:
- ./api:/app
ports:
- "8000:8000"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
networks:
- jarvis-net
labels:
- "traefik.enable=true"
- "traefik.http.routers.api.rule=Host(`api.${DOMAIN:-localhost}`)"
- "traefik.http.services.api.loadbalancer.server.port=8000"
restart: unless-stopped
networks:
jarvis-net:
driver: bridge
volumes:
postgres_data:
redis_data:
milvus_data:
etcd_data:
ollama_data:
n8n_data:
EOF
echo -e "${GREEN}✅ docker-compose.yml created${NC}"
# ============ 7. ENV FILE ============
echo -e "${YELLOW}[7/9] Creating .env file...${NC}"
cat > .env << EOF
DOMAIN=$DOMAIN
DB_PASSWORD=$(openssl rand -base64 32)
CLAUDE_API_KEY=
OLLAMA_MODEL=mistral
LOG_LEVEL=info
JWT_SECRET=$(openssl rand -base64 32)
API_KEY_ADMIN=$(openssl rand -base64 32)
N8N_ENCRYPTION_KEY=$(openssl rand -base64 32)
EOF
chmod 600 .env
echo -e "${GREEN}✅ .env created${NC}"
# ============ 8. DATABASE & API ============
echo -e "${YELLOW}[8/9] Creating database schema...${NC}"
cat > init-db.sql << 'EOF'
CREATE DATABASE jarvis;
CREATE DATABASE n8n;
\c jarvis;
CREATE TABLE users (id SERIAL PRIMARY KEY, username VARCHAR(255) UNIQUE NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, password_hash VARCHAR(255) NOT NULL, api_key VARCHAR(255) UNIQUE, role VARCHAR(50) DEFAULT 'user', is_active BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
CREATE TABLE conversations (id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, title VARCHAR(255), context JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
CREATE INDEX idx_conversations_user_id ON conversations(user_id);
CREATE TABLE messages (id SERIAL PRIMARY KEY, conversation_id INTEGER NOT NULL REFERENCES conversations(id) ON DELETE CASCADE, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, role VARCHAR(50) NOT NULL, content TEXT NOT NULL, tokens_used INTEGER, metadata JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
CREATE INDEX idx_messages_conversation_id ON messages(conversation_id);
CREATE TABLE tasks (id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, description TEXT, task_type VARCHAR(100), status VARCHAR(50) DEFAULT 'pending', priority INTEGER DEFAULT 0, data JSONB, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, completed_at TIMESTAMP);
CREATE INDEX idx_tasks_user_id ON tasks(user_id);
CREATE TABLE documents (id SERIAL PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, title VARCHAR(255) NOT NULL, content TEXT NOT NULL, document_type VARCHAR(100), metadata JSONB, embedding_id VARCHAR(255), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
INSERT INTO users (username, email, password_hash, role) VALUES ('admin', 'admin@jarvis.local', '$2b$12$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36WQoeG6Lruj3djPvga3jaK', 'admin') ON CONFLICT DO NOTHING;
EOF
# Create API directory and files
mkdir -p api
cat > api/requirements.txt << 'EOF'
fastapi==0.104.1
uvicorn[standard]==0.24.0
python-dotenv==1.0.0
pydantic==2.5.0
psycopg2-binary==2.9.9
redis==5.0.1
pymilvus==2.3.4
anthropic==0.14.0
aiohttp==3.9.1
requests==2.31.0
EOF
cat > api/main.py << 'EOF'
from fastapi import FastAPI
from datetime import datetime
import os
app = FastAPI(title="JARVIS API", version="0.1.0")
@app.get("/health")
async def health():
return {"status": "healthy", "timestamp": datetime.now()}
@app.get("/api/v1/admin/stats")
async def stats():
return {"status": "ok", "timestamp": datetime.now()}
@app.post("/api/v1/chat")
async def chat(message: str):
return {"response": f"Echo: {message}", "timestamp": datetime.now()}
if __name__ == "__main__":
import uvicorn
uvicorn.run(app, host="0.0.0.0", port=8000)
EOF
echo -e "${GREEN}✅ Database schema and API created${NC}"
# ============ 9. PERMISSIONS ============
echo -e "${YELLOW}[9/9] Setting permissions...${NC}"
sudo chown -R jarvis-core:jarvis-core $JARVIS_HOME
chmod -R 755 $JARVIS_HOME
chmod 600 .env
echo -e "${GREEN}✅ Permissions set${NC}"
# ============ DEPLOYMENT ============
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN}🚀 STARTING DOCKER CONTAINERS...${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
docker-compose up -d
echo ""
echo -e "${BLUE}Waiting for services to start... (30s)${NC}"
sleep 30
echo ""
echo -e "${GREEN}============================================${NC}"
echo -e "${GREEN}✅ JARVIS DEPLOYED SUCCESSFULLY!${NC}"
echo -e "${GREEN}============================================${NC}"
echo ""
echo -e "${BLUE}📍 Services:${NC}"
echo " 🌐 Web Dashboard: http://$DOMAIN:3000 (⏳ coming soon)"
echo " 📡 API: http://$DOMAIN:8000"
echo " 📡 API Docs: http://$DOMAIN:8000/docs"
echo " ⚙️ n8n: http://$DOMAIN:5678"
echo " 🔌 Traefik: http://$DOMAIN:8080"
echo ""
echo -e "${BLUE}📊 Database Access:${NC}"
echo " PostgreSQL: localhost:5432 (user: jarvis)"
echo " Redis: localhost:6379"
echo " Milvus: localhost:19530"
echo " Ollama: localhost:11434"
echo ""
echo -e "${BLUE}📝 Next steps:${NC}"
echo " 1. Edit .env - Add CLAUDE_API_KEY"
echo " 2. Restart API: docker-compose restart jarvis-api"
echo " 3. Check logs: docker-compose logs -f"
echo ""
echo -e "${YELLOW}⚠️ Important:${NC}"
echo " • Change default admin password in database"
echo " • Setup SSL/HTTPS in production"
echo " • Configure regular backups"
echo ""
# Status
echo -e "${BLUE}📊 Container Status:${NC}"
docker-compose ps
echo ""
echo -e "${GREEN}🎉 Ready to go! Start building with JARVIS!${NC}"