~ 6 min read

How to Setup Raspberry Pi OS: Bullseye like a Python Pro

I setup my Raspberry Pi using Bullseye and installed many of the same developer tools I use on my main dev machine for Python upon it. You can also check out a youtube video I’ve made on setting it up here. I did this from scratch with a brand new install, with all available updates installed at the time. Bullseye is the most recent release of Raspberry Pi OS which came out earlier this month, based on Debian Bullseye.

Specifically, I did this on my Pi 400 which is feeling very lonely having not got much use since I bought it last year. The instructions here however should work for any Raspberry Pi running Bullseye. Out of the box, Bullseye is fully configured to get started programming Python and we have a couple of IDEs installed already. So you might be wondering why we need to do anything at all?

Well, as a Python developer, I have a few preferences for tools I use for writing code, I’m already familiar with them so want to continue to use them. Additionally, I want to be able to manage multiple versions of Python and the library versions within environments simply and easily and update them when I need too, again with familiar tools. This isn’t how a Pi or Bullseye is initially setup it’s mostly used for education rather than professional(!) devs. Pi OS is shipped with everything we might need for Python straight away preinstalled globally. In a educational scenario, if we wanted to change the setup we could just swap out our main disk in the form of a microsd card for another very simply.

In practice it’s important to separate dependencies in any development project so I want to do the do the same on Bullseye too. Practically, switching SD cards all the time doesn’t make sense if I can just switch an environment via a command line.

Preinstalled Software

Out of the box, Bullseye ships with:

  • Python 3.9.2
  • Git 2.30.1

Somewhat differently to other machines I use, the system Python is loaded with a whole bunch of libraries already ready for someone to get coding with straight away. You can see the whole list of packages here. The problem is however that these are all globally fixed and if we were to update one, it may have a conflict with another library that’s installed. We want to install tooling that allows us to manage virtual environments, such as Pipenv and Poetry.

For reference, the previous version of Raspberry Pi OS, Buster shipped with:

  • Python 2.7.16 (Unsupported as of Jan 2020)
  • Python 3.7.3
  • Git 2.20.1


I don’t go into much detail here about how you might use each tool - you can refer to the above video or the others on my channel or articles on this blog. For the rest of this article I cover a number of different tools to install so use these links to jump to the parts you’re most interested in:


Pyenv is a tool which allows us to install multiple versions of Python on the same machine.

In order to install Pyenv on Bullseye, we need to install the Python build dependencies for Debian.

sudo apt-get update; sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

Once that’s done, you can follow the instructions to clone the pyenv repo to your users home directory.

 git clone https://github.com/pyenv/pyenv.git ~/.pyenv

I also went ahead and compiled the bash extension:

 cd ~/.pyenv && src/configure && make -C src

Once cloned, you’ll need to configure your shell to work with Python. There’s a few different options available here, we can use the Debian version. NB. In the video the one that I used was for the Suse install.

# the sed invocation inserts the lines at the start of the file
# after any initial comment lines
sed -Ei -e '/^([^#]|$)/ {a \
export PYENV_ROOT="$HOME/.pyenv"
a \
export PATH="$PYENV_ROOT/bin:$PATH"
a \
' -e ':a' -e '$!{n;ba};}' ~/.profile
echo 'eval "$(pyenv init --path)"' >>~/.profile

echo 'eval "$(pyenv init -)"' >> ~/.bashrc

You’ll need to logout and login again in order for the .profile file that was just created by this command to be sourced. You can also do:

source ~/.profile

At this point you should be able to call pyenv versions and see the cli return some helpful information about which versions of Python are installed. There should currently be a system version and nothing else listed. It should also be highlighted with a start to indicate it is the global version of Python.

If you want to install a new version of python, call:

pyenv install 3.10.0

If you check pyenv versions after install you should see both versions listed.


After spending much time with failed installations on Pi OS, I found the simplest way of getting Python virtualenv tooling installed is using pipx. You should make sure you’re still using the system version of Python before install and call:

python3 -m pip install --user pipx
python3 -m pipx ensurepath


Pipenv is a great tool for managing Python virtual environments and specifying dependencies. It wraps up many of the common management actions into one tool and automatically maintains dependencies in a Pipfile and Pipfile.lock as you install them.

Now we have pipx installed, we can easily install pipenv by calling:

pipx install pipenv


Poetry is another tool for managing Python virtual environments. It takes things a step further than Pipenv by simplifying both managing an environment and publishing to the Python Package Index.

Similar to pipenv, we can easily install Poetry using pipx by calling:

pipx install poetry


ZShell is my shell of choice. It’s the default option on mac and gives me access to the wonderful ohmyzsh plugins. We can easily set this up on the Pi using apt.

sudo apt install zsh -y

At this point, you’ll need to logout and back in again for the changes to occur to the terminal app.

Oh My Zsh

Oh my zsh installs a number of fancy themes for terminal and shortcuts for tools like git. It allows you to see branches when in git directories with status indicated by the cursor colour which is really useful and saves a lot of repeated commands.

It can be installed with:

sh -c "$(curl -fsSL https://raw.github.com/ohmyzsh/ohmyzsh/master/tools/install.sh)"

Visual Studio Code

Although we already have a couple of ide’s installed already, they aren’t ones I generally use day to day. Although Pycharm is available for linux, it’s quite a cumbersome beast requiring a full JDK and will likely be pretty slow on our Pi, so I’d recommend against trying to install it. VSCode is a full featured text editor that can be configured for many languages through the use of plugins and is a familiar tool to me.

sudo apt install code -y

You should then see it appear within the programming menu.

VSCode shown in menu

Once you’ve got it up and running, be sure to install the Python plugin to get syntax highlighting and hinting. You can also install any of the other plugins that take your fancy.


If you followed the same steps as me, your Raspberry Pi should now be ready to get started doing some serious Python coding on Bullseye. You can save money on microsd cards by keeping all your projects separate on the same machine.

Subscribe for Exclusives

My monthly newsletter shares exclusive articles you won't find elsewhere, tools and code. No spam, unsubscribe any time.