Add phase3-karakeep.sh migration script
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
8198980db1
commit
79c76accfb
1 changed files with 412 additions and 0 deletions
412
migration/phase3-karakeep.sh
Executable file
412
migration/phase3-karakeep.sh
Executable file
|
|
@ -0,0 +1,412 @@
|
||||||
|
#!/bin/bash
|
||||||
|
# =============================================================================
|
||||||
|
# Phase 3 Migration: Karakeep Stack
|
||||||
|
# Target: databases (.81)
|
||||||
|
# Services: karakeep-web, meilisearch, chrome, ollama (4 containers)
|
||||||
|
# Run this on the control server (CT 127)
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
COMPOSE_DIR=~/clustered-fucks/compose-files/databases/karakeep
|
||||||
|
PLAYBOOK_DIR=~/clustered-fucks/playbooks
|
||||||
|
|
||||||
|
echo "========================================"
|
||||||
|
echo "Phase 3: Karakeep Stack Migration"
|
||||||
|
echo "Target: databases (192.168.1.81)"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Create directories
|
||||||
|
mkdir -p "$COMPOSE_DIR"
|
||||||
|
mkdir -p "$PLAYBOOK_DIR"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# KARAKEEP DOCKER-COMPOSE
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
echo "Creating Karakeep docker-compose.yml..."
|
||||||
|
|
||||||
|
cat > "$COMPOSE_DIR/docker-compose.yml" << 'EOF'
|
||||||
|
services:
|
||||||
|
# =========================================================================
|
||||||
|
# Karakeep Web - Main application
|
||||||
|
# =========================================================================
|
||||||
|
web:
|
||||||
|
image: ghcr.io/karakeep-app/karakeep:${KARAKEEP_VERSION:-release}
|
||||||
|
container_name: karakeep-web
|
||||||
|
hostname: karakeep-web
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./data:/data
|
||||||
|
ports:
|
||||||
|
- "3054:3000"
|
||||||
|
environment:
|
||||||
|
- DATA_DIR=/data
|
||||||
|
- MEILI_ADDR=http://meilisearch:7700
|
||||||
|
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
|
||||||
|
- BROWSER_WEB_URL=http://chrome:9222
|
||||||
|
- OLLAMA_BASE_URL=http://ollama:11434
|
||||||
|
- INFERENCE_TEXT_MODEL=${INFERENCE_TEXT_MODEL:-llama3.2:3b}
|
||||||
|
- INFERENCE_IMAGE_MODEL=${INFERENCE_IMAGE_MODEL:-llava}
|
||||||
|
- INFERENCE_LANG=${INFERENCE_LANG:-english}
|
||||||
|
- NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000}
|
||||||
|
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET}
|
||||||
|
- NODE_ENV=production
|
||||||
|
- NEXT_TELEMETRY_DISABLED=1
|
||||||
|
depends_on:
|
||||||
|
meilisearch:
|
||||||
|
condition: service_started
|
||||||
|
chrome:
|
||||||
|
condition: service_started
|
||||||
|
ollama:
|
||||||
|
condition: service_started
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
- proxy
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 1G
|
||||||
|
cpus: '2.0'
|
||||||
|
healthcheck:
|
||||||
|
test: ["CMD-SHELL", "wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/api/health || exit 1"]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 3
|
||||||
|
start_period: 30s
|
||||||
|
labels:
|
||||||
|
- "autoheal=true"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
- "homepage.group=Personal"
|
||||||
|
- "homepage.name=Karakeep"
|
||||||
|
- "homepage.icon=karakeep.png"
|
||||||
|
- "homepage.href=https://karakeep.3ddbrewery.com"
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Meilisearch - Full-text search engine
|
||||||
|
# =========================================================================
|
||||||
|
meilisearch:
|
||||||
|
image: getmeili/meilisearch:v1.13.3
|
||||||
|
container_name: karakeep-meilisearch
|
||||||
|
hostname: meilisearch
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./meilisearch:/meili_data
|
||||||
|
ports:
|
||||||
|
- "7700:7700"
|
||||||
|
environment:
|
||||||
|
- MEILI_NO_ANALYTICS=true
|
||||||
|
- MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 1G
|
||||||
|
cpus: '1.0'
|
||||||
|
labels:
|
||||||
|
- "autoheal=true"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Chrome - Headless browser for screenshots/crawling
|
||||||
|
# =========================================================================
|
||||||
|
chrome:
|
||||||
|
image: gcr.io/zenika-hub/alpine-chrome:123
|
||||||
|
container_name: karakeep-chrome
|
||||||
|
hostname: chrome
|
||||||
|
restart: unless-stopped
|
||||||
|
command:
|
||||||
|
- --no-sandbox
|
||||||
|
- --disable-gpu
|
||||||
|
- --disable-dev-shm-usage
|
||||||
|
- --remote-debugging-address=0.0.0.0
|
||||||
|
- --remote-debugging-port=9222
|
||||||
|
- --hide-scrollbars
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
memory: 512M
|
||||||
|
cpus: '1.0'
|
||||||
|
labels:
|
||||||
|
- "autoheal=true"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# Ollama - Local AI inference (CPU-only on databases VM)
|
||||||
|
# =========================================================================
|
||||||
|
ollama:
|
||||||
|
image: ollama/ollama:latest
|
||||||
|
container_name: karakeep-ollama
|
||||||
|
hostname: ollama
|
||||||
|
restart: unless-stopped
|
||||||
|
volumes:
|
||||||
|
- ./ollama:/root/.ollama
|
||||||
|
ports:
|
||||||
|
- "11434:11434"
|
||||||
|
environment:
|
||||||
|
- OLLAMA_HOST=0.0.0.0:11434
|
||||||
|
networks:
|
||||||
|
- karakeep_internal
|
||||||
|
deploy:
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
# Ollama needs more memory for models
|
||||||
|
memory: 4G
|
||||||
|
cpus: '4.0'
|
||||||
|
labels:
|
||||||
|
- "autoheal=true"
|
||||||
|
- "com.centurylinklabs.watchtower.enable=true"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
karakeep_internal:
|
||||||
|
driver: bridge
|
||||||
|
proxy:
|
||||||
|
external: true
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✅ Created $COMPOSE_DIR/docker-compose.yml"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ENVIRONMENT FILE TEMPLATE
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
echo "Creating .env template..."
|
||||||
|
|
||||||
|
cat > "$COMPOSE_DIR/.env.example" << 'EOF'
|
||||||
|
# Karakeep Environment Variables
|
||||||
|
# Copy to .env and fill in the secrets
|
||||||
|
|
||||||
|
# Version
|
||||||
|
KARAKEEP_VERSION=release
|
||||||
|
|
||||||
|
# Meilisearch
|
||||||
|
MEILI_MASTER_KEY=your-meilisearch-master-key-here
|
||||||
|
|
||||||
|
# NextAuth
|
||||||
|
NEXTAUTH_URL=https://karakeep.3ddbrewery.com
|
||||||
|
NEXTAUTH_SECRET=your-nextauth-secret-here
|
||||||
|
|
||||||
|
# AI Models
|
||||||
|
INFERENCE_TEXT_MODEL=llama3.2:3b
|
||||||
|
INFERENCE_IMAGE_MODEL=llava
|
||||||
|
INFERENCE_LANG=english
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✅ Created $COMPOSE_DIR/.env.example"
|
||||||
|
|
||||||
|
# =============================================================================
|
||||||
|
# ANSIBLE PLAYBOOK
|
||||||
|
# =============================================================================
|
||||||
|
|
||||||
|
echo "Creating Ansible playbook..."
|
||||||
|
|
||||||
|
cat > "$PLAYBOOK_DIR/deploy-karakeep.yml" << 'EOF'
|
||||||
|
---
|
||||||
|
# Deploy Karakeep Stack to databases VM
|
||||||
|
# Containers: web, meilisearch, chrome, ollama
|
||||||
|
# Target: databases (192.168.1.81)
|
||||||
|
|
||||||
|
- name: Deploy Karakeep Stack
|
||||||
|
hosts: databases
|
||||||
|
vars:
|
||||||
|
appdata_path: /home/docker/appdata
|
||||||
|
service_name: karakeep
|
||||||
|
service_dir: "{{ appdata_path }}/{{ service_name }}"
|
||||||
|
compose_src: "{{ playbook_dir }}/../compose-files/databases/{{ service_name }}"
|
||||||
|
|
||||||
|
tasks:
|
||||||
|
# =========================================================================
|
||||||
|
# PRE-FLIGHT CHECKS
|
||||||
|
# =========================================================================
|
||||||
|
- name: Check if .env file exists on control server
|
||||||
|
delegate_to: localhost
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ compose_src }}/.env"
|
||||||
|
register: env_file
|
||||||
|
|
||||||
|
- name: Fail if .env is missing
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: |
|
||||||
|
.env file not found at {{ compose_src }}/.env
|
||||||
|
Copy .env.example to .env and fill in the secrets!
|
||||||
|
when: not env_file.stat.exists
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# DIRECTORY SETUP
|
||||||
|
# =========================================================================
|
||||||
|
- name: Create karakeep base directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ service_dir }}"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create karakeep data directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ service_dir }}/data"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create meilisearch directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ service_dir }}/meilisearch"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
- name: Create ollama directory
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ service_dir }}/ollama"
|
||||||
|
state: directory
|
||||||
|
mode: '0755'
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# FILE DEPLOYMENT
|
||||||
|
# =========================================================================
|
||||||
|
- name: Copy docker-compose.yml
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ compose_src }}/docker-compose.yml"
|
||||||
|
dest: "{{ service_dir }}/docker-compose.yml"
|
||||||
|
mode: '0644'
|
||||||
|
|
||||||
|
- name: Copy .env file
|
||||||
|
ansible.builtin.copy:
|
||||||
|
src: "{{ compose_src }}/.env"
|
||||||
|
dest: "{{ service_dir }}/.env"
|
||||||
|
mode: '0600'
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# CONTAINER DEPLOYMENT
|
||||||
|
# =========================================================================
|
||||||
|
- name: Deploy karakeep stack
|
||||||
|
community.docker.docker_compose_v2:
|
||||||
|
project_src: "{{ service_dir }}"
|
||||||
|
state: present
|
||||||
|
pull: always
|
||||||
|
register: karakeep_result
|
||||||
|
|
||||||
|
- name: Show deployment status
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "Karakeep stack deployed: {{ karakeep_result.changed }}"
|
||||||
|
|
||||||
|
# =========================================================================
|
||||||
|
# VERIFICATION
|
||||||
|
# =========================================================================
|
||||||
|
- name: Wait for karakeep-web to be healthy
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "http://localhost:3054/api/health"
|
||||||
|
status_code: 200
|
||||||
|
timeout: 10
|
||||||
|
register: web_health
|
||||||
|
retries: 15
|
||||||
|
delay: 10
|
||||||
|
until: web_health.status == 200
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Wait for meilisearch to be ready
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "http://localhost:7700/health"
|
||||||
|
status_code: 200
|
||||||
|
timeout: 5
|
||||||
|
register: meili_health
|
||||||
|
retries: 10
|
||||||
|
delay: 5
|
||||||
|
until: meili_health.status == 200
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Wait for ollama to be ready
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "http://localhost:11434/api/version"
|
||||||
|
status_code: 200
|
||||||
|
timeout: 5
|
||||||
|
register: ollama_health
|
||||||
|
retries: 10
|
||||||
|
delay: 5
|
||||||
|
until: ollama_health.status == 200
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Summary
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg:
|
||||||
|
- "========================================="
|
||||||
|
- "Karakeep Stack Deployment Complete"
|
||||||
|
- "========================================="
|
||||||
|
- "✅ Karakeep Web: http://192.168.1.81:3054"
|
||||||
|
- "✅ Meilisearch: http://192.168.1.81:7700"
|
||||||
|
- "✅ Ollama: http://192.168.1.81:11434"
|
||||||
|
- "========================================="
|
||||||
|
- "NOTE: Ollama running on CPU only (no GPU)"
|
||||||
|
- "Models may need to be re-pulled after migration"
|
||||||
|
EOF
|
||||||
|
|
||||||
|
echo "✅ Created $PLAYBOOK_DIR/deploy-karakeep.yml"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo "FILES CREATED"
|
||||||
|
echo "========================================"
|
||||||
|
echo " $COMPOSE_DIR/docker-compose.yml"
|
||||||
|
echo " $COMPOSE_DIR/.env.example"
|
||||||
|
echo " $PLAYBOOK_DIR/deploy-karakeep.yml"
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo "NEXT STEPS"
|
||||||
|
echo "========================================"
|
||||||
|
echo ""
|
||||||
|
echo "1. GET SECRETS from alien .env file:"
|
||||||
|
echo " ssh alien 'cat /home/maddox/docker/appdata/karakeep/.env'"
|
||||||
|
echo ""
|
||||||
|
echo "2. CREATE .env file with secrets:"
|
||||||
|
echo " cp $COMPOSE_DIR/.env.example $COMPOSE_DIR/.env"
|
||||||
|
echo " nano $COMPOSE_DIR/.env"
|
||||||
|
echo ""
|
||||||
|
echo "3. STOP OLD CONTAINERS on alien:"
|
||||||
|
echo " ssh alien 'cd /home/maddox/docker/appdata/karakeep && docker compose down'"
|
||||||
|
echo ""
|
||||||
|
echo "4. CREATE TARGET DIRECTORIES on databases:"
|
||||||
|
echo " ssh databases 'mkdir -p /home/docker/appdata/karakeep/{data,meilisearch,ollama}'"
|
||||||
|
echo ""
|
||||||
|
echo "5. RSYNC DATA (run FROM databases):"
|
||||||
|
echo " ssh databases"
|
||||||
|
echo " # Main karakeep data"
|
||||||
|
echo " rsync -avP maddox@alien:/home/maddox/docker/appdata/karakeep/ /home/docker/appdata/karakeep/"
|
||||||
|
echo ""
|
||||||
|
echo " If permission denied, first run on alien:"
|
||||||
|
echo " ssh alien 'sudo chown -R maddox:maddox /home/maddox/docker/appdata/karakeep/'"
|
||||||
|
echo ""
|
||||||
|
echo "6. DEPLOY to databases:"
|
||||||
|
echo " ansible-playbook playbooks/deploy-karakeep.yml"
|
||||||
|
echo ""
|
||||||
|
echo "7. VERIFY services:"
|
||||||
|
echo " curl http://192.168.1.81:3054/api/health # Karakeep"
|
||||||
|
echo " curl http://192.168.1.81:7700/health # Meilisearch"
|
||||||
|
echo " curl http://192.168.1.81:11434/api/version # Ollama"
|
||||||
|
echo ""
|
||||||
|
echo "8. UPDATE TRAEFIK config:"
|
||||||
|
echo " Change karakeep backend IP from alien to databases (192.168.1.81:3054)"
|
||||||
|
echo ""
|
||||||
|
echo "9. CLEANUP alien:"
|
||||||
|
echo " ssh alien 'cd /home/maddox/docker/appdata/karakeep && docker compose rm -f'"
|
||||||
|
echo ""
|
||||||
|
echo "10. COMMIT changes:"
|
||||||
|
echo " cd ~/clustered-fucks"
|
||||||
|
echo " git add -A"
|
||||||
|
echo " git commit -m 'Phase 3: Deploy karakeep stack to databases'"
|
||||||
|
echo " git push"
|
||||||
|
echo ""
|
||||||
|
echo "========================================"
|
||||||
|
echo "IMPORTANT NOTES"
|
||||||
|
echo "========================================"
|
||||||
|
echo "- Karakeep has stateful data in:"
|
||||||
|
echo " - /data (bookmarks, assets)"
|
||||||
|
echo " - /meilisearch (search index)"
|
||||||
|
echo " - /ollama (AI models)"
|
||||||
|
echo ""
|
||||||
|
echo "- Ollama on databases runs CPU-ONLY (no GPU)"
|
||||||
|
echo " - AI tagging will be slower than on alien"
|
||||||
|
echo " - Models (llama3.2:3b, llava) need to be present"
|
||||||
|
echo ""
|
||||||
|
echo "- Consider moving ollama to pve-alien later for GPU acceleration"
|
||||||
|
echo ""
|
||||||
Loading…
Reference in a new issue