I do all my development inside docker containers.
I use the docker image: ghcr.io/fenics/test-env:current-mpich
to get the core dependencies (including petsc), and then install basix, ufl, ffcx and dolfinx on top of that.
The following gist has all commands I use for rebuilding:
including commands I add to .bashrc to rebuild dolfinx etc.
The easiest way to interact with Docker and local installations is by using vscode, as you can attach vscode to docker image, and browse the file-system of the docker container as if it was a local installation.
Another option is to use conda and rely on stable releases of DOLFINx, petsc etc, in an isolated conda environment.