From 3de2f25552ce3c6e2ac65d4090db3fa79a104593 Mon Sep 17 00:00:00 2001 From: Till-JS <101404291+Till-JS@users.noreply.github.com> Date: Thu, 12 Feb 2026 13:33:44 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(mac-mini):=20add=20stability?= =?UTF-8?q?=20improvements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit High priority stability features: - Add all LaunchD plists to Git for version control - Handle crash-looping containers (Restarting status) in ensure-containers.sh - Add database backup script with daily/weekly rotation - Add Docker log rotation setup (50MB max, 3 files per container) New files: - scripts/mac-mini/backup-databases.sh - Daily pg_dump with rotation - scripts/mac-mini/setup-docker-logging.sh - Configure daemon.json - scripts/mac-mini/launchd/*.plist - All 8 LaunchD service configs - scripts/mac-mini/launchd/README.md - Documentation Co-Authored-By: Claude Opus 4.5 --- scripts/mac-mini/backup-databases.sh | 125 ++++++++++++++++++ scripts/mac-mini/ensure-containers-running.sh | 113 ++++++++++++---- scripts/mac-mini/launchd/README.md | 56 ++++++++ .../com.manacore.backup-databases.plist | 35 +++++ .../launchd/com.manacore.docker-startup.plist | 26 ++++ .../launchd/com.manacore.health-check.plist | 24 ++++ .../launchd/com.manacore.image-gen.plist | 53 ++++++++ .../launchd/com.manacore.mana-stt.plist | 39 ++++++ .../launchd/com.manacore.mana-tts.plist | 39 ++++++ .../launchd/com.manacore.ssd-check.plist | 18 +++ .../com.manacore.telegram-ollama-bot.plist | 36 +++++ scripts/mac-mini/setup-docker-logging.sh | 74 +++++++++++ 12 files changed, 615 insertions(+), 23 deletions(-) create mode 100755 scripts/mac-mini/backup-databases.sh create mode 100644 scripts/mac-mini/launchd/README.md create mode 100644 scripts/mac-mini/launchd/com.manacore.backup-databases.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.docker-startup.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.health-check.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.image-gen.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.mana-stt.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.mana-tts.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.ssd-check.plist create mode 100644 scripts/mac-mini/launchd/com.manacore.telegram-ollama-bot.plist create mode 100755 scripts/mac-mini/setup-docker-logging.sh diff --git a/scripts/mac-mini/backup-databases.sh b/scripts/mac-mini/backup-databases.sh new file mode 100755 index 000000000..95b6b6662 --- /dev/null +++ b/scripts/mac-mini/backup-databases.sh @@ -0,0 +1,125 @@ +#!/bin/bash +# ManaCore Database Backup Script +# Creates daily backups of all PostgreSQL databases with rotation +# +# Retention policy: +# - Daily backups: keep last 7 days +# - Weekly backups: keep last 4 weeks (Sundays) +# +# Run via LaunchD daily at 3 AM + +set -e + +# Ensure PATH includes docker +export PATH="/usr/local/bin:/opt/homebrew/bin:$PATH" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" +BACKUP_DIR="/Volumes/ManaData/backups/postgres" +LOG_FILE="/tmp/manacore-backup.log" +DATE=$(date +%Y-%m-%d) +DAY_OF_WEEK=$(date +%u) # 1=Monday, 7=Sunday + +# Load env for password +if [ -f "$PROJECT_ROOT/.env.macmini" ]; then + source "$PROJECT_ROOT/.env.macmini" +fi + +POSTGRES_PASSWORD="${POSTGRES_PASSWORD:-mana123}" + +log() { + echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" +} + +# Load notification config if exists +if [ -f "$PROJECT_ROOT/.env.notifications" ]; then + source "$PROJECT_ROOT/.env.notifications" +fi + +send_notification() { + local message="$1" + local priority="${2:-default}" + + if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then + curl -s -X POST "https://api.telegram.org/bot${TELEGRAM_BOT_TOKEN}/sendMessage" \ + -d "chat_id=${TELEGRAM_CHAT_ID}" \ + -d "text=${message}" \ + -d "parse_mode=HTML" \ + >/dev/null 2>&1 || true + fi +} + +# Create backup directories +mkdir -p "$BACKUP_DIR/daily" +mkdir -p "$BACKUP_DIR/weekly" + +log "=== ManaCore Database Backup ===" + +# Check if postgres container is running +if ! docker ps --format '{{.Names}}' | grep -q "mana-infra-postgres"; then + log "ERROR: PostgreSQL container is not running" + send_notification "🚨 Backup Failed\n\nPostgreSQL container not running" "high" + exit 1 +fi + +# Get list of databases (exclude templates and postgres) +DATABASES=$(docker exec mana-infra-postgres psql -U postgres -t -c "SELECT datname FROM pg_database WHERE datistemplate = false AND datname != 'postgres';" | tr -d ' ' | grep -v "^$") + +log "Found databases: $(echo $DATABASES | tr '\n' ' ')" + +BACKUP_COUNT=0 +BACKUP_SIZE=0 +FAILED_DBS="" + +for DB in $DATABASES; do + log "Backing up: $DB" + BACKUP_FILE="$BACKUP_DIR/daily/${DB}_${DATE}.sql.gz" + + # Create backup using pg_dump inside container, compress with gzip + if docker exec mana-infra-postgres pg_dump -U postgres "$DB" 2>/dev/null | gzip > "$BACKUP_FILE"; then + SIZE=$(ls -lh "$BACKUP_FILE" | awk '{print $5}') + log " OK: $DB ($SIZE)" + BACKUP_COUNT=$((BACKUP_COUNT + 1)) + BACKUP_SIZE=$((BACKUP_SIZE + $(stat -f%z "$BACKUP_FILE" 2>/dev/null || stat -c%s "$BACKUP_FILE" 2>/dev/null))) + else + log " FAILED: $DB" + FAILED_DBS="$FAILED_DBS $DB" + rm -f "$BACKUP_FILE" # Remove incomplete backup + fi +done + +# On Sunday, create weekly backup +if [ "$DAY_OF_WEEK" -eq 7 ]; then + log "Creating weekly backup (Sunday)..." + WEEKLY_DIR="$BACKUP_DIR/weekly/$DATE" + mkdir -p "$WEEKLY_DIR" + cp "$BACKUP_DIR/daily/"*"_${DATE}.sql.gz" "$WEEKLY_DIR/" 2>/dev/null || true + log "Weekly backup created in $WEEKLY_DIR" +fi + +# Rotate daily backups (keep last 7 days) +log "Rotating daily backups (keeping 7 days)..." +find "$BACKUP_DIR/daily" -name "*.sql.gz" -mtime +7 -delete 2>/dev/null || true + +# Rotate weekly backups (keep last 4 weeks) +log "Rotating weekly backups (keeping 4 weeks)..." +find "$BACKUP_DIR/weekly" -mindepth 1 -maxdepth 1 -type d -mtime +28 -exec rm -rf {} \; 2>/dev/null || true + +# Calculate total backup size +TOTAL_SIZE=$(du -sh "$BACKUP_DIR" 2>/dev/null | awk '{print $1}') + +log "=== Backup Summary ===" +log "Databases backed up: $BACKUP_COUNT" +log "Total backup size: $TOTAL_SIZE" + +if [ -n "$FAILED_DBS" ]; then + log "FAILED databases:$FAILED_DBS" + send_notification "⚠️ Backup Partially Failed\n\nFailed:$FAILED_DBS\nSuccessful: $BACKUP_COUNT databases" "high" + exit 1 +else + log "All backups successful!" + # Only send notification on Sundays (weekly summary) + if [ "$DAY_OF_WEEK" -eq 7 ]; then + send_notification "💾 Weekly Backup Complete\n\n$BACKUP_COUNT databases backed up\nTotal size: $TOTAL_SIZE" + fi +fi diff --git a/scripts/mac-mini/ensure-containers-running.sh b/scripts/mac-mini/ensure-containers-running.sh index aba49db94..f2711d46c 100755 --- a/scripts/mac-mini/ensure-containers-running.sh +++ b/scripts/mac-mini/ensure-containers-running.sh @@ -1,9 +1,10 @@ #!/bin/bash # ManaCore Container Health Enforcer -# Ensures all containers are actually running, not just created +# Ensures all containers are actually running and healthy # -# This script detects containers that are stuck in "Created" or "Exited" -# status and automatically starts them. +# This script detects containers that are: +# - Stuck in "Created" or "Exited" status -> starts them +# - Crash-looping in "Restarting" status -> recreates them # # Run via LaunchD every 5 minutes or after system startup. @@ -17,6 +18,7 @@ PROJECT_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)" COMPOSE_FILE="$PROJECT_ROOT/docker-compose.macmini.yml" ENV_FILE="$PROJECT_ROOT/.env.macmini" LOG_FILE="/tmp/manacore-container-health.log" +RESTART_TRACKER="/tmp/manacore-restart-tracker" # Load notification config if exists if [ -f "$PROJECT_ROOT/.env.notifications" ]; then @@ -29,6 +31,7 @@ log() { send_notification() { local message="$1" + local priority="${2:-default}" # Telegram if [ -n "$TELEGRAM_BOT_TOKEN" ] && [ -n "$TELEGRAM_CHAT_ID" ]; then @@ -42,8 +45,8 @@ send_notification() { # ntfy if [ -n "$NTFY_TOPIC" ]; then curl -s -d "$message" \ - -H "Title: ManaCore Container Fixed" \ - -H "Priority: default" \ + -H "Title: ManaCore Container Health" \ + -H "Priority: $priority" \ -H "Tags: white_check_mark" \ "https://ntfy.sh/$NTFY_TOPIC" >/dev/null 2>&1 || true fi @@ -55,29 +58,90 @@ if ! docker info >/dev/null 2>&1; then exit 1 fi -# Get containers that are NOT running (Created, Exited, etc.) -# Filter only mana-* containers from our compose file +# Get containers that are NOT running (Created, Exited) STUCK_CONTAINERS=$(docker ps -a --filter "status=created" --filter "status=exited" --format "{{.Names}}" | grep "^mana-" || true) -if [ -z "$STUCK_CONTAINERS" ]; then +# Get containers that are crash-looping (Restarting) +CRASHLOOP_CONTAINERS=$(docker ps -a --filter "status=restarting" --format "{{.Names}}" | grep "^mana-" || true) + +# Track restart attempts to avoid infinite loops +track_restart() { + local container="$1" + local count_file="$RESTART_TRACKER/$container" + mkdir -p "$RESTART_TRACKER" + + if [ -f "$count_file" ]; then + local count=$(cat "$count_file") + local age=$(( $(date +%s) - $(stat -f %m "$count_file" 2>/dev/null || stat -c %Y "$count_file" 2>/dev/null) )) + # Reset counter if more than 1 hour old + if [ "$age" -gt 3600 ]; then + echo "1" > "$count_file" + echo "1" + else + count=$((count + 1)) + echo "$count" > "$count_file" + echo "$count" + fi + else + echo "1" > "$count_file" + echo "1" + fi +} + +if [ -z "$STUCK_CONTAINERS" ] && [ -z "$CRASHLOOP_CONTAINERS" ]; then log "OK: All containers are running" exit 0 fi -log "WARNING: Found containers not running:" -echo "$STUCK_CONTAINERS" | while read container; do - STATUS=$(docker inspect "$container" --format '{{.State.Status}}' 2>/dev/null || echo "unknown") - log " - $container (status: $STATUS)" -done +# Handle crash-looping containers first (more critical) +if [ -n "$CRASHLOOP_CONTAINERS" ]; then + log "WARNING: Found crash-looping containers:" + for container in $CRASHLOOP_CONTAINERS; do + RESTART_COUNT=$(docker inspect "$container" --format '{{.RestartCount}}' 2>/dev/null || echo "0") + log " - $container (restart count: $RESTART_COUNT)" + done -# Start the stuck containers using docker compose -log "Starting stuck containers via docker compose..." + log "Attempting to recover crash-looping containers..." + for container in $CRASHLOOP_CONTAINERS; do + ATTEMPTS=$(track_restart "$container") + + if [ "$ATTEMPTS" -gt 3 ]; then + log " SKIP: $container has been restarted $ATTEMPTS times in the last hour, needs manual intervention" + send_notification "🚨 Container needs manual fix\n\n$container has crashed $ATTEMPTS times. Check logs:\ndocker logs $container" "high" + continue + fi + + log " Recreating $container (attempt $ATTEMPTS/3)..." + # Stop, remove and recreate the container + docker stop "$container" 2>/dev/null || true + docker rm "$container" 2>/dev/null || true + done +fi + +# Handle stuck containers (Created/Exited) +if [ -n "$STUCK_CONTAINERS" ]; then + log "WARNING: Found containers not running:" + for container in $STUCK_CONTAINERS; do + STATUS=$(docker inspect "$container" --format '{{.State.Status}}' 2>/dev/null || echo "unknown") + log " - $container (status: $STATUS)" + done +fi + +# Combine all containers that need to be started +ALL_PROBLEM_CONTAINERS=$(echo -e "$STUCK_CONTAINERS\n$CRASHLOOP_CONTAINERS" | grep -v "^$" | sort -u || true) + +if [ -z "$ALL_PROBLEM_CONTAINERS" ]; then + log "OK: No containers need recovery" + exit 0 +fi + +log "Starting containers via docker compose..." cd "$PROJECT_ROOT" # Use docker compose up for the specific services # This ensures dependencies are respected -for container in $STUCK_CONTAINERS; do +for container in $ALL_PROBLEM_CONTAINERS; do # Extract service name from container name (remove mana-app- or mana-* prefix) # Container naming: mana-{category}-{service} or mana-app-{service}-{type} SERVICE_NAME="" @@ -139,18 +203,21 @@ done # Wait for containers to start sleep 10 -# Verify containers are now running +# Verify containers are now running (check for created, exited, AND restarting) STILL_STUCK=$(docker ps -a --filter "status=created" --filter "status=exited" --format "{{.Names}}" | grep "^mana-" || true) +STILL_CRASHING=$(docker ps -a --filter "status=restarting" --format "{{.Names}}" | grep "^mana-" || true) +ALL_STILL_BROKEN=$(echo -e "$STILL_STUCK\n$STILL_CRASHING" | grep -v "^$" | sort -u || true) -if [ -z "$STILL_STUCK" ]; then - FIXED_MSG="Auto-fixed stuck containers: $(echo $STUCK_CONTAINERS | tr '\n' ', ')" +if [ -z "$ALL_STILL_BROKEN" ]; then + FIXED_MSG="Auto-fixed containers: $(echo $ALL_PROBLEM_CONTAINERS | tr '\n' ', ')" log "SUCCESS: $FIXED_MSG" send_notification "🔧 ManaCore Auto-Recovery\n\n$FIXED_MSG" else - log "ERROR: Some containers still not running:" - echo "$STILL_STUCK" | while read container; do - log " - $container" + log "ERROR: Some containers still have issues:" + for container in $ALL_STILL_BROKEN; do + STATUS=$(docker inspect "$container" --format '{{.State.Status}}' 2>/dev/null || echo "unknown") + log " - $container (status: $STATUS)" done - send_notification "⚠️ ManaCore Container Issue\n\nContainers still stuck: $(echo $STILL_STUCK | tr '\n' ', ')" + send_notification "⚠️ ManaCore Container Issue\n\nContainers still broken: $(echo $ALL_STILL_BROKEN | tr '\n' ', ')" "high" exit 1 fi diff --git a/scripts/mac-mini/launchd/README.md b/scripts/mac-mini/launchd/README.md new file mode 100644 index 000000000..57a4b26dc --- /dev/null +++ b/scripts/mac-mini/launchd/README.md @@ -0,0 +1,56 @@ +# LaunchD Services for Mac Mini + +These plist files configure automatic services on the Mac Mini server. + +## Installation + +```bash +# Copy all plists to LaunchAgents +cp *.plist ~/Library/LaunchAgents/ + +# Load all services +for f in *.plist; do launchctl load ~/Library/LaunchAgents/$f; done +``` + +## Services + +| Service | Description | Interval | +|---------|-------------|----------| +| `docker-startup` | Starts Docker containers on boot | At login | +| `ensure-containers` | Detects and restarts stuck containers | Every 5 min | +| `health-check` | Checks all services and sends alerts | Every 5 min | +| `ssd-check` | Monitors SSD health | Periodic | +| `mana-stt` | Speech-to-text service (Whisper) | At login | +| `mana-tts` | Text-to-speech service (Kokoro) | At login | +| `image-gen` | Image generation service | At login | +| `telegram-ollama-bot` | Telegram bot with Ollama | At login | + +## Management Commands + +```bash +# Check status +launchctl list | grep manacore + +# View logs +tail -f /tmp/manacore-*.log + +# Reload a service +launchctl unload ~/Library/LaunchAgents/com.manacore.health-check.plist +launchctl load ~/Library/LaunchAgents/com.manacore.health-check.plist + +# Stop a service +launchctl unload ~/Library/LaunchAgents/com.manacore..plist +``` + +## Troubleshooting + +Exit codes in `launchctl list`: +- `0` = Running successfully +- `1` = Last run had errors (check logs) +- `-` = Not running / waiting for next interval +- `78` = Configuration error + +Check error logs: +```bash +cat /tmp/manacore-.error.log +``` diff --git a/scripts/mac-mini/launchd/com.manacore.backup-databases.plist b/scripts/mac-mini/launchd/com.manacore.backup-databases.plist new file mode 100644 index 000000000..98ccf8d0f --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.backup-databases.plist @@ -0,0 +1,35 @@ + + + + + Label + com.manacore.backup-databases + + ProgramArguments + + /bin/bash + /Users/mana/projects/manacore-monorepo/scripts/mac-mini/backup-databases.sh + + + + StartCalendarInterval + + Hour + 3 + Minute + 0 + + + StandardOutPath + /tmp/manacore-backup.log + + StandardErrorPath + /tmp/manacore-backup.error.log + + EnvironmentVariables + + PATH + /usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin + + + diff --git a/scripts/mac-mini/launchd/com.manacore.docker-startup.plist b/scripts/mac-mini/launchd/com.manacore.docker-startup.plist new file mode 100644 index 000000000..54645cf09 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.docker-startup.plist @@ -0,0 +1,26 @@ + + + + + Label + com.manacore.docker-startup + ProgramArguments + + /bin/bash + /Users/mana/projects/manacore-monorepo/scripts/mac-mini/startup.sh + + RunAtLoad + + StartInterval + 0 + StandardOutPath + /tmp/manacore-startup.log + StandardErrorPath + /tmp/manacore-startup.error.log + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + + + diff --git a/scripts/mac-mini/launchd/com.manacore.health-check.plist b/scripts/mac-mini/launchd/com.manacore.health-check.plist new file mode 100644 index 000000000..674034773 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.health-check.plist @@ -0,0 +1,24 @@ + + + + + Label + com.manacore.health-check + ProgramArguments + + /bin/bash + /Users/mana/projects/manacore-monorepo/scripts/mac-mini/health-check.sh + + StartInterval + 300 + StandardOutPath + /tmp/manacore-health.log + StandardErrorPath + /tmp/manacore-health.error.log + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + + + diff --git a/scripts/mac-mini/launchd/com.manacore.image-gen.plist b/scripts/mac-mini/launchd/com.manacore.image-gen.plist new file mode 100644 index 000000000..15a06d090 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.image-gen.plist @@ -0,0 +1,53 @@ + + + + + Label + com.manacore.image-gen + ProgramArguments + + /Users/mana/projects/manacore-monorepo/services/mana-image-gen/.venv/bin/python3 + -m + uvicorn + app.main:app + --host + 0.0.0.0 + --port + 3025 + + WorkingDirectory + /Users/mana/projects/manacore-monorepo/services/mana-image-gen + EnvironmentVariables + + PATH + /opt/homebrew/bin:/Users/mana/projects/manacore-monorepo/services/mana-image-gen/.venv/bin:/usr/local/bin:/usr/bin:/bin + HOME + /Users/mana + PORT + 3025 + FLUX_BINARY + /Users/mana/flux2/flux + FLUX_MODEL_DIR + /Users/mana/flux2/model + DEFAULT_STEPS + 4 + GENERATION_TIMEOUT + 300 + CORS_ORIGINS + https://mana.how,https://picture.mana.how,https://chat.mana.how + + RunAtLoad + + KeepAlive + + SuccessfulExit + + Crashed + + + StandardOutPath + /tmp/manacore-image-gen.log + StandardErrorPath + /tmp/manacore-image-gen.error.log + + diff --git a/scripts/mac-mini/launchd/com.manacore.mana-stt.plist b/scripts/mac-mini/launchd/com.manacore.mana-stt.plist new file mode 100644 index 000000000..0517819c8 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.mana-stt.plist @@ -0,0 +1,39 @@ + + + + + Label + com.manacore.mana-stt + + ProgramArguments + + /bin/bash + -c + cd /Users/mana/projects/manacore-monorepo/services/mana-stt && set -a && source .env && set +a && .venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 3020 + + + WorkingDirectory + /Users/mana/projects/manacore-monorepo/services/mana-stt + + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin + + + RunAtLoad + + + KeepAlive + + + StandardOutPath + /Users/mana/logs/mana-stt.log + + StandardErrorPath + /Users/mana/logs/mana-stt.error.log + + ThrottleInterval + 10 + + diff --git a/scripts/mac-mini/launchd/com.manacore.mana-tts.plist b/scripts/mac-mini/launchd/com.manacore.mana-tts.plist new file mode 100644 index 000000000..513f2ebe0 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.mana-tts.plist @@ -0,0 +1,39 @@ + + + + + Label + com.manacore.mana-tts + + ProgramArguments + + /bin/bash + -c + cd /Users/mana/projects/manacore-monorepo/services/mana-tts && set -a && source .env && set +a && .venv/bin/uvicorn app.main:app --host 0.0.0.0 --port 3022 + + + WorkingDirectory + /Users/mana/projects/manacore-monorepo/services/mana-tts + + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin + + + RunAtLoad + + + KeepAlive + + + StandardOutPath + /Users/mana/logs/mana-tts.log + + StandardErrorPath + /Users/mana/logs/mana-tts.error.log + + ThrottleInterval + 10 + + diff --git a/scripts/mac-mini/launchd/com.manacore.ssd-check.plist b/scripts/mac-mini/launchd/com.manacore.ssd-check.plist new file mode 100644 index 000000000..e5043f0e2 --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.ssd-check.plist @@ -0,0 +1,18 @@ + + + + + Label + com.manacore.ssd-check + ProgramArguments + + /Users/mana/check-ssd.sh + + RunAtLoad + + StandardOutPath + /Users/mana/Library/Logs/ssd-check.log + StandardErrorPath + /Users/mana/Library/Logs/ssd-check.log + + diff --git a/scripts/mac-mini/launchd/com.manacore.telegram-ollama-bot.plist b/scripts/mac-mini/launchd/com.manacore.telegram-ollama-bot.plist new file mode 100644 index 000000000..d3b32df3a --- /dev/null +++ b/scripts/mac-mini/launchd/com.manacore.telegram-ollama-bot.plist @@ -0,0 +1,36 @@ + + + + + Label + com.manacore.telegram-ollama-bot + ProgramArguments + + /opt/homebrew/bin/node + /Users/mana/projects/manacore-monorepo/services/telegram-ollama-bot/dist/main.js + + WorkingDirectory + /Users/mana/projects/manacore-monorepo/services/telegram-ollama-bot + EnvironmentVariables + + PATH + /opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin + TELEGRAM_BOT_TOKEN + 8559479868:AAHF3g7vYLs0eOvDLh7hFVnIB-V8CKehUOM + OLLAMA_URL + http://localhost:11434 + OLLAMA_MODEL + gemma3:4b + PORT + 3301 + + RunAtLoad + + KeepAlive + + StandardOutPath + /Users/mana/Library/Logs/telegram-ollama-bot.log + StandardErrorPath + /Users/mana/Library/Logs/telegram-ollama-bot.log + + diff --git a/scripts/mac-mini/setup-docker-logging.sh b/scripts/mac-mini/setup-docker-logging.sh new file mode 100755 index 000000000..42722bcfc --- /dev/null +++ b/scripts/mac-mini/setup-docker-logging.sh @@ -0,0 +1,74 @@ +#!/bin/bash +# Configure Docker daemon for log rotation +# This prevents docker logs from consuming unlimited disk space +# +# Run once after Docker Desktop installation + +set -e + +DOCKER_CONFIG_DIR="$HOME/.docker" +DAEMON_JSON="$DOCKER_CONFIG_DIR/daemon.json" + +echo "=== Docker Log Rotation Setup ===" + +# Create config directory if needed +mkdir -p "$DOCKER_CONFIG_DIR" + +# Backup existing config +if [ -f "$DAEMON_JSON" ]; then + cp "$DAEMON_JSON" "${DAEMON_JSON}.backup.$(date +%Y%m%d)" + echo "Backed up existing daemon.json" +fi + +# Check if config exists and has content +if [ -f "$DAEMON_JSON" ] && [ -s "$DAEMON_JSON" ]; then + # Merge with existing config using jq if available + if command -v jq &> /dev/null; then + echo "Merging with existing daemon.json..." + jq '. + { + "log-driver": "json-file", + "log-opts": { + "max-size": "50m", + "max-file": "3", + "compress": "true" + } + }' "$DAEMON_JSON" > "${DAEMON_JSON}.tmp" && mv "${DAEMON_JSON}.tmp" "$DAEMON_JSON" + else + echo "WARNING: jq not installed, cannot merge configs" + echo "Please manually add log settings to $DAEMON_JSON" + echo "" + echo 'Add this to your daemon.json:' + echo ' "log-driver": "json-file",' + echo ' "log-opts": {' + echo ' "max-size": "50m",' + echo ' "max-file": "3",' + echo ' "compress": "true"' + echo ' }' + exit 1 + fi +else + # Create new config + echo "Creating new daemon.json..." + cat > "$DAEMON_JSON" << 'EOF' +{ + "log-driver": "json-file", + "log-opts": { + "max-size": "50m", + "max-file": "3", + "compress": "true" + } +} +EOF +fi + +echo "" +echo "Log rotation configured:" +echo " - Max size per log file: 50MB" +echo " - Max files per container: 3" +echo " - Compression: enabled" +echo " - Total max logs per container: ~150MB" +echo "" +echo "IMPORTANT: Restart Docker Desktop for changes to take effect!" +echo "" +echo "To verify after restart:" +echo " docker info | grep -A5 'Logging Driver'"