zyratlo opened a new pull request, #7932:
URL: https://github.com/apache/texera/pull/7932

   ### What changes were proposed in this PR?
   The notebook migration tool shipped its backend service and workspace UI, 
but nothing deployed them. This PR makes the tool work out of the box in the 
single-node Docker Compose stack: it publishes images for the service and for 
the customized JupyterLab server, runs both in the stack, and routes the tool's 
API traffic through the existing nginx proxy.
   
   **`StorageConfig`, `NotebookMigrationResource` (one Jupyter URL becomes 
two)**
   - `storage.jupyter.url` splits into `internal-url` and `public-url`. The 
service calls Jupyter at the internal address (health probes, notebook upload 
and delete); the iframe URL handed to the browser is built from the public one. 
A containerized deployment needs both at once, since the in-network service 
name does not resolve from the browser.
   - `public-url` defaults to `internal-url`, so native local development and 
every existing deployment are unchanged. The old key had a single consumer and 
appeared in no deployment configuration, so no compatibility alias is kept.
   - The existing note about this service still targeting one Jupyter per 
process (#7665) is updated to name which URL is which.
   
   **`bin/dockerfiles/notebook-migration-service.dockerfile` (new)**
   - Follows `config-service.dockerfile`, which copies the shared config 
resources the service reads at startup. Omits the `.git` copy that exists 
elsewhere for jgit calls from `OPVersion`: that lives in `workflow-core` and 
`workflow-operator`, which this service does not depend on.
   
   **`bin/dockerfiles/jupyter.dockerfile` (new)**
   - Builds the customized JupyterLab image from the files that already live 
with the service, so the image can be published rather than built by hand.
   - Replaces `notebook-migration-service/src/main/resources/Dockerfile` and 
the standalone `docker-compose.yml` beside it, both now deleted. Every compose 
file in the repo consumes published images, so the per-service compose file had 
no remaining role once the image is built by CI.
   
   **`build-and-push-images.yml`**
   - Adds image name mappings for both new dockerfiles. Without them the 
discovery step falls through to its default and publishes under bare names, 
missing the `texera-` prefix every other image uses.
   
   **`bin/single-node/`**
   - `docker-compose.yml` runs `notebook-migration-service` and `jupyter`, the 
latter publishing its port because the browser loads it directly rather than 
through nginx.
   - The Jupyter container deliberately does not receive `env_file`. Users 
execute arbitrary code there, so it gets only the two values it needs instead 
of the whole environment, which carries the database, S3, lakeFS and LiteLLM 
credentials. This also keeps `JUPYTER_PORT` out of that container, which the 
base image would otherwise read and use to move the server off its expected 
port.
   - `nginx.conf` routes `/api/notebook-migration/` to the service. Longest 
prefix matching gives it priority over the `/api/` catch all.
   - `.env` gains the published port, the Jupyter token, the internal Jupyter 
address, and the GUI toggle for the tool. Values needing interpolation are set 
in the compose file instead, matching how lakeFS composes its browser facing 
presigned endpoint.
   
   **Docs**
   - `bin/single-node/README.md` covers the new port in all three places ports 
are listed, how to use and disable the tool, and a warning that all users share 
one JupyterLab server and one token, which is acceptable on a single machine 
but must not be carried into a multi-user deployment.
   
   ### Any related issues, documentation, discussions?
   Closes #7931
   Parent issue #4301
   
   ### How was this PR tested?
   Added a test in `StorageConfigSpec.scala` pinning that the public Jupyter 
URL defaults to the internal one, so splitting them stays a no-op outside 
containerized deployments. The rest of this PR is deployment configuration, 
which the existing suites do not cover.
   
   Existing suites pass: `NotebookMigrationService/test` (42), `Config/testOnly 
StorageConfigSpec`, and `bin/single-node/tests/test_single_node_sh.sh`.
   
   Manually verified by running the full stack with `bin/single-node.sh up`:
   - All containers reach a healthy state, including both new ones.
   - Authenticated through nginx, then called 
`/api/notebook-migration/get-jupyter-url`, which returned the browser reachable 
address rather than the in-network one. That request also confirms the internal 
direction, since the endpoint only succeeds after its reachability probe to 
Jupyter passes.
   - `POST /api/notebook-migration/set-notebook` through nginx succeeded and 
the notebook landed inside the Jupyter container. The iframe URL then returned 
200 with the expected `frame-ancestors` header naming the Texera origin.
   - Confirmed no credentials are present in the Jupyter container's 
environment.
   - The existing routes (`/api/dataset`, `/api/computing-unit`, `/api/models`, 
`/api/compile`, `/`) are unaffected.
   - With an API key configured, a live model call through the tool's LLM path 
returned successfully.
   
   ### Was this PR authored or co-authored using generative AI tooling?
   Generated-by: Claude Code (Claude Opus 5)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to