383 lines
12 KiB
Bash
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}"
|