You can and probably should go thinner than this, with uv we effectively have a workflow comparable to deploying static binaries in other language stacks. You don't need the complexity of docker for this book's goal.
This go thin with uv is good advice for smaller projects. But as you grow with more aspects, it gets more problematic.
I ran code that way for years. But now we have 23 different services: web apps, APIs, and database servers, my code and other self-hosted services.
I would NOT run 23 projects/servers (3 versions of postgres) this way. Like so much, it depends. FWIW, the book goes into depth about these trade-offs.
Presumably just directly on whatever system they are using. If you have something that can be plopped on whatever linux distro and run reliably then you've already got what docker is supposed to give you.
Exactly as sibling comment says, e.g. let's pretend the popular httpx cli was my project to deploy and run on the server. With only uv installed, i can:
uv tool run "httpx[cli] @ git+https://github.com/encode/httpx"
To be clear in this example i'm not pulling a package published on pypi, i'm running the HEAD of that git repo (i could do a branch or tag instead). I could use the "uvx" shortcut instead of "uv tool run". I could specify a specific python version (either one already installed on this OS or choose a dist which uv downloads for me).
This caches the deps in an isolated virtual env for me. It'll only download the deps in the first run.
Was hoping the book would cover data persistence.