Чи погано мати свій каталог virtualenv всередині мого сховища git?


285

Я думаю про те, щоб поставити virtualenv для веб-додатку Django, який я створюю у своєму сховищі git для програми. Це здається простим способом зберегти розгортання просто і легко. Чи є якась причина, чому я не повинен цього робити?

Відповіді:


302

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


81
Ви можете заощадити зайвий простір у вашій репо-сервері та все-таки розгорнути на новий сервер за допомогою однієї команди: virtualenv --no-site-пакети --distribute .env && source .env / bin / activate && pip install -r требования.txt
RyanBrady

2
Я даю вам відповідь на це питання, оскільки це, мабуть, "найкраща практика", і ви запропонували це першим. Я, безумовно, стикався з деякими проблемами, про які згадували всі. Я підрахував, я даю собі ще один день возитися з ним, перш ніж я просто зроблю те, що ви, хлопці, пропонували весь час, і використовуйте файл pip та файл вимог. Спасибі за вашу допомогу!
Лайл Пратт

11
Якщо ви, скажімо pip install mysql-python, на 64-бітній машині, а потім хтось із 32-бітною машиною намагається ним користуватися, це не вийде. Для підвищення продуктивності він використовує модуль С, як це роблять багато модулів Python. Я думаю, що Windows-> Linux також не працює.
Метт Вільямсон

7
лише зауваження: ми потрапили трохи в минуле, оскільки чомусь бібліотеки стають недоступними через pip (версія занадто стара), змушуючи оновити, поки сайт не працював. тому ... я більше ніколи більше не буду покладатися на pip freezeце. проблема полягає в тому, що під час примусового оновлення оновлення ніхто не платить за нього, а за проміжні оновлення (технічне обслуговування «найкращої практики») ніхто також не робить.
ДОГОВІР каже, що я право

5
Зверніть увагу на коментар @RayanBrady: Параметри --distributeта --setuptoolsпараметри тепер не підтримуються. (Поширюйте, що це вилка setuptools була об'єднана давно). --no-site-packagesВИКОРИСТАНО, тепер поведінка за замовчуванням
JackNova

49

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

Вже дане рішення полягає в тому, щоб зберігати достатню кількість інформації в git, щоб під час розгортання ви могли створювати virtualenv і робити необхідні установки pip. Зазвичай люди бігають, pip freezeщоб отримати список, а потім зберігають його у файлі з назвою вимоги.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 або git pull.

Зберігання каталогу virtualenv також робить трохи складніше обробляти оновлення файлів, оскільки вам доведеться вручну додавати / видаляти та фіксувати файли в результаті оновлення. За допомогою файлу вимоги.txt ви просто змінюєте відповідні рядки у вимовах.txt та повторно запускаєте pip install -r requirements.txt. Як уже зазначалося, це також зменшує "вчинення спаму".


4
Зауважимо, що --розподілити тепер застаріло (принаймні в 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. Мій PyCrypto mac не працював би на Cygwin, він не працював на Ubuntu.

Керувати сховищем стає абсолютно кошмаром.

У будь-якому випадку мені було легше керувати заморожуванням піп і файлом вимог, ніж мати все це в git. Це також чистіше, оскільки ви можете уникнути спаму на тисячі файлів, коли ці бібліотеки оновлюються ...


Хм. У мене точно не виникне проблем з тим, що речі складаються по-різному в різних умовах. Я думаю, його, ймовірно, не варто робити цього просто, щоб уникнути спаму.
Лейл Пратт

@LylePratt: Я думаю, що навпаки: краще не включати цілі virtualenv у сховище, щоб уникнути проблем із використанням таких чудових інструментів, як PyCrypto або PIL.
Тадек

17

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

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


Це правильне питання щодо того, чому погана ідея зберігати virtualenv в SCM, але варто розглянути або щось на зразок пропозиції @ RJBrady або подію сценарію bootstrap.py , оскільки наявність певних засобів для відтворення того ж середовища на машинах - це серйозна потреба в роботі з іншими людьми.
ig0774

Я не впевнений, що проблема, яку ви згадали, була б проблемою саме в моїй ситуації. Мій додаток Django містить файл .wsgi, який визначає, де virtualenv відносно його місцезнаходження (2 каталоги вгору '../../env'). Тож у моєму сценарії проблема абсолютного шляху не повинна негативно впливати на мене ... правда?
Лайл Пратт

Якщо ви завжди запускаєте свою програму за допомогою WSGI, ви можете позбутися її. Якщо ви використовуєте сервер розробки (через manage.py), ви точно будете стикатися з проблемами.
Torsten Engelbrecht

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на вашому шляху, перш ніж він знайде той у поточному каталозі.


Люблячий такий підхід! Звучить дуже розумно, дякую за обмін.
Езолітос

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

3

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

  1. Відкрийте Pycharm і на першій сторінці виберіть проект із системи контролю джерел (у моєму випадку я використовую github)

  2. У Pycharm перейдіть до налаштувань та оберіть "Interpreter Project" та оберіть опцію для додавання нового віртуального середовища, ви можете назвати це "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.

Наприклад, систему можна ідентифікувати за допомогою модуля платформи .

Насправді це те, що я роблю з написаної вами внутрішньої програми, і до якої я можу швидко додати новий віртуаленс системи у разі необхідності. Таким чином, я не повинен покладатися на те, що піп зможе успішно завантажити програмне забезпечення, яке вимагає моя програма. Мені також не доведеться турбуватися про компіляцію, наприклад, psycopg2, яку я використовую.

Якщо ви не знаєте, на якій операційній системі може працювати ваша програма, вам, ймовірно, краще скористатися, pip freezeяк пропонується в інших відповідях тут.


0

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

Або автоматизований інсталятор, або документація повинні вказувати шлях virtualenv як відносний шлях, таким чином ви не зіткнетеся з проблемами при обміні проектом з іншими людьми. Про пакунки використовувані пакунки повинні бути збережені pip freeze -r requirements.txt.


-1

Якщо ви просто налаштовуєте програму env, тоді використовуйте файл pip freeze, caz, який робить git repo чистим.

Тоді, якщо ви робите виробниче розгортання, перевірте всю папку venv. Це зробить ваше розгортання більш відтворюваним, не потрібні ці пакети libxxx-dev та уникне проблем з Інтернетом.

Отже, є дві репости. Один для вашого основного вихідного коду, який включає вимоги.txt. І env repo, який містить всю папку venv.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.