#!/usr/bin/env bash # # Push ia.enso.4nkweb.com nginx config to the LAN proxy (192.168.1.100) over SSH. # Requires passwordless sudo for nginx on the proxy host. # # Environment: # IA_ENSO_OLLAMA_BEARER_TOKEN Bearer secret for /ollama (if unset, openssl rand -hex 32). # IA_ENSO_SSH_KEY SSH private key (default: ~/.ssh/id_ed25519). # IA_ENSO_PROXY_USER SSH user on proxy (default: ncantu). # IA_ENSO_PROXY_HOST Proxy IP or hostname (default: 192.168.1.100). # IA_ENSO_BACKEND_IP Ollama + AnythingLLM host IPv4 (default: 192.168.1.164). # DEPLOY_SSH_PROXY_HOST Jump host (default: 4nk.myftp.biz); empty = direct SSH to proxy. # DEPLOY_SSH_PROXY_USER Jump user (default: same as IA_ENSO_PROXY_USER). # set -euo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" SMART_IDE_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)" SSH_LIB="${SMART_IDE_ROOT}/ia_dev/deploy/_lib/ssh.sh" if [[ ! -f "$SSH_LIB" ]]; then echo "Missing ${SSH_LIB} (ia_dev submodule checkout?)" >&2 exit 1 fi # shellcheck source=/dev/null source "$SSH_LIB" IA_ENSO_SSH_KEY="${IA_ENSO_SSH_KEY:-${HOME}/.ssh/id_ed25519}" IA_ENSO_PROXY_USER="${IA_ENSO_PROXY_USER:-ncantu}" IA_ENSO_PROXY_HOST="${IA_ENSO_PROXY_HOST:-192.168.1.100}" IA_ENSO_BACKEND_IP="${IA_ENSO_BACKEND_IP:-192.168.1.164}" DEPLOY_SSH_PROXY_USER="${DEPLOY_SSH_PROXY_USER:-$IA_ENSO_PROXY_USER}" if [[ ! -v DEPLOY_SSH_PROXY_HOST ]]; then export DEPLOY_SSH_PROXY_HOST='4nk.myftp.biz' elif [[ -z "$DEPLOY_SSH_PROXY_HOST" ]]; then unset DEPLOY_SSH_PROXY_HOST fi export DEPLOY_SSH_PROXY_USER TOKEN="${IA_ENSO_OLLAMA_BEARER_TOKEN:-}" if [[ -z "$TOKEN" ]]; then TOKEN="$(openssl rand -hex 32)" echo "IA_ENSO_OLLAMA_BEARER_TOKEN was unset; generated token (store for Cursor API key):" echo "$TOKEN" echo "---" fi if [[ "$TOKEN" == *'"'* ]] || [[ "$TOKEN" == *'\'* ]]; then echo "Token must not contain double quotes or backslashes." >&2 exit 1 fi if [[ ! "$IA_ENSO_BACKEND_IP" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "IA_ENSO_BACKEND_IP must be an IPv4 address (got: ${IA_ENSO_BACKEND_IP})" >&2 exit 1 fi # mode: full = websocket + bearer; bearer_only = bearer + map_hash (duplicate websocket elsewhere) write_maps_file() { local path="$1" local mode="$2" { cat <<'HASHOF' map_hash_bucket_size 256; HASHOF if [[ "$mode" == "full" ]]; then cat <<'MAPEOF' map $http_upgrade $connection_upgrade { default upgrade; '' close; } MAPEOF fi cat <"$path" } TMP_DIR="$(mktemp -d)" cleanup() { rm -rf "$TMP_DIR" } trap cleanup EXIT try_install() { local mode="$1" write_maps_file "${TMP_DIR}/ia-enso-http-maps.conf" "$mode" sed "s/__IA_ENSO_BACKEND_IP__/${IA_ENSO_BACKEND_IP}/g" "${SCRIPT_DIR}/sites/ia.enso.4nkweb.com.conf" >"${TMP_DIR}/ia.enso.4nkweb.com.conf" scp_copy "$IA_ENSO_SSH_KEY" "${TMP_DIR}/ia-enso-http-maps.conf" "$IA_ENSO_PROXY_USER" "$IA_ENSO_PROXY_HOST" "/tmp/ia-enso-http-maps.conf" scp_copy "$IA_ENSO_SSH_KEY" "${TMP_DIR}/ia.enso.4nkweb.com.conf" "$IA_ENSO_PROXY_USER" "$IA_ENSO_PROXY_HOST" "/tmp/ia.enso.4nkweb.com.conf" ssh_run "$IA_ENSO_SSH_KEY" "$IA_ENSO_PROXY_USER" "$IA_ENSO_PROXY_HOST" bash <<'REMOTE' set -euo pipefail sudo install -d -m 0755 /etc/nginx/conf.d sudo install -m 0644 /tmp/ia-enso-http-maps.conf /etc/nginx/conf.d/ia-enso-http-maps.conf sudo install -m 0644 /tmp/ia.enso.4nkweb.com.conf /etc/nginx/sites-available/ia.enso.4nkweb.com.conf sudo ln -sf /etc/nginx/sites-available/ia.enso.4nkweb.com.conf /etc/nginx/sites-enabled/ia.enso.4nkweb.com.conf rm -f /tmp/ia-enso-http-maps.conf /tmp/ia.enso.4nkweb.com.conf if ! grep -q 'include /etc/nginx/conf.d/\*\.conf;' /etc/nginx/nginx.conf; then echo "ERROR: /etc/nginx/nginx.conf must include conf.d inside http { }." >&2 echo "Add: include /etc/nginx/conf.d/*.conf;" >&2 exit 1 fi sudo nginx -t sudo systemctl reload nginx echo "nginx reload OK" REMOTE } echo "Deploying ia.enso upstreams to ${IA_ENSO_BACKEND_IP} (Ollama :11434, AnythingLLM :3001)." if ! try_install full; then echo "Retrying with Bearer map only (websocket map likely already defined on proxy)..." if ! try_install bearer_only; then echo "Deploy failed (SSH, sudo, nginx -t, or missing include /etc/nginx/conf.d/*.conf)." >&2 echo "Re-run from a host with SSH access (LAN: DEPLOY_SSH_PROXY_HOST=); set IA_ENSO_OLLAMA_BEARER_TOKEN to reuse secret." >&2 exit 1 fi fi echo "Done. Bearer required on /ollama/. Cursor base: https://ia.enso.4nkweb.com/ollama/v1 — API key = token above (if generated) or IA_ENSO_OLLAMA_BEARER_TOKEN."