Spaces:
Running
Running
Deploy Aureon OS (deploy/selfhost stack: nginx edge + fusion API x2 + console + HNC organ + redis + postgres; paper mode) (part 19)
da0ce7b verified Download scripts/selfhost_up.py from GaryLeckey/aureon-os: direct link, hf CLI and curl.
- Browser
- Download file 8.67 kB
-
https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/scripts/selfhost_up.py
- Command line
-
hf download hf://spaces/GaryLeckey/aureon-os/scripts/selfhost_up.py
-
curl -L -o selfhost_up.py https://huggingface.co/spaces/GaryLeckey/aureon-os/resolve/main/scripts/selfhost_up.py
8.67 kB
| """Non-Docker self-host supervisor. | |
| Starts Postgres RLS, Redis, two API replicas, the frontend HTTP profile, | |
| nginx, and the local error sink. Live trading stays off. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| import signal | |
| import subprocess | |
| import sys | |
| import time | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[1] | |
| RUNTIME = ROOT / "deploy" / "selfhost" / "runtime" | |
| NGINX_CONF = RUNTIME / "nginx.conf" | |
| PIDFILE = RUNTIME / "supervisor.pid" | |
| PIDS = RUNTIME / "pids.json" | |
| TOKEN = "local-selfhost-token" | |
| def _run(cmd: list[str], check: bool = True) -> subprocess.CompletedProcess[str]: | |
| return subprocess.run(cmd, check=check, capture_output=True, text=True) | |
| def _postgres() -> None: | |
| probe = _run(["pg_isready"], check=False) | |
| if probe.returncode != 0: | |
| _run(["sudo", "pg_ctlcluster", "16", "main", "start"]) | |
| exists = _run(["sudo", "-u", "postgres", "psql", "-tAc", "SELECT 1 FROM pg_database WHERE datname='aureon'"]) | |
| if exists.stdout.strip() != "1": | |
| _run(["sudo", "-u", "postgres", "createdb", "aureon"]) | |
| sql_files = [ | |
| ROOT / "deploy" / "selfhost" / "postgres" / "01_roles.sql", | |
| ROOT / "deploy" / "selfhost" / "postgres" / "02_tables.sql", | |
| ROOT / "supabase" / "migrations" / "20260811210525_lock_down_legacy_public_tables.sql", | |
| ] | |
| for path in sql_files: | |
| _run(["sudo", "-u", "postgres", "psql", "-d", "aureon", "-v", "ON_ERROR_STOP=1", "-f", str(path)]) | |
| def _redis() -> None: | |
| probe = _run(["redis-cli", "ping"], check=False) | |
| if probe.stdout.strip() != "PONG": | |
| subprocess.Popen(["redis-server", "--daemonize", "yes", "--bind", "127.0.0.1", "--port", "6379"]) | |
| for _ in range(20): | |
| if _run(["redis-cli", "ping"], check=False).stdout.strip() == "PONG": | |
| return | |
| time.sleep(0.2) | |
| raise SystemExit("redis did not answer") | |
| def _write_nginx() -> None: | |
| temp = RUNTIME / "nginx-temp" | |
| for name in ("client", "proxy", "fastcgi", "uwsgi", "scgi"): | |
| (temp / name).mkdir(parents=True, exist_ok=True) | |
| NGINX_CONF.write_text( | |
| f""" | |
| daemon off; | |
| worker_processes 1; | |
| error_log {RUNTIME / "nginx-error.log"}; | |
| pid {RUNTIME / "nginx.pid"}; | |
| events {{ worker_connections 128; }} | |
| http {{ | |
| access_log {RUNTIME / "nginx-access.log"}; | |
| client_body_temp_path {temp / "client"}; | |
| proxy_temp_path {temp / "proxy"}; | |
| fastcgi_temp_path {temp / "fastcgi"}; | |
| uwsgi_temp_path {temp / "uwsgi"}; | |
| scgi_temp_path {temp / "scgi"}; | |
| limit_req_zone $binary_remote_addr zone=aureon_api:10m rate=2r/s; | |
| limit_req_status 429; | |
| upstream aureon_api {{ | |
| server 127.0.0.1:8765; | |
| server 127.0.0.1:8766; | |
| }} | |
| server {{ | |
| listen 127.0.0.1:8080; | |
| location = /healthz {{ proxy_pass http://aureon_api; }} | |
| location = /readyz {{ proxy_pass http://aureon_api; }} | |
| location /api/ {{ | |
| limit_req zone=aureon_api burst=3 nodelay; | |
| proxy_pass http://aureon_api; | |
| }} | |
| location = /error-test {{ | |
| limit_req zone=aureon_api burst=3 nodelay; | |
| proxy_pass http://aureon_api; | |
| }} | |
| location /app/ {{ proxy_pass http://127.0.0.1:5173/; }} | |
| location / {{ | |
| root {ROOT / "deploy" / "selfhost" / "www"}; | |
| try_files $uri $uri/ /index.html; | |
| }} | |
| }} | |
| }} | |
| """.strip() | |
| + "\n", | |
| encoding="utf-8", | |
| ) | |
| def _spawn(name: str, cmd: list[str], env: dict[str, str], log_name: str) -> int: | |
| log_path = RUNTIME / log_name | |
| handle = log_path.open("a", encoding="utf-8") | |
| proc = subprocess.Popen(cmd, cwd=ROOT, env=env, stdout=handle, stderr=subprocess.STDOUT, start_new_session=True) | |
| return proc.pid | |
| def _api_env(replica: str, port: str) -> dict[str, str]: | |
| env = dict(os.environ) | |
| env.update( | |
| { | |
| "PYTHONPATH": str(ROOT), | |
| "AUREON_FUSION_BIND": "127.0.0.1", | |
| "AUREON_FUSION_PORT": port, | |
| "AUREON_FUSION_API_TOKEN": TOKEN, | |
| "AUREON_LIVE_TRADING": "0", | |
| "AUREON_FUSION_ARM_LIVE": "", | |
| "AUREON_FUSION_RATE_LIMIT": "100000", | |
| "AUREON_REDIS_URL": "redis://127.0.0.1:6379/0", | |
| "AUREON_ERROR_WEBHOOK_URL": "http://127.0.0.1:8088/envelope", | |
| "AUREON_FUSION_CACHE_TTL_S": "30", | |
| "AUREON_REPLICA_ID": replica, | |
| "AUREON_LOG_PATH": str(RUNTIME / f"{replica}.jsonl"), | |
| "AUREON_ERROR_SINK_PATH": str(RUNTIME / "errors.jsonl"), | |
| } | |
| ) | |
| return env | |
| def start() -> None: | |
| RUNTIME.mkdir(parents=True, exist_ok=True) | |
| os.chmod(RUNTIME, 0o777) | |
| _postgres() | |
| _redis() | |
| _write_nginx() | |
| env = dict(os.environ) | |
| env["PYTHONPATH"] = str(ROOT) | |
| env["AUREON_LIVE_TRADING"] = "0" | |
| env["AUREON_ERROR_SINK_BIND"] = "127.0.0.1" | |
| env["AUREON_ERROR_SINK_PORT"] = "8088" | |
| env["AUREON_ERROR_SINK_PATH"] = str(RUNTIME / "errors.jsonl") | |
| pids = { | |
| "error_sink": _spawn("error_sink", [sys.executable, str(ROOT / "deploy" / "selfhost" / "error_sink.py")], env, "error_sink.out"), | |
| "api_a": _spawn("api_a", [sys.executable, "-m", "aureon_fusion.http_service"], _api_env("api_a", "8765"), "api_a.out"), | |
| "api_b": _spawn("api_b", [sys.executable, "-m", "aureon_fusion.http_service"], _api_env("api_b", "8766"), "api_b.out"), | |
| "frontend": _spawn( | |
| "frontend", | |
| [sys.executable, "-m", "aureon.operator.local_http_profile", "--serve", "--host", "127.0.0.1", "--port", "5173"], | |
| env, | |
| "frontend.out", | |
| ), | |
| "hnc_core": _spawn( | |
| "hnc_core", | |
| [sys.executable, "-m", "aureon_fusion.hnc_core", "--supervise"], | |
| env, | |
| "hnc_core.out", | |
| ), | |
| } | |
| nginx = subprocess.Popen(["nginx", "-c", str(NGINX_CONF)], start_new_session=True) | |
| pids["nginx"] = nginx.pid | |
| PIDS.write_text(json.dumps(pids), encoding="utf-8") | |
| PIDFILE.write_text(str(os.getpid()), encoding="utf-8") | |
| print(json.dumps({"ok": True, "base": "http://127.0.0.1:8080", "live_trading": False, "pids": pids})) | |
| def _stop(_signum, _frame) -> None: | |
| stop() | |
| raise SystemExit(0) | |
| signal.signal(signal.SIGTERM, _stop) | |
| signal.signal(signal.SIGINT, _stop) | |
| while True: | |
| time.sleep(2) | |
| current = json.loads(PIDS.read_text(encoding="utf-8")) | |
| for name, pid in list(current.items()): | |
| try: | |
| os.kill(int(pid), 0) | |
| except OSError: | |
| if name == "nginx": | |
| nginx = subprocess.Popen(["nginx", "-c", str(NGINX_CONF)], start_new_session=True) | |
| current[name] = nginx.pid | |
| elif name == "frontend": | |
| current[name] = _spawn( | |
| name, | |
| [sys.executable, "-m", "aureon.operator.local_http_profile", "--serve", "--host", "127.0.0.1", "--port", "5173"], | |
| env, | |
| "frontend.out", | |
| ) | |
| elif name == "error_sink": | |
| current[name] = _spawn(name, [sys.executable, str(ROOT / "deploy" / "selfhost" / "error_sink.py")], env, "error_sink.out") | |
| elif name == "hnc_core": | |
| current[name] = _spawn( | |
| name, | |
| [sys.executable, "-m", "aureon_fusion.hnc_core", "--supervise"], | |
| env, | |
| "hnc_core.out", | |
| ) | |
| elif name.startswith("api_"): | |
| port = "8765" if name == "api_a" else "8766" | |
| current[name] = _spawn(name, [sys.executable, "-m", "aureon_fusion.http_service"], _api_env(name, port), f"{name}.out") | |
| PIDS.write_text(json.dumps(current), encoding="utf-8") | |
| def stop() -> None: | |
| if PIDS.is_file(): | |
| pids = json.loads(PIDS.read_text(encoding="utf-8")) | |
| for pid in pids.values(): | |
| try: | |
| os.kill(int(pid), signal.SIGTERM) | |
| except OSError: | |
| pass | |
| if NGINX_CONF.is_file(): | |
| subprocess.run(["nginx", "-c", str(NGINX_CONF), "-s", "stop"], check=False) | |
| if PIDFILE.is_file(): | |
| PIDFILE.unlink() | |
| def main(argv: list[str] | None = None) -> int: | |
| args = list(sys.argv[1:] if argv is None else argv) | |
| if "--stop" in args: | |
| stop() | |
| print(json.dumps({"ok": True, "stopped": True})) | |
| return 0 | |
| start() | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |