add Virtual environments page (project isolation + pyenv)
New docs/environments.md, nav 'Virtual environments' (before Deploy): - the rule: never touch system Python (danger callout) - project-based isolation as Local .venv / Makefile-driven / Docker tabs, each with a runnable snippet; Docker ties back to the deploy standard - local dev with pyenv: why, official install link, shell init with annotated lines, everyday use, per-project .python-version - shell quality-of-life extras (flake8 alias, .local/bin + npm-global PATH), cross-ref'd to Standards and Workflow workflow.md pyenv bullet now points at the new page; index.md gains a card. Verified in-browser: tabs switch (Local/Makefile/Docker), annotations and admonitions render; mkdocs build --strict clean (cross-ref anchors resolve). Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
parent
e684ac2853
commit
613d8f28ea
145
docs/environments.md
Normal file
145
docs/environments.md
Normal file
@ -0,0 +1,145 @@
|
||||
# Virtual environments
|
||||
|
||||
How we keep a project's Python isolated — from the system Python and from every
|
||||
other project. The rule underneath all of it: **never install into, or upgrade,
|
||||
the system Python.** The OS depends on it; a project must never touch it.
|
||||
|
||||
!!! danger "Leave the system Python alone"
|
||||
No `sudo pip install`, no upgrading the system interpreter for a project. If a
|
||||
project needs a different version or a package, that goes in a **virtual
|
||||
environment** — never the system one. Breaking system Python can break the OS.
|
||||
|
||||
## Project-based isolation
|
||||
|
||||
Every project runs against its own isolated environment. There are three ways that
|
||||
happens, depending on where the project runs:
|
||||
|
||||
=== "Local `.venv`"
|
||||
|
||||
A virtualenv living in the repo. Simplest for day-to-day local work.
|
||||
|
||||
```bash
|
||||
python -m venv .venv # create it (once)
|
||||
source .venv/bin/activate # activate for this shell
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
Keep `.venv/` **gitignored** — it's per-machine, never committed.
|
||||
|
||||
=== "Makefile-driven"
|
||||
|
||||
Wrap the venv in a `make` target so every dev (and CI) sets up identically —
|
||||
no "did you activate it?" drift.
|
||||
|
||||
```makefile
|
||||
VENV := .venv
|
||||
PY := $(VENV)/bin/python
|
||||
|
||||
$(VENV): requirements.txt
|
||||
python -m venv $(VENV)
|
||||
$(PY) -m pip install -r requirements.txt
|
||||
|
||||
.PHONY: run
|
||||
run: $(VENV)
|
||||
$(PY) -m yourapp
|
||||
```
|
||||
|
||||
`make run` creates the venv if missing, installs deps, and runs — all against
|
||||
the isolated interpreter, no manual activation.
|
||||
|
||||
=== "Docker"
|
||||
|
||||
The container **is** the isolation — its own filesystem, its own interpreter,
|
||||
nothing shared with the host. You don't need a `.venv` inside an image; install
|
||||
straight into the container's Python.
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.12-slim
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
COPY . .
|
||||
```
|
||||
|
||||
This is how things run in production — see the [Deploy guide](deploy.md) for the
|
||||
full container standard (uid 1337, mounts, layer caching).
|
||||
|
||||
!!! tip "Which one?"
|
||||
**Local `.venv`** for quick iteration, **Makefile** when you want repeatable
|
||||
setup across the team, **Docker** for anything that ships. They're not
|
||||
exclusive — a project often has a `.venv` for local dev *and* a Dockerfile for
|
||||
deploy.
|
||||
|
||||
## Local dev with pyenv
|
||||
|
||||
For local work you also need the right **Python version**, not just isolated deps.
|
||||
We target **Python 3.10+**, and [pyenv](https://github.com/pyenv/pyenv) installs and
|
||||
switches versions per-project without touching the system Python.
|
||||
|
||||
- **Per-project pinning:** a `.python-version` file in a repo makes pyenv
|
||||
auto-select that interpreter when you `cd` in — everyone on the project runs the
|
||||
same one.
|
||||
- **Pairs with venvs:** combined with `pyenv-virtualenv`, each project gets both an
|
||||
isolated version *and* isolated deps.
|
||||
|
||||
### Install
|
||||
|
||||
Follow the [official pyenv installation](https://github.com/pyenv/pyenv#installation)
|
||||
for the installer and build dependencies — no point reproducing it here. Then add
|
||||
the shell init below to your `~/.zshrc` (or `~/.bashrc`) and restart your shell.
|
||||
|
||||
### Shell init
|
||||
|
||||
Without these lines pyenv's shims aren't on `PATH`, so `pyenv` and
|
||||
auto-version-switching won't work:
|
||||
|
||||
```bash
|
||||
# pyenv — Python version management
|
||||
export PYENV_ROOT="$HOME/.pyenv"
|
||||
export PATH="$PYENV_ROOT/bin:$PATH"
|
||||
eval "$(pyenv init --path)" # (1)!
|
||||
eval "$(pyenv init -)" # (2)!
|
||||
eval "$(pyenv virtualenv-init -)" # (3)!
|
||||
```
|
||||
|
||||
1. Puts the **shims** dir on `PATH`, so `python` resolves to the pyenv-selected
|
||||
version instead of the system one.
|
||||
2. Shell integration — command rehashing and completion.
|
||||
3. Auto-activates a project's virtualenv on `cd` — **only** if you use
|
||||
`pyenv-virtualenv`. Drop this line if you don't.
|
||||
|
||||
### Everyday use
|
||||
|
||||
```bash
|
||||
pyenv install 3.10.14 # install a version (one-time)
|
||||
pyenv install --list # see available versions
|
||||
cd <project>
|
||||
pyenv local 3.10.14 # writes .python-version -> auto-selects here
|
||||
python --version # confirms the pinned version
|
||||
```
|
||||
|
||||
- **`pyenv local <ver>`** per project — commit the `.python-version` so the team
|
||||
matches.
|
||||
- **`pyenv global <ver>`** for your default outside any project.
|
||||
|
||||
## Shell quality-of-life extras
|
||||
|
||||
A couple of optional lines worth having alongside pyenv:
|
||||
|
||||
```bash
|
||||
# flake8 with our shared config (max line 120)
|
||||
alias flake8='flake8 --config ~/.config/flake8'
|
||||
|
||||
# local bins on PATH (pip --user installs, npm globals)
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
export PATH="$HOME/.npm-global/bin:$PATH"
|
||||
```
|
||||
|
||||
- The **flake8 alias** keeps everyone linting with the same config (our 120
|
||||
max-line, etc. — see [Standards](standards.md#files-and-style)).
|
||||
- The **`.local/bin` / npm-global** PATH lines stop "command not found" after a
|
||||
`pip install --user` or a global npm install.
|
||||
|
||||
!!! note "More shell setup"
|
||||
This is the Python-env slice. The fuller dev shell setup — the WSL/Windows
|
||||
clipboard bridges, per-repo git-identity aliases, and the `gl` graph log — is on
|
||||
the [Workflow](workflow.md#handy-shell-setup) page.
|
||||
@ -32,6 +32,13 @@ out of it; examples use placeholders like `<dev>`, `<project>`, and `/srv/...`.
|
||||
How we actually work day to day — our Gitea, git habits, and the
|
||||
plan-in-chat / build-in-Claude-Code flow, plus shell setup.
|
||||
|
||||
- :material-language-python: __[Virtual environments](environments.md)__
|
||||
|
||||
---
|
||||
|
||||
Project-based Python isolation — local `.venv`, Makefile, or Docker — and
|
||||
local version management with pyenv.
|
||||
|
||||
- :material-rocket-launch: __[Deploy](deploy.md)__
|
||||
|
||||
---
|
||||
|
||||
@ -171,8 +171,9 @@ works by running it** — don't accept "this should work."
|
||||
[Remote — WSL](https://code.visualstudio.com/docs/remote/wsl), and run
|
||||
[Claude Code](https://docs.claude.com/en/docs/claude-code/overview) as your
|
||||
agent (terminal or the VS Code extension).
|
||||
- **[pyenv](https://github.com/pyenv/pyenv)** for Python versions — per-project
|
||||
versions, we target Python **3.10+**.
|
||||
- **[pyenv](https://github.com/pyenv/pyenv)** for per-project Python versions
|
||||
(we target **3.10+**) and isolated `.venv`s — full setup on the
|
||||
[Virtual environments](environments.md) page.
|
||||
- **[flake8](https://flake8.pycqa.org/)** with a shared config — max line length
|
||||
**120** (see the alias below).
|
||||
|
||||
|
||||
@ -54,4 +54,5 @@ nav:
|
||||
- Libraries: libraries.md
|
||||
- Standards: standards.md
|
||||
- Workflow: workflow.md
|
||||
- Virtual environments: environments.md
|
||||
- Deploy: deploy.md
|
||||
|
||||
Loading…
Reference in New Issue
Block a user