Feat: remote deployment support and coral-remote-server in docker-compose#187
Conversation
…ume mount - docs: add docs/remote-setup.md with end-to-end guide for connecting the Electron app to CORAL + Slurm containers on a real remote machine over SSH - docs: add Remote + Coral (real machine) row to README execution modes table - chore: replace Docker build secret with volume mount for SSH authorized_keys in both Dockerfile.coral and docker-compose.yml - chore: remove secrets section from docker-compose.yml - docs: update CHANGELOG under [Unreleased]
- feat: add coral-remote-server service to docker-compose.yml - chore: use directory volume mount for SQLite database to avoid Docker file-mount pitfall - docs: update CHANGELOG under [Unreleased]
- fix: mount public key to /tmp/ssh_key.pub instead of directly as authorized_keys - fix: copy key with correct root ownership and 600 permissions in entrypoint
- chore: add .env to .gitignore (machine-specific SSH key path)
- chore: use ${SSH_PUB_KEY_PATH} variable in docker-compose volume mount
- docs: simplify remote-setup guide to 7 steps, remove Dockerfile/docker-compose edit instructions
- docs: mention .env machine-agnostic SSH key path in changelog entry
- docs: replace -j$(nproc) with -j4 in all four build guides
- docs: replace "adjust docker-compose.yml" instruction with .env creation step in run-coral-docker.md - docs: add port 8080 to SSH tunnel command in remote-setup.md (coral-remote-server)
- chore: use :? syntax in docker-compose so missing SSH_PUB_KEY_PATH gives a clear error - chore: add committed .env.example template that developers copy to .env - docs: update run-coral-docker.md and remote-setup.md to reference .env.example
Visualizer performance analysis — remote vs localContext: coral-visualizer issue #34 documents 11 bottlenecks (B1–B11) in edit-session performance on large meshes. This PR introduces the remote deployment architecture (SSH tunnel → containers on a cluster node) described in 1. OSMesa (software rendering) — and why the hidden window mattersWhen the app is run locally without a container on Ubuntu, ParaView obtains a real X11 display and uses hardware OpenGL via GLX. The extra VTK window that appears is the GPU-backed render surface. When that window is hidden or minimized:
The benchmark slowdowns observed locally with the window hidden are therefore a faithful proxy for container performance — both paths hit the Mesa software renderer. "Window visible = faster" means GPU rendering; "window hidden = slower" means software fallback. Fix — use EGL offscreen rendering instead of OSMesa. If there is truly no GPU on the node, Mesa's software EGL is still at least as fast as OSMesa and often faster because it uses a more modern pipeline. 2. Trame's default mode is server-side image streaming — devastating over SSHThe more fundamental problem for the remote scenario is the network protocol Trame uses by default. The current setup has no Each rendered frame for a large mesh is a high-resolution JPEG (potentially hundreds of KB). Over an SSH tunnel with real network RTT, every mouse interaction triggers a full round-trip plus an image download. This dominates interactive latency — not computation, but image streaming. Fix — switch to client-side (local) rendering. In trame-vtk this is controlled by using The tradeoff: the client GPU must be capable of rendering the mesh. For a 5.6 M-cell mesh this is fine on any modern laptop GPU; the geometry serialization is a one-time cost per data change. 3. pvserver + MPI — parallelizing the VTK pipelineCurrently With
How to wire pvserver into the current app: In the container entrypoint, before starting mpirun -np 4 pvserver --server-port=11111 --force-offscreen-rendering &Then in simple.Connect("localhost", 11111)Everything else — When pvserver runs on the same machine as the trame container, the pvserver↔app link is a Unix socket or localhost TCP (effectively zero latency). The Fetch cost is then purely serialization/deserialization, not network I/O. This is the ideal setup: pvserver and trame in the same container host, browser connects via the SSH tunnel. 4. SSH tunnel bandwidth and compressionThe tunnel command in If staying with server-side rendering in the short term:
5. Production settings checklist
Summary
The highest-leverage single change for the remote scenario is switching to |
Overview
The Electron app always connects to
localhost:2222(SSH),localhost:8008(visualizer), andlocalhost:8080(remote server). Whether it reaches a local Docker container or a real HPC cluster is purely a network concern — the app settings never change. Opening an SSH tunnel is all it takes to switch from local to remote.Local (containers running on your machine)
Remote (SSH tunnel open to the cluster)
The tunnel is opened with a single command; no configuration change in the app is needed:
The SSH public key injected into the container is configured via a gitignored
.envfile (SSH_PUB_KEY_PATH), so the samedocker-compose.ymlworks on any machine without modification. A.env.exampleis committed as a template.Shared data directory permissions
The
containers/shared-datadirectory is created owned by the host user. Thecoral-visualizercontainer runs asmambauser(a non-root user baked into the micromamba base image) whose UID does not match the host user, so it falls into the "other" category and cannot write. This applies on any host — local or remote — since the UID mismatch is between the host user and the image-definedmambauser, not a property of the machine. The fix is a one-timechmod a+w containers/shared-data, documented in bothdocs/run-coral-docker.mdanddocs/remote-setup.md.A named Docker volume would also solve the UID mismatch — Docker manages ownership internally so any container user can write regardless of UID. However, named volumes are stored in
/var/lib/docker/volumes/and are not directly accessible from the host filesystem, which means grid files and VTK outputs produced by CORAL would requiredocker execor a temporary container to extract, copy, or back up. Since the shared data directory is also the working directory where the Electron app uploads graphs and downloads results via SSH, a bind mount is more practical for day-to-day use.Summary
docs/remote-setup.md: step-by-step guide for connecting the app to CORAL + Slurm containers on a real remote machine via SSH tunnel/tmp/ssh_key.pub) copied intoauthorized_keysby the container entrypoint — fixes ownership issues that caused publickey auth failures.env(SSH_PUB_KEY_PATH);.env.examplecommitted as a template;docker-compose.ymlfails fast with a clear error if the variable is unsetcoral-remote-serveradded to the maindocker-compose.ymlso a singledocker compose upstarts the full stack (SSH+Slurm, visualizer, remote server)coral-remote-serverupdated to include thedata/directory volume mount andDB_PATHenv var fixchmod a+w containers/shared-datastep and steps renumbered accordinglyTest plan
docker compose up -d --buildstarts all three containers cleanly (locally and on cluster)ssh -p 2222 root@localhost 'echo hello'succeeds after containers starthttp://localhost:8008in both local and tunnelled setupsdocker compose upwithout a.envfile prints a clear error messagechmod a+w containers/shared-dataon the remote host