Say you have a uv-managed Python website project with pyproject.toml and uv.lock
(the latter pins the dependency versions for /more/ repeatable builds) that you want
to build on Cloudflare Pages and you experience strange build failures like
error: Multiple top-level modules discovered in a flat-layout
An earlier post, uv-managed dependencies and Cloudflare Pages, suggested adding
[tool.setuptools]
packages = []
to work around that problem.
This suggestion is simple and gets rid of the build failures. It’s also wrong.
Since uv is not directly supported in CF pages at this time, the build process only
makes use of the contents of pyproject.toml while completely ignoring uv.lock.
It installs the dependencies but there’s no guarantee their versions correspond to
the ones defined in uv.lock.
The actual way to fix this problem is as follows:
-
Set the SKIP_DEPENDENCY_INSTALL environment variable to
1in the Pages project’s settings:SKIP_DEPENDENCY_INSTALL=1.This allows us to take full(ish) control of the dependency installation process.
-
Override the build command to install uv and to run the actual build command via uv.
This is necessary because uv is not available by default and then, once installed, it needs to install the necessary dependencies and the build needs to be run in the uv-managed environment. An example build command (for a Sphinx-based application):
pipx install uv==0.7.8 && uv run make htmlPinning the uv version is not required but I’d say it’s a good thing to do to avoid surprises in the future.
The downside is the version needs to be manually adjusted if an upgrade is desired in the future and the fact that the version is pinned is not obvious as it’s kind of hidden deep in the Cloudflare dashboard. One option to make this nicer is to store the whole command in a file in the repository and then run that file in the build command.