docs: correct the "pi-studio has no bind flag" claim everywhere it was baked
1e4c238fixed README; the same claim lived in three more places, all wrong since pi-studio 0.9.60 added /studio --listen-all: - rootfs/usr/local/bin/studio-expose header (and so its --help; the sed range grows 2,31p -> 2,35p so --help still ends at "runs it backgrounded.") - pi-devbox-environment skill section 7: --listen-all as a third path, plus the 0.10 whole-URL / 409 / "link looks damaged" notes, the published-port rule, --stop before --port, and the on-host curl 403-vs-empty-reply diagnostic - Dockerfile.variant STUDIO_PORT comment Bridge and --listen-all on one port: whichever starts second fails, measured both ways on tor-ms22 (v1.11.2): Studio "listen EADDRINUSE ... 0.0.0.0:8765" with the bridge up; studio-expose rc 1 on socat "bind(...): Address already in use" with a 0.0.0.0 listener up. README's warning now says both directions. Cost: studio-expose and the skill are in rootfs/, which base_tag hashes, so the next release rebuilds the base (recomputed with the CI recipe: base-6f3b20266de1 at1e4c238-> base-26d425cea6c2 now). Noted in the CHANGELOG Unreleased entry. No pin changes. lint-shell, dockerfile-directives and base-hash guards pass; check-doc-drift is red only for the unrelated pi-extensions 750b2a8 -> 0d8e417.
This commit is contained in:
+16
-6
@@ -13,18 +13,28 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
|||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
Docs only: this entry changes no pin.
|
Docs and comments only: this entry changes no pin. Two of the files are
|
||||||
|
baked into the base image (`rootfs/usr/local/bin/studio-expose` and the
|
||||||
|
`pi-devbox-environment` skill), and `base_tag` hashes all of `rootfs/`, so
|
||||||
|
**the next release rebuilds the base** rather than reusing
|
||||||
|
`base-6f3b20266de1`.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|
||||||
- **README "Using pi-studio" said pi-studio has no bind flag.** It has had
|
- **README "Using pi-studio" said pi-studio has no bind flag.** It has had
|
||||||
`/studio --listen-all` (binds `0.0.0.0`) since pi-studio 0.9.60, so the
|
`/studio --listen-all` (binds `0.0.0.0`) since pi-studio 0.9.60, so the
|
||||||
section now lists it as path **C**, next to host networking (A) and the
|
section now lists it as path **C**, next to host networking (A) and the
|
||||||
`studio-expose` bridge (B). It also warns not to combine B and C on one port.
|
`studio-expose` bridge (B). It also warns not to combine B and C on one
|
||||||
With `STUDIO_EXPOSE=1` the bridge holds the egress IP on `$STUDIO_PORT`
|
port, because whichever starts second fails. With `STUDIO_EXPOSE=1`,
|
||||||
from boot, and `/studio --listen-all --port 8765` then fails with
|
`/studio --listen-all --port 8765` fails with
|
||||||
`listen EADDRINUSE: address already in use 0.0.0.0:8765` (measured on
|
`listen EADDRINUSE: address already in use 0.0.0.0:8765`. In the other
|
||||||
tor-ms22, v1.11.2).
|
order, `studio-expose` exits 1 on socat's `bind(…): Address already in
|
||||||
|
use` (both measured on tor-ms22, v1.11.2). The same stale "no bind
|
||||||
|
flag" claim is corrected in the three other places that carried it:
|
||||||
|
the `studio-expose` header (and so its `--help`, whose `sed` range
|
||||||
|
grows from `2,31p` to `2,35p`), §7 of the baked `pi-devbox-environment`
|
||||||
|
skill (which also gains the whole-URL, published-port and `curl` notes
|
||||||
|
below), and the `STUDIO_PORT` comment in `Dockerfile.variant`.
|
||||||
- **The remote recipe described a pi-studio 0.9 URL.** Since 0.10 the printed
|
- **The remote recipe described a pi-studio 0.9 URL.** Since 0.10 the printed
|
||||||
URL carries `studioTabState` and `hostedWorkspace` as well as the token, and
|
URL carries `studioTabState` and `hostedWorkspace` as well as the token, and
|
||||||
a token-only URL is answered `409`. The recipe now says to open the whole
|
a token-only URL is answered `409`. The recipe now says to open the whole
|
||||||
|
|||||||
+5
-4
@@ -676,10 +676,11 @@ RUN if [ "${INSTALL_STUDIO}" = "true" ]; then \
|
|||||||
|
|
||||||
# STUDIO_PORT: advisory default consumed by docker-compose port publishing
|
# STUDIO_PORT: advisory default consumed by docker-compose port publishing
|
||||||
# and the recommended `/studio --no-browser --port "$STUDIO_PORT"` launch.
|
# and the recommended `/studio --no-browser --port "$STUDIO_PORT"` launch.
|
||||||
# Harmless in the non-studio variant. NOTE: pi-studio hard-binds the server
|
# Harmless in the non-studio variant. NOTE: by default pi-studio binds the
|
||||||
# to 127.0.0.1 inside the container (index.ts: .listen(port,"127.0.0.1")),
|
# server to 127.0.0.1 inside the container, so reaching it from a browser
|
||||||
# so reaching it from a browser needs a loopback bridge or host networking —
|
# needs host networking, the studio-expose loopback bridge, or the opt-in
|
||||||
# see the "Using pi-studio" section in README.md.
|
# `/studio --listen-all` (pi-studio >= 0.9.60; never together with the
|
||||||
|
# bridge on one port) — see the "Using pi-studio" section in README.md.
|
||||||
ENV STUDIO_PORT=8765
|
ENV STUDIO_PORT=8765
|
||||||
|
|
||||||
# ── Optional: Go toolchain ───────────────────────────────────────────
|
# ── Optional: Go toolchain ───────────────────────────────────────────
|
||||||
|
|||||||
@@ -261,10 +261,11 @@ publish. Keep the publish on `127.0.0.1:` as in B: anyone who can reach the
|
|||||||
port and has the full URL controls Studio, including running prompts and
|
port and has the full URL controls Studio, including running prompts and
|
||||||
reading or writing files, and there is no TLS.
|
reading or writing files, and there is no TLS.
|
||||||
|
|
||||||
> **Use B or C on a port, not both.** With `STUDIO_EXPOSE=1` the bridge holds
|
> **Use B or C on a port, not both.** Whichever starts second fails with
|
||||||
> the container's egress IP on `$STUDIO_PORT` from boot, and `--listen-all` on
|
> `EADDRINUSE`: `0.0.0.0` includes the egress IP the bridge binds. With
|
||||||
> that same port fails with `EADDRINUSE` (`0.0.0.0` includes that address).
|
> `STUDIO_EXPOSE=1` the bridge holds `$STUDIO_PORT` from boot, so
|
||||||
> If the bridge is running, start Studio *without* `--listen-all`.
|
> `/studio --listen-all --port 8765` fails. If the bridge is running, start
|
||||||
|
> Studio *without* `--listen-all`.
|
||||||
|
|
||||||
### Remote host (SSH / mosh)
|
### Remote host (SSH / mosh)
|
||||||
|
|
||||||
|
|||||||
@@ -3,13 +3,17 @@
|
|||||||
# through a published Docker port.
|
# through a published Docker port.
|
||||||
#
|
#
|
||||||
# WHY THIS EXISTS
|
# WHY THIS EXISTS
|
||||||
# pi-studio hard-binds its HTTP/WebSocket server to 127.0.0.1 inside the
|
# By default pi-studio binds its HTTP/WebSocket server to 127.0.0.1 inside
|
||||||
# container (index.ts: `.listen(port, "127.0.0.1")`) and there is no
|
# the container. A plain `docker run -p 8765:8765` forwards to the
|
||||||
# --host / bind flag. A plain `docker run -p 8765:8765` forwards to the
|
|
||||||
# container's EXTERNAL interface (eth0), not its loopback, so it cannot
|
# container's EXTERNAL interface (eth0), not its loopback, so it cannot
|
||||||
# reach Studio. This helper runs a socat TCP relay that listens on the
|
# reach a default Studio. This helper runs a socat TCP relay that listens
|
||||||
# container's egress IP and forwards to 127.0.0.1:<port>, so a published
|
# on the container's egress IP and forwards to 127.0.0.1:<port>, so a
|
||||||
# port (and an `ssh -L` tunnel from your laptop) can reach Studio.
|
# published port (and an `ssh -L` tunnel from your laptop) can reach Studio.
|
||||||
|
#
|
||||||
|
# The alternative (pi-studio >= 0.9.60) is `/studio --listen-all`, which
|
||||||
|
# binds 0.0.0.0 and needs no bridge. Use one or the other on a port, never
|
||||||
|
# both: whichever starts second fails with EADDRINUSE (0.0.0.0 includes
|
||||||
|
# the egress IP this relay binds).
|
||||||
#
|
#
|
||||||
# SECURITY
|
# SECURITY
|
||||||
# This intentionally exposes Studio beyond loopback — anything that can
|
# This intentionally exposes Studio beyond loopback — anything that can
|
||||||
@@ -34,7 +38,7 @@ set -euo pipefail
|
|||||||
PORT="${1:-${STUDIO_PORT:-8765}}"
|
PORT="${1:-${STUDIO_PORT:-8765}}"
|
||||||
|
|
||||||
if [ "$PORT" = "--help" ] || [ "$PORT" = "-h" ]; then
|
if [ "$PORT" = "--help" ] || [ "$PORT" = "-h" ]; then
|
||||||
sed -n '2,31p' "$0" | sed 's/^# \{0,1\}//'
|
sed -n '2,35p' "$0" | sed 's/^# \{0,1\}//'
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -356,8 +356,8 @@ window: 0". Leave the indexing alone in this environment.
|
|||||||
## 7. pi-studio reachability (only in the `-studio` variant)
|
## 7. pi-studio reachability (only in the `-studio` variant)
|
||||||
|
|
||||||
Present only if `/opt/pi-studio` exists / the `studio_*` tools are in your tool
|
Present only if `/opt/pi-studio` exists / the `studio_*` tools are in your tool
|
||||||
list. pi-studio **binds to `127.0.0.1` inside the container** with no host-bind
|
list. By default pi-studio **binds to `127.0.0.1` inside the container**, so a
|
||||||
flag, so a plain `docker -p` publish can't reach it. Two supported paths:
|
plain `docker -p` publish can't reach it. Three supported paths:
|
||||||
|
|
||||||
- **Host networking** (`network_mode: host`): container loopback == host
|
- **Host networking** (`network_mode: host`): container loopback == host
|
||||||
loopback; open the tokenized URL on the host. (Changes
|
loopback; open the tokenized URL on the host. (Changes
|
||||||
@@ -365,10 +365,25 @@ flag, so a plain `docker -p` publish can't reach it. Two supported paths:
|
|||||||
- **`studio-expose` bridge** (`STUDIO_EXPOSE=1` or run `studio-expose &`): a
|
- **`studio-expose` bridge** (`STUDIO_EXPOSE=1` or run `studio-expose &`): a
|
||||||
`socat` relay from the container's external interface to its loopback, so a
|
`socat` relay from the container's external interface to its loopback, so a
|
||||||
published `127.0.0.1:PORT` + `ssh -L PORT:127.0.0.1:PORT host` reaches it.
|
published `127.0.0.1:PORT` + `ssh -L PORT:127.0.0.1:PORT host` reaches it.
|
||||||
|
- **`/studio --listen-all`** (pi-studio ≥ 0.9.60): binds `0.0.0.0`, so the
|
||||||
|
published port reaches it with no bridge; the printed URL still says
|
||||||
|
`127.0.0.1`. **Never on the same port as the bridge**: whichever starts
|
||||||
|
second fails with `EADDRINUSE`. `ss -ltnp | grep ":$STUDIO_PORT"` showing a
|
||||||
|
`socat` line means the bridge is up, so start Studio without `--listen-all`.
|
||||||
|
|
||||||
The real auth token comes from the `/studio` slash command (`/studio --status`
|
The real auth token comes from the `/studio` slash command (`/studio --status`
|
||||||
to reprint), **not** from `studio-expose`. For Graphviz, use `dot-watch` →
|
to reprint), **not** from `studio-expose`. Hand over the **whole** printed
|
||||||
PNG (Studio renders Mermaid natively and previews PNG, but not SVG/DOT).
|
URL: since pi-studio 0.10 it also carries `studioTabState` + `hostedWorkspace`
|
||||||
|
(or `docPath`/`watchFile`/… for `--watch`), and a token-only URL is answered
|
||||||
|
`409`. The URL wraps across TUI lines; if a side panel's text lands inside the
|
||||||
|
copy, Studio answers *"This link looks damaged…"*. Studio must run on the
|
||||||
|
**published** port (only the laptop side of `ssh -L` is free to choose), and
|
||||||
|
`--port` on a running server only warns, so `/studio --stop` first. On the
|
||||||
|
Docker host, `curl -s http://127.0.0.1:$STUDIO_PORT/` answering `403` means
|
||||||
|
the chain is up; an empty reply means Studio is down or on another port.
|
||||||
|
|
||||||
|
For Graphviz, use `dot-watch` → PNG (Studio renders Mermaid natively and
|
||||||
|
previews PNG, but not SVG/DOT).
|
||||||
|
|
||||||
## 8. MemPalace is the shared brain
|
## 8. MemPalace is the shared brain
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user