Локальные и контейнерные окружения нельзя смешивать

Симптом

В Zed language server Ruff постоянно сбрасывал соединение и не запускался.

Ошибка указывала, что бинарник Ruff не может быть выполнен.

Контекст

Один и тот же каталог проекта использовался и локальными инструментами, и проверками внутри Linux-контейнера, который нужен для запуска ralphex. При запуске проверок в контейнере в общий virtualenv попал Linux-бинарник Ruff. macOS-инструмент редактора затем пытался запустить его как локальную команду.

Корневая причина

Virtualenv был привязан к платформе, но использовался как будто он переносим между локальной macOS-средой и Linux-контейнером. В результате Zed получил бинарник другой операционной системы.

Ошибочное предположение

Я предполагал, что virtualenv можно безопасно переиспользовать между двумя окружениями, если они работают с одним исходным кодом. Исходный код общий, но бинарные зависимости и инструменты окружения - нет.

Обнаружение

Сигналом был stderr language server: бинарник Ruff существовал по ожидаемому пути, но операционная система не могла его выполнить. Проверка архитектуры бинарника и владельца virtualenv должна быть частью диагностики таких сбоев.

Исправление

Я создал два независимых virtualenv:

Общие исходники не означают, что окружение с бинарными зависимостями тоже должно быть общим.

Проверка

Нужно проверять запуск Ruff из каждого окружения отдельно и убедиться, что Zed использует локальный interpreter, а контейнерные проверки - свой. В CI полезно проверять, что virtualenv не пересекается с каталогом, который монтируется между разными операционными системами.

Общий вывод

Virtualenv и другие каталоги с бинарными зависимостями принадлежат конкретной платформе. Между host и container следует разделять не только процессы, но и окружения инструментов, даже если исходный код проекта общий.