**Motivations:** - Restore gate on /ollama/; document Cursor streamFromAgentBackend note. **Root causes:** - N/A. **Correctifs:** - location /ollama/ if map + clear Authorization upstream; deploy script emits Bearer + websocket maps with retry bearer_only. **Evolutions:** - README Cursor subsection on streamFromAgentBackend (observed behavior); feature/services/infrastructure aligned. **Pages affectées:** - deploy/nginx/sites/ia.enso.4nkweb.com.conf - deploy/nginx/deploy-ia-enso-to-proxy.sh - deploy/nginx/README-ia-enso.md - deploy/nginx/http-maps/ia-enso-ollama-bearer.map.conf.example - docs/features/ia-enso-nginx-proxy-ollama-anythingllm.md - docs/services.md - docs/infrastructure.md
126 lines
4.6 KiB
Bash
Executable File
126 lines
4.6 KiB
Bash
Executable File
#!/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 <<MAPEOF
|
|
map \$http_authorization \$ia_enso_ollama_authorized {
|
|
default 0;
|
|
"Bearer ${TOKEN}" 1;
|
|
}
|
|
MAPEOF
|
|
} >"$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."
|