platform-deployments/provisioning/setup-black.sh
2026-01-15 11:01:33 -08:00

269 lines
8.3 KiB
Bash
Executable file

#!/bin/bash
#
# Provision black (10.0.0.11) as staging environment
#
# This script sets up all prerequisites for running webmap-router staging.
# Run this ONCE when setting up a new staging host.
#
# Usage: ./setup-black.sh [--check | --full | --nginx]
#
# Prerequisites:
# - SSH access to black
# - sudo privileges on black
# - Ubuntu 24.04 (or similar Debian-based)
#
# What it sets up:
# - Node.js 22 LTS
# - PostgreSQL 16
# - lilith database user
# - lilith_webmap database
# - /opt/lilith-platform directory structure
# - nginx (optional, with --nginx flag)
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
INFRA_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
# Target host
BLACK_HOST="${BLACK_HOST:-black}"
BLACK_USER="${BLACK_USER:-lilith}"
BLACK_SSH_KEY="${BLACK_SSH_KEY:-${HOME}/.ssh/id_ed25519_black}"
# Configuration
NODE_VERSION="22"
POSTGRES_VERSION="16"
DEPLOY_PATH="/opt/lilith-platform"
DB_NAME="lilith_webmap"
DB_USER="lilith"
DB_PASSWORD="${DB_PASSWORD:-lilith}"
# Colors
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
log_section() { echo -e "\n${BLUE}━━━ $1 ━━━${NC}"; }
ssh_cmd() {
ssh -i "$BLACK_SSH_KEY" "$BLACK_USER@$BLACK_HOST" "$@"
}
# Check connectivity and basic info
check_host() {
log_section "Host Check"
if ! ssh_cmd "echo 'SSH connection OK'" &>/dev/null; then
log_error "Cannot connect to $BLACK_HOST"
exit 1
fi
log_info "SSH connection: OK"
ssh_cmd "cat /etc/os-release | grep PRETTY_NAME"
ssh_cmd 'echo "Hostname: $(hostname)"'
ssh_cmd 'echo "IP: $(hostname -I | awk '\''{print $1}'\'')"'
}
# Install Node.js
setup_nodejs() {
log_section "Node.js ${NODE_VERSION}"
if ssh_cmd "node --version 2>/dev/null" | grep -q "v${NODE_VERSION}"; then
log_info "Node.js ${NODE_VERSION} already installed"
return
fi
log_info "Installing Node.js ${NODE_VERSION}..."
ssh_cmd "curl -fsSL https://deb.nodesource.com/setup_${NODE_VERSION}.x | sudo -E bash -"
ssh_cmd "sudo apt-get install -y nodejs"
ssh_cmd "node --version"
log_info "Node.js installed"
}
# Install PostgreSQL
setup_postgresql() {
log_section "PostgreSQL ${POSTGRES_VERSION}"
if ssh_cmd "psql --version 2>/dev/null" | grep -q "${POSTGRES_VERSION}"; then
log_info "PostgreSQL ${POSTGRES_VERSION} already installed"
else
log_info "Installing PostgreSQL ${POSTGRES_VERSION}..."
ssh_cmd "sudo apt-get update"
ssh_cmd "sudo apt-get install -y postgresql-${POSTGRES_VERSION} postgresql-contrib"
ssh_cmd "sudo systemctl enable postgresql"
ssh_cmd "sudo systemctl start postgresql"
fi
# Create database user
log_info "Creating database user: ${DB_USER}"
ssh_cmd "sudo -u postgres psql -c \"CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASSWORD}';\" 2>/dev/null || echo 'User exists'"
# Create database
log_info "Creating database: ${DB_NAME}"
ssh_cmd "sudo -u postgres psql -c \"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};\" 2>/dev/null || echo 'Database exists'"
# Grant privileges
ssh_cmd "sudo -u postgres psql -c \"GRANT ALL PRIVILEGES ON DATABASE ${DB_NAME} TO ${DB_USER};\""
# Allow local password auth (for Node.js connections)
log_info "Configuring pg_hba.conf for local connections..."
ssh_cmd "sudo grep -q 'local.*${DB_NAME}.*${DB_USER}.*md5' /etc/postgresql/${POSTGRES_VERSION}/main/pg_hba.conf || \
echo 'local ${DB_NAME} ${DB_USER} md5' | sudo tee -a /etc/postgresql/${POSTGRES_VERSION}/main/pg_hba.conf"
ssh_cmd "sudo grep -q 'host.*${DB_NAME}.*${DB_USER}.*127.0.0.1.*md5' /etc/postgresql/${POSTGRES_VERSION}/main/pg_hba.conf || \
echo 'host ${DB_NAME} ${DB_USER} 127.0.0.1/32 md5' | sudo tee -a /etc/postgresql/${POSTGRES_VERSION}/main/pg_hba.conf"
ssh_cmd "sudo systemctl reload postgresql"
log_info "PostgreSQL configured"
}
# Create directory structure
setup_directories() {
log_section "Directory Structure"
log_info "Creating ${DEPLOY_PATH}..."
ssh_cmd "sudo mkdir -p ${DEPLOY_PATH}/{webmap-router,apps/landing,apps/seo,secrets,logs}"
ssh_cmd "sudo chown -R ${BLACK_USER}:${BLACK_USER} ${DEPLOY_PATH}"
ssh_cmd "chmod 700 ${DEPLOY_PATH}/secrets"
log_info "Directory structure:"
ssh_cmd "tree -L 2 ${DEPLOY_PATH} 2>/dev/null || ls -la ${DEPLOY_PATH}"
}
# Create secrets file
setup_secrets() {
log_section "Secrets"
local secrets_file="${DEPLOY_PATH}/secrets/webmap.env"
if ssh_cmd "test -f ${secrets_file}" &>/dev/null; then
log_info "Secrets file exists, skipping"
return
fi
log_info "Creating secrets file..."
ssh_cmd "cat > ${secrets_file}" <<EOF
# WebMap Router Secrets
# Generated by setup-black.sh on $(date -Iseconds)
DATABASE_PASSWORD=${DB_PASSWORD}
EOF
ssh_cmd "chmod 600 ${secrets_file}"
log_info "Secrets file created at ${secrets_file}"
}
# Install nginx (optional)
setup_nginx() {
log_section "Nginx"
if ssh_cmd "which nginx" &>/dev/null; then
log_info "nginx already installed"
else
log_info "Installing nginx..."
ssh_cmd "sudo apt-get install -y nginx"
ssh_cmd "sudo systemctl enable nginx"
fi
# Create sites-available/enabled structure if not exists
ssh_cmd "sudo mkdir -p /etc/nginx/sites-available /etc/nginx/sites-enabled"
# Check if nginx.conf includes sites-enabled
if ! ssh_cmd "grep -q 'sites-enabled' /etc/nginx/nginx.conf"; then
log_warn "Adding sites-enabled include to nginx.conf..."
ssh_cmd "sudo sed -i '/http {/a\\ include /etc/nginx/sites-enabled/*;' /etc/nginx/nginx.conf"
fi
ssh_cmd "sudo nginx -t && sudo systemctl reload nginx"
log_info "nginx configured"
}
# Install useful tools
setup_tools() {
log_section "Tools"
log_info "Installing useful tools..."
ssh_cmd "sudo apt-get install -y jq tree curl"
log_info "Tools installed"
}
# Print summary
print_summary() {
log_section "Setup Complete"
echo -e "\n${GREEN}Black is ready for staging deployment!${NC}\n"
echo "Services:"
local pg_status
pg_status=$(ssh_cmd "systemctl is-active postgresql 2>/dev/null || echo 'inactive'")
echo " PostgreSQL: ${pg_status}"
local nginx_status
nginx_status=$(ssh_cmd "which nginx &>/dev/null && systemctl is-active nginx || echo 'not installed'")
echo " nginx: ${nginx_status}"
echo ""
echo "Database:"
echo " Host: localhost"
echo " Port: 5432"
echo " Database: ${DB_NAME}"
echo " User: ${DB_USER}"
echo ""
echo "Directories:"
echo " Deploy: ${DEPLOY_PATH}"
echo " Secrets: ${DEPLOY_PATH}/secrets/"
echo " Logs: ${DEPLOY_PATH}/logs/"
echo ""
echo "Next steps:"
echo " 1. Run database migrations: ./deploy-staging-black.sh --db-only"
echo " 2. Deploy application: ./deploy-staging-black.sh --full"
}
# Main
main() {
local mode="${1:---check}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} Provisioning: ${BLACK_HOST}${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
check_host
case "$mode" in
--check)
log_info "Check mode - no changes made"
;;
--nginx)
setup_tools
setup_nodejs
setup_postgresql
setup_directories
setup_secrets
setup_nginx
print_summary
;;
--full)
setup_tools
setup_nodejs
setup_postgresql
setup_directories
setup_secrets
print_summary
;;
*)
echo "Usage: $0 [--check | --full | --nginx]"
echo ""
echo "Options:"
echo " --check Check connectivity only (default)"
echo " --full Full setup without nginx"
echo " --nginx Full setup with nginx"
exit 1
;;
esac
}
main "$@"