You’ve set up your dream development environment:
- Your host system (maybe Pop!_OS, Ubuntu, or something similar) uses
pyenv
to manage many Python versions. - For clean, reproducible builds, you spin up a Fedora container with Distrobox.
It feels like the best of both worlds… until something breaks.
Inside your container you type:
~$ which python3 ~/.pyenv/shims/python3 😖😩
Instead of Fedora’s Python, it points to your host’s ~/.pyenv/shims/python3
.
Your container isn’t clean anymore — your host has leaked into it.
Don’t panic. This is a common issue, and the fix is simple once you know what’s happening.
⚡ The Hidden Culprit: A Pyenv Shell Function
At first, you may think the problem is just the $PATH
.
But that’s only part of the story.
The real issue is a pyenv shell function.
When you run this on your host:
eval "$(pyenv init -)"
…it doesn’t only change your path. It also creates a function that overrides python
. This function gets copied into your Distrobox container and takes priority over any path fixes you try.
So, to solve this:
👉 You need to remove the shell function and clean the path inside the container.
🛠️ The Smart .bashrc
Fix
The best solution is to make your .bashrc
“smart.”
With one block of code, it can detect whether you are on the host (Pop!_OS/Ubuntu) or inside a container (Fedora or others).
Replace your current pyenv settings with this block:
# ================================================================== # Pyenv & Distrobox Isolation # ================================================================== # Works on host (Pop!_OS, Ubuntu, etc.) and keeps containers (Fedora, etc.) # completely clean. if [ -z "$CONTAINER_ID" ]; then # --- HOST SYSTEM --- # Normal pyenv setup export PYENV_ROOT="$HOME/.pyenv" export PATH="$PYENV_ROOT/bin:$PATH" eval "$(pyenv init -)" else # --- GUEST (Distrobox Container) --- # Aggressively decontaminate the inherited host environment. # 1. Disable the pyenv shell function pyenv() { : # Does nothing } # 2. Rebuild PATH without pyenv entries _CLEAN_PATH="" OLD_IFS="$IFS"; IFS=':'; for p in $PATH; do case "$p" in # Explicitly skip any path containing .pyenv */.pyenv*) ;; # Skip pyenv paths *) if [ -n "$p" ]; then _CLEAN_PATH="${_CLEAN_PATH:+$_CLEAN_PATH:}$p" fi ;; esac done # Prepend the container's native paths to guarantee priority. export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:${_CLEAN_PATH}" IFS="$OLD_IFS" unset _CLEAN_PATH OLD_IFS fi
After saving, close and reopen your terminals.
- On your host (Pop!_OS/Ubuntu), pyenv works as usual.
- Inside your Fedora container, you’ll get a clean, native
/usr/bin/python3
🤩😍.
✅ Why This Is the Right Fix
This isn’t a quick hack — it’s a clean, long-term solution.
Pros:
- One-time setup: Update
.bashrc
once, and forget about it. - True isolation: Both
$PATH
and the shell function are handled. - Future-proof: If you later install pyenv inside the container, it works correctly.
- Clear boundaries: Keeps host and container separate.
Cons:
- Works only for bash. If you use
zsh
orfish
, you’ll need to adapt it. - Depends on
.bashrc
being loaded properly.
🎯 Conclusion
With this fix, you get the best of both worlds:
- Host (Pop!_OS/Ubuntu/ etc.): full pyenv power.
- Container (Fedora or other Distrobox guests): clean, isolated Python environment.
Now you can code with confidence, without pyenv sneaking into places it doesn’t belong.
Top comments (0)