platform-codebase/infrastructure/docker/setup-databases.sh
Quinn Ftw b5fe73edd0 feat(infra): database stack, reconciliation, and VPS setup scripts
- Add PostgreSQL + Redis deployment stack
- Add reconciliation framework for fleet management
- Add VPS setup scripts (nginx, wireguard)
- Add dev environment bootstrap scripts
- Update service-registry and systemd configs

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 00:37:52 -08:00

337 lines
10 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# =============================================================================
# Database Services Setup Script
# =============================================================================
#
# Purpose: Automated setup for Lilith Platform database services on apricot
# Host: apricot (10.9.0.1 on VPN)
# Usage: ./setup-databases.sh [--skip-dirs] [--skip-env]
#
# This script:
# 1. Creates data directories with proper permissions
# 2. Generates secure credentials
# 3. Creates .env.databases file
# 4. Optionally starts services
#
# =============================================================================
set -euo pipefail
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Configuration
BASE_DIR="/mnt/bigdisk/_/lilith-platform/databases"
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ENV_FILE="${SCRIPT_DIR}/.env.databases"
ENV_EXAMPLE="${SCRIPT_DIR}/.env.databases.example"
# Parse command line arguments
SKIP_DIRS=false
SKIP_ENV=false
for arg in "$@"; do
case $arg in
--skip-dirs)
SKIP_DIRS=true
shift
;;
--skip-env)
SKIP_ENV=true
shift
;;
--help)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Options:"
echo " --skip-dirs Skip data directory creation"
echo " --skip-env Skip .env.databases file generation"
echo " --help Show this help message"
exit 0
;;
esac
done
# =============================================================================
# Helper Functions
# =============================================================================
print_header() {
echo -e "${BLUE}===================================================================${NC}"
echo -e "${BLUE}$1${NC}"
echo -e "${BLUE}===================================================================${NC}"
}
print_success() {
echo -e "${GREEN}$1${NC}"
}
print_warning() {
echo -e "${YELLOW}$1${NC}"
}
print_error() {
echo -e "${RED}$1${NC}"
}
print_info() {
echo -e "${BLUE} $1${NC}"
}
generate_password() {
openssl rand -base64 32 | tr -d "=+/" | cut -c1-32
}
# =============================================================================
# Main Setup
# =============================================================================
print_header "Lilith Platform Database Services Setup"
echo ""
# Check if running on apricot (optional check)
if [[ "$(hostname)" != "apricot" ]] && [[ "$(hostname)" != "apricot.localdomain" ]]; then
print_warning "This script is designed for apricot host"
read -p "Continue anyway? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
# =============================================================================
# Step 1: Create Data Directories
# =============================================================================
if [[ "$SKIP_DIRS" == false ]]; then
print_header "Step 1: Creating Data Directories"
echo ""
# Check if base directory exists
if [[ ! -d "/mnt/bigdisk" ]]; then
print_error "/mnt/bigdisk does not exist"
print_info "Please ensure the disk is mounted before continuing"
exit 1
fi
# Create directory structure
print_info "Creating directory structure at ${BASE_DIR}"
sudo mkdir -p "${BASE_DIR}"/{postgresql,redis,meilisearch,meilisearch-snapshots}
# Set ownership for PostgreSQL (UID 999 = postgres user in Docker)
print_info "Setting ownership for PostgreSQL directory"
sudo chown -R 999:999 "${BASE_DIR}/postgresql"
sudo chmod 750 "${BASE_DIR}/postgresql"
# Set ownership for Redis and Meilisearch (current user)
print_info "Setting ownership for Redis and Meilisearch directories"
sudo chown -R "${USER}:${USER}" "${BASE_DIR}/redis"
sudo chown -R "${USER}:${USER}" "${BASE_DIR}/meilisearch"
sudo chown -R "${USER}:${USER}" "${BASE_DIR}/meilisearch-snapshots"
sudo chmod 755 "${BASE_DIR}/redis"
sudo chmod 755 "${BASE_DIR}/meilisearch"
sudo chmod 755 "${BASE_DIR}/meilisearch-snapshots"
print_success "Data directories created successfully"
echo ""
else
print_info "Skipping data directory creation (--skip-dirs)"
echo ""
fi
# =============================================================================
# Step 2: Generate Environment File
# =============================================================================
if [[ "$SKIP_ENV" == false ]]; then
print_header "Step 2: Generating Environment Configuration"
echo ""
# Check if .env.databases already exists
if [[ -f "$ENV_FILE" ]]; then
print_warning ".env.databases already exists"
read -p "Overwrite existing file? (y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
print_info "Skipping environment file generation"
echo ""
SKIP_ENV=true
fi
fi
if [[ "$SKIP_ENV" == false ]]; then
# Generate secure passwords
print_info "Generating secure credentials..."
POSTGRES_PASSWORD=$(generate_password)
REDIS_PASSWORD=$(generate_password)
MEILI_MASTER_KEY=$(generate_password)
# Create .env.databases from template
print_info "Creating .env.databases file..."
cat > "$ENV_FILE" <<EOF
# =============================================================================
# DATABASE SERVICES ENVIRONMENT CONFIGURATION
# =============================================================================
# Generated: $(date)
# Host: $(hostname)
# =============================================================================
# =============================================================================
# POSTGRESQL CONFIGURATION
# =============================================================================
POSTGRES_USER=postgres
POSTGRES_PASSWORD=${POSTGRES_PASSWORD}
POSTGRES_DB=lilith_platform
# Data directory
POSTGRES_DATA_DIR=${BASE_DIR}/postgresql
# Performance tuning (adjust based on available RAM)
POSTGRES_SHARED_BUFFERS=8GB
POSTGRES_EFFECTIVE_CACHE_SIZE=24GB
POSTGRES_WORK_MEM=256MB
POSTGRES_MAINTENANCE_WORK_MEM=2GB
POSTGRES_MAX_CONNECTIONS=200
POSTGRES_WAL_BUFFERS=16MB
POSTGRES_CHECKPOINT_COMPLETION_TARGET=0.9
# Authentication
POSTGRES_HOST_AUTH_METHOD=scram-sha-256
# =============================================================================
# REDIS CONFIGURATION
# =============================================================================
REDIS_PASSWORD=${REDIS_PASSWORD}
# Data directory
REDIS_DATA_DIR=${BASE_DIR}/redis
# Memory configuration
REDIS_MAX_MEMORY=4GB
REDIS_LOG_LEVEL=notice
# =============================================================================
# MEILISEARCH CONFIGURATION
# =============================================================================
MEILI_MASTER_KEY=${MEILI_MASTER_KEY}
MEILI_ENV=production
# Data directories
MEILI_DATA_DIR=${BASE_DIR}/meilisearch
MEILI_SNAPSHOT_DIR=${BASE_DIR}/meilisearch-snapshots
# HTTP binding
MEILI_HTTP_ADDR=0.0.0.0:7700
# Performance settings
MEILI_MAX_INDEXING_MEMORY=2GB
MEILI_MAX_INDEXING_THREADS=2
# Telemetry
MEILI_NO_ANALYTICS=true
MEILI_LOG_LEVEL=INFO
EOF
# Set secure permissions
chmod 600 "$ENV_FILE"
print_success "Environment file created: ${ENV_FILE}"
print_warning "File permissions set to 600 (owner read/write only)"
echo ""
# Display credentials (one-time only)
print_info "Generated Credentials (SAVE THESE SECURELY):"
echo "────────────────────────────────────────────────────────"
echo "PostgreSQL Password: ${POSTGRES_PASSWORD}"
echo "Redis Password: ${REDIS_PASSWORD}"
echo "Meilisearch Key: ${MEILI_MASTER_KEY}"
echo "────────────────────────────────────────────────────────"
echo ""
print_warning "These credentials are also saved in ${ENV_FILE}"
echo ""
fi
else
print_info "Skipping environment file generation (--skip-env)"
echo ""
fi
# =============================================================================
# Step 3: Verify Setup
# =============================================================================
print_header "Step 3: Verifying Setup"
echo ""
# Check data directories
if [[ -d "${BASE_DIR}/postgresql" ]]; then
print_success "PostgreSQL data directory exists"
else
print_error "PostgreSQL data directory missing"
fi
if [[ -d "${BASE_DIR}/redis" ]]; then
print_success "Redis data directory exists"
else
print_error "Redis data directory missing"
fi
if [[ -d "${BASE_DIR}/meilisearch" ]]; then
print_success "Meilisearch data directory exists"
else
print_error "Meilisearch data directory missing"
fi
# Check environment file
if [[ -f "$ENV_FILE" ]]; then
print_success "Environment file exists"
# Verify permissions
PERMS=$(stat -c "%a" "$ENV_FILE")
if [[ "$PERMS" == "600" ]]; then
print_success "Environment file permissions correct (600)"
else
print_warning "Environment file permissions: ${PERMS} (should be 600)"
print_info "Run: chmod 600 ${ENV_FILE}"
fi
else
print_error "Environment file missing"
print_info "Run this script without --skip-env to generate it"
fi
echo ""
# =============================================================================
# Step 4: Next Steps
# =============================================================================
print_header "Setup Complete!"
echo ""
print_info "Next steps:"
echo ""
echo "1. Review the generated .env.databases file:"
echo " ${ENV_FILE}"
echo ""
echo "2. Adjust performance settings if needed (based on available RAM)"
echo ""
echo "3. Start database services:"
echo " cd ${SCRIPT_DIR}"
echo " docker-compose -f docker-compose.databases.yml --env-file .env.databases up -d"
echo ""
echo "4. Verify services are running:"
echo " docker-compose -f docker-compose.databases.yml ps"
echo ""
echo "5. Check service health:"
echo " docker-compose -f docker-compose.databases.yml logs -f"
echo ""
echo "For more information, see: README.databases.md"
echo ""
print_success "Setup completed successfully!"
echo ""