#!/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}" # ${VAR:-default} treats empty VAR as unset, so DEPLOY_SSH_PROXY_HOST= would wrongly become the bastion. 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 write_maps_file() { local path="$1" local with_websocket="$2" { cat <<'HASHOF' # Long Bearer keys (e.g. openssl rand -hex 32) exceed default map_hash buckets. map_hash_bucket_size 256; HASHOF if [[ "$with_websocket" == "1" ]]; 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 with_ws="$1" write_maps_file "${TMP_DIR}/ia-enso-http-maps.conf" "$with_ws" 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 1; then echo "Retrying with Bearer map only (websocket map likely already defined on proxy)..." if ! try_install 0; 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 to the proxy (LAN direct: DEPLOY_SSH_PROXY_HOST=); reuse token with IA_ENSO_OLLAMA_BEARER_TOKEN if needed." >&2 exit 1 fi fi echo "Done. Public URLs:" echo " AnythingLLM: https://ia.enso.4nkweb.com/anythingllm/" echo " Ollama API: https://ia.enso.4nkweb.com/ollama/api/tags (native) — Bearer required" echo " Cursor/OpenAI base: https://ia.enso.4nkweb.com/ollama/v1 — API key = Bearer secret (see token above if generated)."