Разве плохо иметь мой каталог virtualenv внутри моего репозитория git?

285

Я думаю о том, чтобы поместить virtualenv для веб-приложения Django, которое я создаю, в свой git-репозиторий для приложения. Кажется, что простой способ сделать развертывание простым и легким. Есть ли причина, почему я не должен этого делать?

Лайл Пратт
источник

Ответы:

302

Я использую, pip freezeчтобы получить нужные мне пакеты в requirements.txtфайл и добавить их в свой репозиторий. Я пытался придумать способ, почему вы хотели бы хранить все virtualenv, но я не смог.

RyanBrady
источник
81
Вы можете сохранить ненужное пространство в репозитории и по-прежнему развертывать его на новом сервере с помощью одной команды: virtualenv --no-site-packages --distribute .env && source .env / bin / activ && pip install -r needs.txt
RyanBrady
2
Я даю вам ответ на этот вопрос, поскольку это, вероятно, «лучшая практика», и вы предложили ее в первую очередь. Я определенно столкнулся с некоторыми проблемами, о которых все упоминали. Я полагаю, что еще раз подумаю над этим, прежде чем просто сделать то, что вы, ребята, предлагали все время, и использовать pip и файл требований. Спасибо за вашу помощь!
Лайл Пратт
11
Если вы, скажем pip install mysql-python, на 64-битной машине, а затем кто-то с 32-битной машиной пытается использовать его, это не будет работать. Он использует модуль C, как и многие модули Python, для повышения производительности. Я думаю, что Windows-> Linux также не будет работать.
Мэтт Уильямсон
7
просто замечание: мы ушли в прошлое, потому что библиотеки стали недоступны из-за pip (слишком старая версия), что привело к обновлению, когда сайт не работал. так что ... теперь я никогда больше не буду полагаться на pip freezeэто. проблема заключается в том, что во время повторного развертывания принудительного обновления никто не платит за него, а за промежуточные обновления («наилучшая практика») никто также не платит.
контракте говорится, что я прав
5
Обратите внимание на @RayanBrady Комментарий: --distributeи --setuptoolsварианты не являются в настоящее время нет оп. (распространяйте, что это был ответвление от setuptools, уже давно объединено). --no-site-packagesУСТАРЕЛО, теперь это поведение по умолчанию
JackNova
49

Хранение каталога virtualenv внутри git, как вы заметили, позволит вам развернуть все приложение, просто выполнив клон git (плюс установив и настроив Apache / mod_wsgi). Одна потенциально значительная проблема с этим подходом заключается в том, что в Linux полный путь жестко запрограммирован в сценариях активации venv, django-admin.py, easy_install и pip. Это означает, что ваша virtualenv не будет работать полностью, если вы захотите использовать другой путь, возможно, для запуска нескольких виртуальных хостов на одном сервере. Я думаю, что сайт может работать с неправильными путями в этих файлах, но у вас будут проблемы при следующем запуске pip.

Решение, которое уже дано, состоит в том, чтобы хранить достаточно информации в git, чтобы во время развертывания вы могли создать virtualenv и выполнить необходимые установки pip. Обычно люди бегут pip freezeза списком, а затем сохраняют его в файле с именем needs.txt. Это может быть загружено с pip install -r requirements.txt. RyanBrady уже показал, как можно выстроить операторы развертывания в одну строку:

# before 15.1.0
virtualenv --no-site-packages --distribute .env &&\
    source .env/bin/activate &&\
    pip install -r requirements.txt

# after deprecation of some arguments in 15.1.0
virtualenv .env && source .env/bin/activate && pip install -r requirements.txt

Лично я просто помещаю их в скрипт оболочки, который запускаю после выполнения git clone или git pull.

Хранение каталога virtualenv также несколько усложняет обработку обновлений pip, поскольку вам придется вручную добавлять / удалять и фиксировать файлы, полученные в результате обновления. Используя файл require.txt, вы просто меняете соответствующие строки в файле require.txt и запускаете заново pip install -r requirements.txt. Как уже отмечалось, это также уменьшает «спам».

