TL;DR
Access Points on same network
If you are on the same network:
http://camelot:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
If you're Frodo from the Sh1re, you can tunnel in:
ssh -L 8888:localhost:8888 tux@camelot
Then on Frodo:
http://localhost:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
🗺️ Where We Are
You are Frodo, traveling from the Sh1re to Camelot (your Fedora 42 server). Camelot is:
- Running locally or privately (no external certs),
- About to be taught the Magic of Jupyter by Frodo,
- Already home to a TransferDepot, a RESTful Flask API that successfully handles secure file exchanges with Distant Lands.
📜 Today's Mission (on Camelot)
-
Get Jupyter running and prepare it as a demo tool:
- Teach Camelot how to visualize, prototype, and share insights.
- Output shall be exported and made publishable — a means of knowledge transfer.
-
Learn from Camelot’s REST API success:
- A working Flask app with clean routing for file handling.
-
Likely a simpler version of
app.pyfrom the Sh1re’s Transfer UI. - Used in production or testing on Camelot to handle uploads/downloads.
-
Document the exchange:
- What Jupyter enables (interactive experiments),
- What the Flask API handles (reliable document transit),
- How this exchange can continue between the Sh1re and Distant Lands — even those stuck in the Age of TLSv1 (Firefox 1.5, the stuff of myth).
🏰 Tomorrow’s Plan (Back in the Sh1re)
-
Register an
api.sh1resubdomain to match the realm's DNS magic. - Move the Flask app (based on what worked in Camelot) behind the Sh1re’s Nginx reverse proxy.
-
Prove it can:
- Accept file uploads from virtca8 (now also in the Sh1re),
- Serve files cleanly and securely,
-
Survive the treacherous translation from
localhost:8080→https://api.sh1re/...
✨ Summary of What’s Needed Today
| Component | Role |
| --------------------- | ---------------------------------------------------- |
| `jupyter` | Taught to Camelot by Frodo |
| `notebook_test.ipynb` | Proof of Jupyter’s utility |
| `app.py` (simplified) | REST API showing current file exchange success |
| Export/Transfer Test | How to pass data from Jupyter to the TransferDepot |
| Notes & Export Paths | For Frodo to bring back to the Sh1re for review/demo |
The path is clear, and this mission both teachable and demonstrable to all who govern knowledge in the realm of the Sh1re.
jupyter server --ip=0.0.0.0 --no-browser
tux@camelot:~$ jupyter server --ip=0.0.0.0 --no-browser
[I 2025-07-20 12:15:58.705 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2025-07-20 12:15:58.707 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2025-07-20 12:15:58.710 ServerApp] jupyterlab | extension was successfully linked.
[I 2025-07-20 12:15:58.712 ServerApp] notebook | extension was successfully linked.
[I 2025-07-20 12:15:58.854 ServerApp] notebook_shim | extension was successfully linked.
[I 2025-07-20 12:15:58.864 ServerApp] notebook_shim | extension was successfully loaded.
[I 2025-07-20 12:15:58.865 ServerApp] jupyter_lsp | extension was successfully loaded.
[I 2025-07-20 12:15:58.866 ServerApp] jupyter_server_terminals | extension was successfully loaded.
[I 2025-07-20 12:15:58.867 LabApp] JupyterLab extension loaded from /usr/lib/python3.13/site-packages/jupyterlab
[I 2025-07-20 12:15:58.867 LabApp] JupyterLab application directory is /usr/share/jupyter/lab
[I 2025-07-20 12:15:58.868 LabApp] Extension Manager is 'pypi'.
[I 2025-07-20 12:15:58.876 ServerApp] jupyterlab | extension was successfully loaded.
[I 2025-07-20 12:15:58.878 ServerApp] notebook | extension was successfully loaded.
[I 2025-07-20 12:15:58.878 ServerApp] Serving notebooks from local directory: /home/tux
[I 2025-07-20 12:15:58.878 ServerApp] Jupyter Server 2.15.0 is running at:
[I 2025-07-20 12:15:58.878 ServerApp] http://camelot:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
[I 2025-07-20 12:15:58.878 ServerApp] http://127.0.0.1:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
[I 2025-07-20 12:15:58.878 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 2025-07-20 12:15:58.880 ServerApp]
To access the server, open this file in a browser:
file:///home/tux/.local/share/jupyter/runtime/jpserver-45505-open.html
Or copy and paste one of these URLs:
http://camelot:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
http://127.0.0.1:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794
[I 2025-07-20 12:15:58.892 ServerApp] Skipped non-installed server(s): bash-language-server, dockerfile-language-server-nodejs, javascript-typescript-langserver, jedi-language-server, julia-language-server, pyright, python-language-server, python-lsp-server, r-languageserver, sql-language-server, texlab, typescript-language-server, unified-language-server, vscode-css-languageserver-bin, vscode-html-languageserver-bin, vscode-json-languageserver-bin, yaml-language-server
[W 2025-07-20 12:55:48.138 ServerApp] Clearing invalid/expired login cookie username-camelot-8888
🧭 Orientation: What We See from Camelot
✅ Jupyter Server is Up and Running
- Version: Jupyter Server 2.15.0
-
IP Binding:
--ip=0.0.0.0means it’s listening on all interfaces -
Port:
8888 -
Auth: Using token-based access (
?token=...) -
Serving From:
/home/tux/— this is the root for all notebooks -
Control Shortcut: Press
Ctrl+Ctwice to cleanly shut it down.
🌐 Where to Access It From
If you're on the same network:
http://camelot:8888/?token=6731e677bd79a997c5fac158161c967049cf88704a569794If you're Frodo from the Sh1re, you can tunnel in:
ssh -L 8888:localhost:8888 tux@camelotThen on Frodo:
http://localhost:8888/?token=...🧙♂️ Installed Extensions (Jupyter Powers)
These were successfully linked and loaded:
-
jupyterlab— modern UI (try/labafter the port) -
notebook— the classic UI -
jupyter_lsp— Language Server Protocol support -
jupyter_server_terminals— access to a terminal inside the browser
⚠️ Warnings and Skipped Services
[W] Clearing invalid/expired login cookie username-camelot-8888
Not a problem. Just expired session data — common when switching tokens or restarting.
[I] Skipped non-installed server(s): ...
Also fine. Jupyter is just listing LSPs (language plugins) that aren't installed. You can install them later if you want advanced code intelligence, but this does not affect core functionality.
🧪 Sunday Tour Guide
Here’s a suggested roadmap for today:
🟢 1. Create a Test Notebook
In /home/tux, click New → Python 3 and create:
print("Frodo lives, and Camelot listens.")Add a markdown cell:
# Orientation Day at Camelot
This is a test of the Jupyter Notebook service hosted at Camelot.🟢 2. Export It
Once saved, from Jupyter UI:
- File → Download as → HTML or Markdown
Or from terminal:
jupyter nbconvert notebook.ipynb --to html🟢 3. Test Integration with Flask (optional)
If you have Camelot’s TransferDepot Flask API running locally:
import requests
files = {'file': open('notebook.html', 'rb')}
response = requests.post('http://localhost:5000/upload', files=files)
print(response.status_code, response.text)Or reverse — GET a file and show inside Jupyter.
🟢 4. Confirm What Works
Use the cousin inside Camelot to:
-
Open a browser and verify
http://camelot:8888/works - Copy/paste a notebook into the transfer depot
- Confirm that file upload, download, and directory listing all work
When Frodo returns to the Sh1re tomorrow, he shall bring:
- Exported notebook as proof
- API examples from Camelot
- Confidence that Jupyter + Flask can co-exist and collaborate
- And perhaps… a sticky note that says: "Containers next week?"
Let me know when you're ready for the Return of the Kernel notebook template, or if you'd like a Flask skeleton app to sketch the TransferDepot out.
A noble decision, Frodo! A small workspace called sh1re will bring structure to this otherwise scroll-littered desktop. And yes — the “Lab” tab can be overwhelming and strange when no familiar landmarks are set.
Let us fix that now.
The Key to Camelot fails to open the Gateway
allison@frodo:~$ ssh -L 8888:localhost:8888 tux@10.20.30.1
tux@10.20.30.1's password:
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Sun Jul 20 13:27:11 2025 from 10.20.30.1
Replace the key
tux@camelot:~/sh1re$ jupyter notebook --NotebookApp.allow_origin='*' --ip=0.0.0.0 --no-browser
[I 2025-07-20 14:12:20.452 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2025-07-20 14:12:20.454 ServerApp] jupyter_server_terminals | extension was successfully linked.
[I 2025-07-20 14:12:20.615 LabApp] Extension Manager is 'pypi'.
[I 2025-07-20 14:12:20.624 ServerApp] jupyterlab | extension was successfully loaded.
[I 2025-07-20 14:12:20.626 ServerApp] notebook | extension was successfully loaded.
[I 2025-07-20 14:12:20.626 ServerApp] Serving notebooks from local directory: /home/tux/sh1re
[I 2025-07-20 14:12:20.626 ServerApp] Jupyter Server 2.15.0 is running at:
[I 2025-07-20 14:12:20.626 ServerApp] http://camelot:8888/tree?token=2eef7915de4f8d75bd36428a5662316839ea37e680d3969c
[I 2025-07-20 14:12:20.626 ServerApp] http://127.0.0.1:8888/tree?token=2eef7915de4f8d75bd36428a5662316839ea37e680d3969c
[I 2025-07-20 14:12:20.626 ServerApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).
[C 2025-07-20 14:12:20.628 ServerApp]
Find the key:
tux@camelot:~/sh1re$ jupyter server list
http://localhost:8888/tree
😄 A hush falls over the Sh1re as the fire crackles... and someone—maybe Sam—leans in:
“Did I ever tell you about the time...
Things We Never Speak Of Again: The Day We SSH’d Into Ourselves?”
The table bursts into laughter.
Tux spills his ale.
Even Gandalf chuckles without saying a word.
Did you get all that?
Nothing listening?
On Camelot:
-
Nothing is listening on port
8888, confirmed by:
sudo lsof -i :8888
sudo netstat -tulnp | grep 8888
So the tunnel opens, but when you try to use it, it tries to connect to localhost:8888 on Camelot, fails, and floods you with:
channel 3: open failed: connect failed: Connection refusedssh back in & restart:
ssh -L 8888:localhost:8888 tux@10.20.30.1
jupyter server list
tux@camelot:~$ jupyter server list
Currently running servers:Restart Notebook server
jupyter notebook --NotebookApp.allow_origin='*' --ip=0.0.0.0 --no-browserRecheck server list
jupyter server list
tux@camelot:~$ jupyter server list
Currently running servers:
http://camelot:8888/?token=310d92483c9e435e737009b23f6a52c419e7efc153f34d16 :: /home/tuxRe-tunnel from Frodo:
ssh -L 8888:localhost:8888 tux@10.20.30.1
Open in Browser:
http://localhost:8888/?token=...
allison@frodo:~/dev/TransferPoint$ ssh -L 8888:localhost:8888 tux@10.20.30.1
tux@10.20.30.1's password:
Activate the web console with: systemctl enable --now cockpit.socket
Last login: Sun Jul 20 15:52:42 2025 from ::ffff:192.168.11.185
tux@camelot:~$ jupyter server list
Currently running servers:
tux@camelot:~$ jupyter notebook --NotebookApp.allow_origin='*' --ip=0.0.0.0 --no-browser
[I 2025-07-20 19:51:48.977 ServerApp] jupyter_lsp | extension was successfully linked.
[I 2025-07-20 19:51:48.979 ServerApp] jupyter_server_terminals | extension was successfully linked.
[W 2025-07-20 19:51:48.980 LabApp] 'allow_origin' has moved from NotebookApp to ServerApp. This config will be passed to ServerApp. Be sure to update your config before our next release.
[I 2025-07-20 19:51:48.982 ServerApp] jupyterlab | extension was successfully linked.
[I 2025-07-20 19:51:48.984 ServerApp] notebook | extension was successfully linked.
💬 Bonus: Reduce the Noise
If this keeps happening, you can add -v or -vvv to SSH for verbose logs, or redirect stderr to a log file so it doesn’t flood your terminal:
ssh -L 8888:localhost:8888 tux@10.20.30.1 2> ssh_tunnel.log
🏗️ Create or navigate to the Sh1re Workspace
📁 1. Create the Folder
From your shell:
mkdir -p /home/tux/sh1re
Now you have a clean little corner of Camelot where all .ipynb, .html, .md, and Flask scrolls can live together.
💻 2. Place the Notebook There
Let’s drop the notebook directly into this new realm:
Option A: Use CLI to write it from Frodo
If you copied the return_of_the_kernel.ipynb earlier:
scp return_of_the_kernel.ipynb tux@camelot:/home/tux/sh1re/Option B: Create a blank file and paste in contents
nano /home/tux/sh1re/return_of_the_kernel.ipynb
Then paste the JSON I gave earlier. Save with Ctrl+O, exit with Ctrl+X.
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# The Return of the Kernel\n",
"\n",
"*A notebook forged in Camelot by Frodo, emissary of the Sh1re.*"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"print(\"Camelot lives, and Frodo rides once more!\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## The Wisdom of Visualization\n",
"\n",
"Here lies a chart, rendered to show the passage of time and wisdom gained."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"\n",
"x = [1, 2, 3, 4]\n",
"y = [1, 4, 2, 3]\n",
"\n",
"plt.plot(x, y, marker='o')\n",
"plt.title(\"A Chart Worthy of the Realm\")\n",
"plt.xlabel(\"Scroll Pages\")\n",
"plt.ylabel(\"Wisdom Gained\")\n",
"plt.grid(True)\n",
"plt.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Final Notes\n",
"\n",
"- ✅ Jupyter runs in Camelot\n",
"- ✅ Plots render\n",
"- ✅ Markdown flows like elvish poetry\n",
"- ✅ The Sh1re shall receive this tale\n",
"\n",
"**Farewell for now, until the next test of the Flasken Scrolls.**"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"name": "python",
"version": "3.13"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
🧠 3. Access It in Jupyter UI
Now when you open:
http://camelot:8888/tree/sh1re/You’ll see:
return_of_the_kernel.ipynbOpen it, run the cells, and export when ready.
🧭 A Quick Word on “Launcher” and Tabs
- Launcher: That’s the Lab UI’s quickstart screen — like a dashboard. You’ll find New Notebook, New Console, Terminal, etc.
-
Tree View (Classic): What you're looking for now — a simple file browser. Stick to
http://camelot:8888/tree/for clarity. - Tabs: If you see nothing at first, click the “folder” icon (top left) to browse the file tree. Or open the direct folder above.
🛡️ Summary Boost
mkdir -p ~/sh1re
nano ~/sh1re/return_of_the_kernel.ipynb # (paste in content or use scp)
Then visit:
http://camelot:8888/tree/sh1re/
Open the notebook, and run:
print("Camelot lives, and Frodo rides once more!")Let me know if you’d like a Flask scroll to join the sh1re folder next. The quest continues.
🔧 Prepare the Flask
-
A TransferDepot ready for distant lands
-
Routes for:
-
POST /upload -
GET /files/<filename> -
GET /listor/index
-
🔐 Add Protection
-
Path restrictions?
-
Token header?
-
Maybe even a tiny logbook (
upload.log)?
📦 Integration with:
-
Notebook exports from Jupyter
-
Downloads to Fred
-
Possibly... redirection to
/shire/success.html
tux@camelot:~/sh1re$ flask routes
Endpoint Methods Rule
----------- ------- -----------------------
get_file GET /files/<filename>
list_files GET /list
static GET /static/<path:filename>
upload_file POST /upload
welcome GET /
🗺️ The RESTful Map of TransferPoint
| 🌐 **URL Path** | 🧙♂️ **Method** | ⚙️ **Handler Function** |
| ------------------- | ---------------- | ----------------------- |
| `/` | `GET` | `welcome` |
| `/upload` | `POST` | `upload_file` |
| `/list` | `GET` | `list_files` |
| `/files/<filename>` | `GET` | `get_file` |
| `/static/<path>` | `GET` | Flask static route |
✅ What This Means
You have a classic file exchange interface:
-
GET /→ Welcome page (perhaps a UI? or JSON message?) -
POST /upload→ Upload files -
GET /list→ Show all available files -
GET /files/<filename>→ Retrieve a specific file -
GET /static/...→ Serve static assets (if applicable)
For test or DEMO
curl http://localhost:5000/
curl http://localhost:5000/list
curl -F 'file=@test.txt' http://localhost:5000/upload