Trouble deploying simple app with uv

I’m trying to deploy a Ray Serve app to an already running cluster (connecting with ray.init(address="ray://<HEAD>:10001")). The project is a package: myapp/ (with __init__.py) contains app.py that builds the graph (entry = Ingress.bind(Embedder.bind(), Inferencer.bind())), and a deploy.py does serve.run(entry, name="gradio-mix"). I ship code via runtime_env (working_dir pointing at the project root; also tried adding py_modules: ["myapp"]) and set up deps with either setup_commands: ["uv sync --frozen"] or py_executable: "uv run" (no flags). Logs show the working dir is uploaded (e.g., gcs://_ray_pkg_...) and the runtime env is created, but deployment fails when Serve unpickles the deployment on the cluster with:

File “…/ray/serve/_private/config.py”, line 703, in deployment_defself._deployment_def = cloudpickle.loads(self.serialized_deployment_def)ModuleNotFoundError: No module named ‘myapp’

So it looks like the Serve worker that deserializes the project can’t import the packaged module even though myapp/__init__.py exists and the env reports created. Any pointers on what I’m missing to make the module visible to Serve actors in client mode? (Python 3.12; using FastAPI+Gradio ingress.)

here’s my project layout:

project-root/
├─ pyproject.toml              # deps (ray[serve], fastapi, gradio)
├─ uv.lock                     
├─ deploy.py                   # connects to running cluster and calls serve.run(entry, name=...)
├─ pyproject.toml
└─ myapp/
   ├─ __init__.py              # empty
   └─ serve_app.py             # defines APP_NAME, deployments, ingress, and `entry`

here’s a link to a zip file containing the project

ray_serve_bug.zip

1. Severity of the issue: (select one)
High: Completely blocks me.

2. Environment:

  • Ray version: 2.48.0
  • Python version: 3.12.9
  • OS: ubuntu
  • Cloud/Infrastructure: docker running on a AWS EC2 instance
  • Other libs/tools (if relevant):

3. What happened vs. what you expected:

  • Expected: cloudpickle.load finds my module
  • Actual: cloudpickle.load fails to find the inlined module

after trying to debug this further, I’d say running a yaml-based AWS cluster with Ray 2.48.0 doesn’t actually use or support astral-uv despite what the documentation says, either that or uv support is broken in 2.48.0.