host: go live — blog.rose-ash.com served by the SX host in the stack
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 15s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 15s
Promote lib/host into the docker stack behind blog.rose-ash.com (reusing a down Quart subdomain). New compose service sx_host runs lib/host/serve.sh on externalnet; Caddy reverse-proxies blog.rose-ash.com -> sx-dev-sx_host-1:8000. hosts/ fix: http-listen bound inet_addr_loopback only, unreachable from other containers. Add SX_HTTP_HOST env (default loopback for tests/local; stack sets 0.0.0.0) in sx_server.ml. serve.sh made container-friendly (SX_PROJECT_DIR). Verified live through Cloudflare->Caddy: /health, /feed, relations reads serve real JSON; / 404 (no root route yet). rose-ash.com untouched. Conformance 145/145 green with the rebuilt binary. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
37
docker-compose.dev-sx-host.yml
Normal file
37
docker-compose.dev-sx-host.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
# host-on-sx live service — the SX web host (lib/host) served by the native
|
||||
# http-listen server via lib/host/serve.sh. Joins the sx-dev project + externalnet
|
||||
# so Caddy can reverse_proxy a subdomain to it (blog.rose-ash.com). Isolated from
|
||||
# the sx_docs server: separate container, separate port.
|
||||
#
|
||||
# Usage:
|
||||
# docker compose -p sx-dev -f docker-compose.dev-sx-host.yml up -d sx_host
|
||||
# docker compose -p sx-dev -f docker-compose.dev-sx-host.yml logs -f sx_host
|
||||
# docker compose -p sx-dev -f docker-compose.dev-sx-host.yml down
|
||||
|
||||
services:
|
||||
sx_host:
|
||||
image: registry.rose-ash.com:5000/sx_docs:latest
|
||||
container_name: sx-dev-sx_host-1
|
||||
entrypoint: ["bash", "/app/lib/host/serve.sh"]
|
||||
working_dir: /app
|
||||
environment:
|
||||
SX_PROJECT_DIR: /app
|
||||
SX_SERVER: /app/bin/sx_server
|
||||
HOST_PORT: "8000"
|
||||
# Bind all interfaces so Caddy (on externalnet) can reach it.
|
||||
SX_HTTP_HOST: "0.0.0.0"
|
||||
OCAMLRUNPARAM: "b"
|
||||
volumes:
|
||||
# SX source (hot-reload on container restart)
|
||||
- ./spec:/app/spec:ro
|
||||
- ./lib:/app/lib:ro
|
||||
# OCaml server binary — this worktree's build (has the SX_HTTP_HOST bind fix)
|
||||
- ./hosts/ocaml/_build/default/bin/sx_server.exe:/app/bin/sx_server:ro
|
||||
networks:
|
||||
- externalnet
|
||||
- default
|
||||
restart: unless-stopped
|
||||
|
||||
networks:
|
||||
externalnet:
|
||||
external: true
|
||||
@@ -745,8 +745,15 @@ let setup_evaluator_bridge env =
|
||||
| _ -> raise (Eval_error "http-listen: (port handler)") in
|
||||
let sock = Unix.socket Unix.PF_INET Unix.SOCK_STREAM 0 in
|
||||
Unix.setsockopt sock Unix.SO_REUSEADDR true;
|
||||
(* Bind host: loopback by default (safe for tests + local runs); set
|
||||
SX_HTTP_HOST=0.0.0.0 to expose on the network (container/Caddy). *)
|
||||
let bind_addr =
|
||||
match Sys.getenv_opt "SX_HTTP_HOST" with
|
||||
| Some h -> (try Unix.inet_addr_of_string h
|
||||
with _ -> Unix.inet_addr_loopback)
|
||||
| None -> Unix.inet_addr_loopback in
|
||||
Unix.bind sock
|
||||
(Unix.ADDR_INET (Unix.inet_addr_loopback, port));
|
||||
(Unix.ADDR_INET (bind_addr, port));
|
||||
Unix.listen sock 64;
|
||||
(* SX runtime is shared across threads — serialize handler calls. *)
|
||||
let mtx = Mutex.create () in
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
# exactly what the suites verify.
|
||||
|
||||
set -uo pipefail
|
||||
cd "$(git rev-parse --show-toplevel)"
|
||||
# Project root: SX_PROJECT_DIR in containers (set to /app by the compose stack),
|
||||
# else the git toplevel for local runs.
|
||||
cd "${SX_PROJECT_DIR:-$(git rev-parse --show-toplevel 2>/dev/null || echo .)}"
|
||||
|
||||
SX_SERVER="${SX_SERVER:-hosts/ocaml/_build/default/bin/sx_server.exe}"
|
||||
if [ ! -x "$SX_SERVER" ]; then
|
||||
|
||||
@@ -133,8 +133,18 @@ lib/host/sxtp.sx subsystem APIs (feed/search/commerce/…
|
||||
- [x] native `http-listen` ↔ Dream-app bridge (`lib/host/server.sx`:
|
||||
`host/native-handler`/`host/serve`) + `lib/host/serve.sh` launcher. Serves
|
||||
real HTTP on a host port — verified live (health/feed/relations reads + 404).
|
||||
- [ ] promote into the docker stack + a Caddy subdomain (NOT `rose-ash.com` — that
|
||||
is the legacy public site, untouched). Scope now includes `hosts/` + Caddy.
|
||||
- [x] promote into the docker stack + a Caddy subdomain — **LIVE at
|
||||
`https://blog.rose-ash.com`** (reusing a down Quart subdomain). New compose
|
||||
service `sx_host` (`docker-compose.dev-sx-host.yml`, container
|
||||
`sx-dev-sx_host-1`) runs `serve.sh` on `externalnet`; Caddy reverse-proxies
|
||||
`blog.rose-ash.com` → `sx-dev-sx_host-1:8000`. Required a `hosts/` fix:
|
||||
`http-listen` bound `inet_addr_loopback` only — added `SX_HTTP_HOST` env
|
||||
(default loopback; stack sets `0.0.0.0`) in `sx_server.ml`, rebuilt this
|
||||
worktree's binary. Verified: `/health`, `/feed`, relations reads serve real
|
||||
JSON through Cloudflare→Caddy; `/` 404 (no root route yet). `rose-ash.com`
|
||||
untouched. CAVEAT: `/root/caddy/Caddyfile` is an inode-pinned bind mount —
|
||||
edited file shows a NEW inode the container can't see; loaded live via
|
||||
`caddy reload` from a non-bind path. A caddy restart reconciles the bind.
|
||||
- [ ] proxy-to-Quart fallback for un-migrated paths (strangler requirement before
|
||||
a real subdomain fronts users).
|
||||
- [ ] internal-HMAC middleware on `/internal/*` (service-to-service auth; protocol
|
||||
|
||||
Reference in New Issue
Block a user