# Running a shared server `noodlelab serve` on your own machine needs no setup: no logins, one local user. This page is for a server other people use. ## Which pages may use the server A browser lets any website send requests to a server on your machine, so the server checks where they come from: - **Without logins** (the default on your own machine), it answers only to this machine's names: `localhost`, a loopback address and the `--host` it was started with. With `--host 0.0.0.0 --auth none` it also answers to IP addresses, so reach it from other machines as `http://192.168.1.5:8000`, not by a host name. This stops DNS rebinding, where another site points its own name at your machine. - **Pages from other websites** cannot open the editor's WebSocket or save, run, upload or delete anything: those requests must come from the editor's own page. On a shared server, the page's host name must be the one the request was sent to (`Host`, or `X-Forwarded-Host` from a reverse proxy that rewrites `Host`). Programs (the CLI, the MCP server, scripts) send no `Origin` header and are not affected. ## Roles and guest links On a shared server (`--auth users`), each person has one role in each workspace. A workspace is a project, and its managers are the project managers. | Role | Can | |---|---| | **Viewer** | Open graphs, browse files, and look at runs and reports. | | **Runner** | Everything a viewer can, plus run graphs and export them to Python. | | **Editor** | Everything a runner can, plus change and save graphs, upload files and copy examples. | | **Manager** | Everything an editor can, plus add members, set roles, create guest links, and finalise or delete anyone's runs. | Where roles are set: - **Admins** are managers of every workspace. They set members and roles under **Admin → Workspaces → Share…**. - **Managers** do the same from the editor, with **Members…** in the top bar. - **Everyone else signed in** gets a workspace's default role. It can be *no access*, which means the workspace is for members only. - A user who adds their own folder, when **allow user workspaces** is on, becomes its manager, and nobody else can open it until they share it. The folder may not contain or lie inside another workspace, the server's home or its scratch, checkpoint and mount folders. A **guest link** gives someone without an account view-only or view-and-run access to one workspace. It lasts until it expires (at most 30 days by default) or is revoked. Only a hash of its token is stored, so the link is shown once, when it is made. Guest links can be turned off in **Admin → Settings**. The server enforces all of these rules. In the editor, viewers and runners get a read-only canvas marked *View only* or *Run only*. **Files stay inside the workspace.** On a shared server, graphs, previews and the file browser reach only the workspace's own folder and the mounts an admin configured, for admins too. Absolute paths (`/data/run1.csv`), `~` and paths that leave the workspace (`../other-project`) are refused, so one workspace cannot read another's files or the server's `config.json`. To share a folder on the server, add it as a mount (see [Remote storage](#remote-storage)). Servers upgraded from earlier versions: graphs that used absolute paths such as `/data/...` need them changed to a mount (`data://...`). ## Remote storage Admins can mount S3, Google Cloud Storage, Azure, SFTP or a network share under a short name that graphs use in file paths (`lab-s3://2026/run1.csv`), for every workspace or only some. [Remote storage](storage.md) explains how. A folder on the server itself is a mount too, with the URL `local:///data/shared`: on a shared server this is the only way to reach files outside a workspace. ## Slurm clusters A shared server can send runs to a Slurm cluster as batch jobs. Turn it on under **Admin → Cluster**: set the partition, account, time limit and resources, add setup lines such as `module load`, and press **Test connection**. People who may run graphs then get a **Run on** menu next to **Run**, with the choices *On the server* and *On the cluster*. A cluster run looks the same in the editor: progress, previews and reports show up as usual, with the job state (*Slurm job 1234 · pending*) until it starts, and **Stop** cancels the job. It needs: - the workspaces on a file system shared with the compute nodes; - noodlelab installed where the jobs run; - a server that can run `sbatch`, directly or through `ssh`. [docs/slurm.md](slurm.md) explains the setup and what a job looks like. ## Docker ```bash docker build -t noodlelab . docker run -d -p 8000:8000 -v noodlelab-data:/data \ -e NOODLELAB_ADMIN_TOKEN='' noodlelab ``` Or run `make docker-up` (`docker compose up -d --build`, with the version taken from the git tag) with `NOODLELAB_ADMIN_TOKEN` set in `.env`; plain `docker compose` builds report version 0.0.0. The compose file also installs Claude Code for the **Agent** panel. For a public demo, set `NOODLELAB_DEMO=1`, which gives you guests only, one run at a time and a 25 MB file limit. [`render.yaml`](../render.yaml) deploys it on Render's free plan. ## The Agent panel on a shared server The **Agent** panel runs Claude Code or Codex CLI as the server's user, so it is offered to admins only when logins are on, never on a demo server (`NOODLELAB_DEMO=1`), and only while **Admin → Settings → agent terminal** is on. Each agent session gets an API token of its own, revoked when the session ends.