Pre-commit with Docker and Multi-Project Monorepos
The Learning
Pre-commit is designed to run on the host machine, not inside Docker containers. In monorepos like open-wearables with multiple Python projects (e.g., backend + MCP), each project needs its own virtualenv for local hooks that use project-specific tools like ty.
Why Pre-commit Runs on the Host, Not in Docker
Git access — Pre-commit installs into
.git/hooks/pre-commitand needs the.gitdirectory, which typically isn’t mounted in containers.Repo-wide scope — Hooks may check both
backend/andmcp/, but the app container often only has backend code, so it can’t run the full pre-commit setup.
Recommended: Run pre-commit on the host. Ex:
cd open-wearables
uv run pre-commit run --all-filesLocal Hooks with Per-Project Virtualenvs
With repository local hooks, each hook can use its own .venv:
# .pre-commit-config.yaml
- repo: local
hooks:
- id: ty-backend
name: ty check (backend)
entry: sh -c 'cd backend && .venv/bin/ty check .'
language: system
files: ^backend/.*\.py$
- id: ty-mcp
name: ty check (mcp)
entry: sh -c 'cd mcp && .venv/bin/ty check .'
language: system
files: ^mcp/.*\.py$Each project (backend, mcp) has its own isolated venv; pre-commit invokes .venv/bin/ty directly—no need to activate them manually.
One-Time Setup: Create Both Virtualenvs
If the MCP venv doesn’t exist yet, create it:
# 1. Backend venv (if needed)
cd backend && uv sync --group code-quality
# 2. MCP venv
cd mcp && uv sync --group code-quality
# 3. Run pre-commit from repo root
cd open-wearables
uv run pre-commit run --all-filesWhy --group code-quality? Each project’s pyproject.toml defines a code-quality dependency group containing pre-commit, ruff, and ty. By default, uv sync only installs main dependencies and the dev group—it skips other groups. Without --group code-quality, ty (and the other code-quality tools) won’t be installed, so .venv/bin/ty won’t exist and the pre-commit hooks will fail.
Summary
Pre-commit and its hooks should run on the host. Use uv sync --group code-quality in each project to create the venvs that local hooks expect.