Open a port as an app#
Anything you run in a runtime that serves HTTP — TensorBoard, a Streamlit
or Gradio demo, Spark's UI — opens in your browser at an address of its
own, r-<id>-<port>.<domain>. Nothing is opened on the machine: the
machine's own outbound connection carries it, and it connects to the port
inside the container.
Before you begin#
- A running environment, or a notebook's runtime (Ready or
Starting). A stopped one answers
409 RUNTIME_NOT_RUNNING: start it first. - To be its owner, one of the people it is shared with, or an admin of the workspace — the same people may open its apps.
- The server must listen on a port of the container, on any of its
addresses:
127.0.0.1is enough. Not port 2222 (SSH), nor the runtime's own server: 8888 in a notebook's runtime (Jupyter: open the notebook), 8822 in an IDE environment (the IDE: Open IDE). - For the CLI tabs,
astrasigned in (Install the CLI); for the API tabs,ASTRAEUS_TOKEN,CONSOLEandAPIas in Create and change a runtime.
1. Start the server in the runtime#
In a terminal of the runtime (astra ssh dev, an IDE terminal, or a
notebook cell with !), start the server in the background. For example,
in an environment of the PyTorch preset made with
--pip tensorboard==2.21.0 --pip streamlit==1.64.0 --pip gradio==6.29.0:
An app receives no cookies, so Streamlit's upload protection (its XSRF check) must be off:
$ mkdir -p /content/projects && cd /content/projects
$ cat > app.py <<'EOF'
import streamlit as st
st.title("Hello from the GPU machine")
n = st.slider("Points", 10, 1000, 100)
st.line_chart([i * i for i in range(n)])
EOF
$ nohup ~/.local/bin/streamlit run app.py --server.port 8501 --server.headless true \
--server.enableXsrfProtection false > streamlit.log 2>&1 &
2. Open it#
- Open the environment's page (Hesperus → Environments → the environment; for a notebook's runtime with SSH, Connect in Hesperus → Runtimes).
- Under Apps, press Open port…. The dialog suggests TensorBoard · 6006 for the deep learning presets, Spark UI · 4040 for Spark, and Streamlit · 8501 and Gradio · 7860 for any.
- Enter the Port and, optionally, a Name. Remember it on this environment (checked) lists it under Apps with an Open button.
- Press Open. It opens in a new tab at its own address.
Forget takes an app off the list; the app keeps running.
$ astra env port dev 6006 --as TensorBoard
Opened https://r-4f1c9a0b2d7e83a65c10-6006.<runtime domain>
$ astra env port dev 8501 --print
https://r-4f1c9a0b2d7e83a65c10-8501.<runtime domain>/__astralyx/enter?ticket=ast_rtt_…
(works once, within a minute: it signs the browser that opens it in to https://r-4f1c9a0b2d7e83a65c10-8501.<runtime domain> only)
astra env port <runtime> <port> takes any runtime you may use, a
notebook's included. --as <name> also remembers it under that name
(listed on the environment's page); --print prints the link instead
of opening a browser — it works once, within a minute.
Name apps on the runtime (the list replaces the previous one; at most 16, names at most 40 characters):
$ curl -fsS -X PUT "$API/notebook-runtimes/dev/apps" -H "Authorization: Bearer $ASTRAEUS_TOKEN" \
-H 'content-type: application/json' \
-d '{"apps": [{"name": "TensorBoard", "port": 6006}, {"name": "Streamlit", "port": 8501}]}' | jq '.spec.apps'
And ask for a link into one (any port, named or not):
$ curl -fsS -X POST "$CONSOLE/clusters/<cluster>/runtime-links" -H "Authorization: Bearer $ASTRAEUS_TOKEN" \
-H 'content-type: application/json' -d '{"runtime": "dev", "port": 6006}' | jq '{url, origin, expires_at}'
The url works once, within a minute; the browser that follows it is
signed in to that address for 8 hours.
Who reaches an app#
The same people as the runtime: its owner, the people it is shared with and the workspace's admins, each signed in with their own account. Taking someone off the runtime's people refuses their next request. Each address is signed in separately, for 8 hours; open it again from the console after that.
What an app may not rely on:
- Cookies. No cookie reaches an app, and none it sets reaches the browser. Apps that need their own (Streamlit's upload protection) run without it.
- Being framed or called from another site. An app's pages are not shown inside other sites, and cross-origin requests to it are refused.
- Raw TCP. Only HTTP and WebSockets. For anything else, forward the port over SSH (Use ssh, scp and rsync).
Requests to an app are activity: an app in use keeps the runtime from stopping as idle.