Дэвид Сикмиллер
источник
4
Обратите внимание, что --distribute устарела (по крайней мере, в 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC
1
--no-site-packagesустарела и в 15.1.0, так как теперь это значение по умолчанию.
CJS
35

Раньше я делал то же самое, пока не начал использовать библиотеки, которые компилируются по-разному в зависимости от среды, такой как PyCrypto. Мой Mac PyCrypto не будет работать на Cygwin, не будет работать на Ubuntu.

Управление хранилищем становится настоящим кошмаром.

В любом случае мне было проще управлять замораживанием пипсов и файлом требований, чем иметь все это в git. Это тоже чище, так как вы можете избежать спама для тысяч файлов при обновлении этих библиотек ...

Юджи "Томита" Томита
источник
Хм. У меня точно не будет проблем с тем, что вещи компилируются по-разному в разных средах. Я думаю, что, вероятно, не стоит этого делать, просто чтобы избежать спама.
Лайл Пратт
@LylePratt: Я думаю, что наоборот: лучше не включать в репозиторий весь virtualenv, чтобы избежать проблем с такими замечательными инструментами, как PyCrypto или PIL.
Tadeck
17

Я думаю, что одна из основных проблем заключается в том, что virtualenv не может быть использован другими людьми. Причина в том, что он всегда использует абсолютные пути. Так что, если вы, например, в virtualenv, /home/lyle/myenv/будете предполагать то же самое для всех остальных людей, использующих этот репозиторий (это должен быть точно такой же абсолютный путь). Вы не можете предполагать, что люди используют ту же структуру каталогов, что и вы.

Лучше всего, чтобы каждый настраивал свою среду (будь то с помощью virtualenv или без нее) и устанавливал там библиотеки. Это также делает ваш код более удобным для использования на разных платформах (Linux / Windows / Mac), также потому, что virtualenv устанавливается по-разному на каждой из них.

Торстен Энгельбрехт
источник
Это правильно, почему плохая идея сохранять виртуальность в SCM, но стоит рассмотреть что-то вроде предложения @ RJBrady или сценарий bootstrap.py , поскольку наличие некоторых средств для воссоздания одной и той же среды на компьютерах является серьезная необходимость при работе с другими людьми.
ig0774
Я не совсем уверен, что проблема, которую вы упомянули, будет проблемой именно в моей ситуации. Мое приложение Django содержит файл .wsgi, который определяет, где virtualenv относительно его местоположения (2 директории вверх '../../env'). Таким образом, в моем сценарии проблема абсолютного пути не должна негативно влиять на меня ... верно?
Лайл Пратт
Если вы всегда запускаете свое приложение с WSGI, то вам это может сойти с рук. Если вы используете сервер разработки (через manage.py), вы наверняка столкнетесь с проблемами.
Торстен Энгельбрехт
3

Я использую то, что в основном является ответом Дэвида Сикмиллера, с немного большей автоматизацией. Я создаю (неисполняемый) файл на верхнем уровне моего проекта activateсо следующим содержанием:

[ -n "$BASH_SOURCE" ] \
    || { echo 1>&2 "source (.) this with Bash."; exit 2; }
(
    cd "$(dirname "$BASH_SOURCE")"
    [ -d .build/virtualenv ] || {
        virtualenv .build/virtualenv
        . .build/virtualenv/bin/activate
        pip install -r requirements.txt
    }
)
. "$(dirname "$BASH_SOURCE")/.build/virtualenv/bin/activate"

(Согласно ответу Дэвида, это предполагает, что вы делаете все, pip freeze > requirements.txtчтобы поддерживать свой список требований в актуальном состоянии.)

Вышесказанное дает общую идею; Реальный сценарий активации ( документация ), который я обычно использую, немного сложнее, предлагает -q(тихий) вариант, использование, pythonкогда python3он недоступен и т. д.

Затем он может быть получен из любого текущего рабочего каталога и будет правильно активирован, при необходимости сначала настраивая виртуальную среду. Мой тестовый сценарий верхнего уровня обычно содержит код, аналогичный приведенному ниже, так что его можно запустить без предварительной активации разработчиком:

cd "$(dirname "$0")"
[[ $VIRTUAL_ENV = $(pwd -P) ]] || . ./activate

Поиск здесь ./activateне activateважен, потому что последний найдет любой другой activateв вашем пути, прежде чем найдет тот в текущем каталоге.

CJS
источник
Люблю этот подход! Звучит очень разумно, спасибо, что поделились.
Esolitos
Мне пришлось изменить первую строку, чтобы [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }определить, выполнялся ли сценарий, а не
Крис Сноу,
3

Не стоит включать в репозитории какой-либо компонент или параметр, зависящий от среды, поскольку одним из ключевых аспектов использования репо, возможно, является предоставление его другим разработчикам. Вот как я могу настроить свою среду разработки на ПК с Windows (скажем, Win10).

  1. Откройте Pycharm и на первой странице выберите вариант проверки проекта из системы управления версиями (в моем случае я использую github)

  2. В Pycharm перейдите к настройкам и выберите «Project Interpreter» и выберите опцию добавления новой виртуальной среды, которую вы можете назвать «venv».

  3. Выберите базовый интерпретатор Python, который находится по адресу C: \ Users {user} \ AppData \ Local \ Programs \ Python \ Python36 (убедитесь, что вы выбрали подходящую версию Python на основе того, что вы установили)

  4. Обратите внимание, что Pycharm создаст новую виртуальную среду и скопирует двоичные файлы Python и необходимые библиотеки в папку venv внутри папки вашего проекта.

  5. Позвольте Pycharm завершить сканирование, так как ему нужно перестроить / обновить каркас вашего проекта

  6. исключить папку venv из ваших взаимодействий с git (добавьте файл venv \ в .gitignore в папке вашего проекта)

Бонус: если вы хотите, чтобы люди легко (ну, почти легко) устанавливали все библиотеки, в которых нуждается ваше программное обеспечение, вы можете использовать

pip freeze > requirements.txt

и поместите инструкцию в ваш git, чтобы люди могли использовать следующую команду, чтобы загрузить все необходимые библиотеки одновременно.

pip install -r requirements.txt 
Уильям Пурмаджиди
источник
2

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

Система может быть, например, идентифицирована с использованием модуля платформы .

Фактически, это то, что я делаю с внутренним приложением, которое я написал, и к которому я могу быстро добавить virtualenv новой системы в случае необходимости. Таким образом, мне не нужно полагаться на то, что pip сможет успешно загрузить программное обеспечение, необходимое для моего приложения. Мне также не придется беспокоиться о компиляции, например, psycopg2, который я использую.

Если вы не знаете, в какой операционной системе может работать ваше приложение, вам, вероятно, лучше использовать, pip freezeкак это предлагается в других ответах здесь.

Фредрик
источник
0

Я думаю, что лучше всего установить виртуальную среду по пути внутри папки репозитория, может быть, лучше включить подкаталог, выделенный для этой среды (я случайно удалил весь свой проект при принудительной установке виртуальной среды в корне репозитория). папка, хорошо, что у меня проект был сохранен в его последней версии в Github).

Либо автоматический установщик, либо документация должна указывать путь virtualenv как относительный путь, так что вы не столкнетесь с проблемами при совместном использовании проекта с другими людьми. О пакетах, используемые пакеты должны быть сохранены pip freeze -r requirements.txt.

Lucioric2000
источник
-1

Если вы просто настраиваете env разработки, то используйте файл pip freeze, caz, который делает git repo чистым.

Затем, если вы производите развертывание, проверьте всю папку venv. Это сделает ваше развертывание более воспроизводимым, не потребует этих пакетов libxxx-dev и позволит избежать проблем с интернетом.

Итак, есть два репо. Один для вашего основного исходного кода, который включает в себя файл require.txt. И репозиторий env, который содержит всю папку venv.

Шо
источник