You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When using a Dockerfile, the file content contributed by different steps in the build is split into different layers, which are then combined via use of an overlay filesystem. In this model, it's possible for multiple steps of the build to write to the same directory locations - albeit at the cost of changes in earlier layers triggering cache invalidation of later layers.
With CNBs, the file content contributed by different steps in the build (whether that be from separate buildpacks, or steps within the same buildpack) are kept separate via the concept of CNB layers: https://buildpacks.io/docs/for-buildpack-authors/concepts/layer/
This provides several advantages (finer grained caching; easier multi-language images etc), however, to take full advantage of them we have to write the build content to separate layer directories.
For Python, this means we cannot simply install everything into the system site-packages directory (which lives inside the Python installation directory).
Until now, the way we've handled this is by:
Installing pip (and formerly setuptools/wheel) into the system site-packages directory
Installing the app dependencies into the user site-packages directory using pip install --user combined with PYTHONUSERBASE (which changes the user site-packages location from its default of the user home directory, to the location of the dependencies layer)
Several package managers don't support the equivalent of --user installs (such as Poetry or uv), meaning when we add support for them, we would have to use a different approach for them - which would then mean app dependency environments are set up differently depending on what package manager an app uses, which doesn't seem ideal.
Given that PEP-405 style virtual environments (venvs) are:
very lightweight (they are only a few binary symlinks, activation scripts and empty directories vs the old style virtualenvs)
much more frequently used in the wild compared to say --user (and therefore the better tested path)
...then it makes more sense to use a venv for the app dependencies instead of a user install.
Note: We can't use PYTHONPATH instead of a user site-packages install, since any directories specified via PYTHONPATH are given a higher precedence in Python's sys.path than the Python stdlib (unlike system and user site-packages, which are added to sys.path after the Python stdlib). This can then cause hard to debug issues if apps use outdated backport libraries (which can often happen unintentionally via broken/suboptimal packages in their transitive dependency tree).
When using a
Dockerfile, the file content contributed by different steps in the build is split into different layers, which are then combined via use of an overlay filesystem. In this model, it's possible for multiple steps of the build to write to the same directory locations - albeit at the cost of changes in earlier layers triggering cache invalidation of later layers.With CNBs, the file content contributed by different steps in the build (whether that be from separate buildpacks, or steps within the same buildpack) are kept separate via the concept of CNB layers:
https://buildpacks.io/docs/for-buildpack-authors/concepts/layer/
This provides several advantages (finer grained caching; easier multi-language images etc), however, to take full advantage of them we have to write the build content to separate layer directories.
For Python, this means we cannot simply install everything into the system site-packages directory (which lives inside the Python installation directory).
Until now, the way we've handled this is by:
pip install --usercombined withPYTHONUSERBASE(which changes the user site-packages location from its default of the user home directory, to the location of the dependencies layer)However, this has a number of downsides:
--userinstalls when using relocated Python, and otherwise require other workarounds (such as settingPYTHONHOME). eg: Incorrect stdlib path for relocated Python installs, resulting inModuleNotFoundError: No module named 'encodings'unbit/uwsgi#2525--userinstalls (such as Poetry or uv), meaning when we add support for them, we would have to use a different approach for them - which would then mean app dependency environments are set up differently depending on what package manager an app uses, which doesn't seem ideal.Given that PEP-405 style virtual environments (venvs) are:
--user(and therefore the better tested path)...then it makes more sense to use a venv for the app dependencies instead of a user install.
Note: We can't use
PYTHONPATHinstead of a user site-packages install, since any directories specified viaPYTHONPATHare given a higher precedence in Python'ssys.paththan the Python stdlib (unlike system and user site-packages, which are added tosys.pathafter the Python stdlib). This can then cause hard to debug issues if apps use outdated backport libraries (which can often happen unintentionally via broken/suboptimal packages in their transitive dependency tree).GUS-W-16616226.