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)