¿Es malo tener mi directorio virtualenv dentro de mi repositorio git?

285

Estoy pensando en poner el virtualenv para una aplicación web Django que estoy haciendo dentro de mi repositorio git para la aplicación. Parece una manera fácil de mantener la implementación simple y fácil. ¿Hay alguna razón por la que no debería hacer esto?

Lyle Pratt
fuente

Respuestas:

302

Utilizo pip freezepara obtener los paquetes que necesito en un requirements.txtarchivo y agregarlos a mi repositorio. Traté de pensar en una forma de por qué querrías almacenar todo el virtualenv, pero no pude.

RyanBrady
fuente
81
Puede guardar el espacio innecesario en su repositorio y aún implementarlo en un nuevo servidor en un solo comando: virtualenv --no-site-packages --distribute .env && source .env / bin / enable && pip install -r require.txt
RyanBrady
2
Le doy la respuesta a esta pregunta, ya que probablemente sea la "mejor práctica" y usted la ofreció primero. Definitivamente me he encontrado con algunos de los problemas que todos han mencionado. Estoy estimando que me doy otro día jugando con eso antes de hacer lo que ustedes han estado sugiriendo todo el tiempo y usar pip y un archivo de requisitos. ¡Gracias por tu ayuda!
Lyle Pratt
11
Si usted, por ejemplo pip install mysql-python, en una máquina de 64 bits, y luego alguien con una máquina de 32 bits intenta utilizarlo, no funcionará. Utiliza un módulo C, como lo hacen muchos módulos Python, para aumentar el rendimiento. Me imagino que Windows-> Linux tampoco funcionaría.
Matt Williamson
77
solo una observación: nos mordió en el pasado porque de alguna manera las bibliotecas no están disponibles desde pip (versión demasiado antigua), lo que obliga a una actualización mientras el sitio estaba inactivo. entonces ... ahora nunca pip freezevolveré a confiar en hacer esto. el problema es que durante la implementación de la actualización forzada, nadie paga por ella, y para las actualizaciones intermedias (mantenimiento de "mejores prácticas") tampoco lo hace nadie.
EL CONTRATO DICE QUE ESTOY CORRECTO el
55
Nota sobre el comentario de @RayanBrady: Las opciones --distributey --setuptoolsahora no son opcionales. (distribuir, que era una bifurcación de herramientas de configuración que se fusionó hace mucho tiempo). --no-site-packagesestá DEPRECADO, ahora es el comportamiento predeterminado
JackNova
49

El almacenamiento del directorio virtualenv dentro de git le permitirá, como ha señalado, implementar toda la aplicación con solo hacer un clon de git (además de instalar y configurar Apache / mod_wsgi). Un problema potencialmente significativo con este enfoque es que en Linux la ruta completa se codifica en los scripts de venv's enable, django-admin.py, easy_install y pip. Esto significa que su virtualenv no funcionará por completo si desea utilizar una ruta diferente, tal vez para ejecutar varios hosts virtuales en el mismo servidor. Creo que el sitio web realmente puede funcionar con las rutas incorrectas en esos archivos, pero tendría problemas la próxima vez que intente ejecutar pip.

La solución, ya dada, es almacenar suficiente información en git para que durante la implementación pueda crear virtualenv y realizar las instalaciones necesarias de pip. Por lo general, las personas corren pip freezepara obtener la lista y luego la almacenan en un archivo llamado require.txt. Se puede cargar con pip install -r requirements.txt. RyanBrady ya mostró cómo puede encadenar las declaraciones de implementación en una sola línea:

# 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

Personalmente, acabo de ponerlos en un script de shell que ejecuto después de hacer el clon git o git pull.

El almacenamiento del directorio virtualenv también hace que sea un poco más complicado manejar las actualizaciones de pip, ya que tendrá que agregar / eliminar manualmente y confirmar los archivos resultantes de la actualización. Con un archivo require.txt, simplemente cambia las líneas apropiadas en require.txt y vuelve a ejecutarlo pip install -r requirements.txt. Como ya se señaló, esto también reduce el "envío de spam".

David Sickmiller
fuente
44
Tenga en cuenta que --distribute ahora está en desuso (al menos en 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC
1
--no-site-packagesestá en desuso también en 15.1.0, ya que ahora es el valor predeterminado.
cjs
35

Solía ​​hacer lo mismo hasta que comencé a usar bibliotecas que se compilan de manera diferente según el entorno, como PyCrypto. Mi PyCrypto mac no funcionaría en Cygwin no funcionaría en Ubuntu.

Se convierte en una pesadilla absoluta para administrar el repositorio.

De cualquier manera, me resultó más fácil administrar el congelamiento de pip y un archivo de requisitos que tenerlo todo en git. También es más limpio, ya que puedes evitar el envío de spam para miles de archivos a medida que esas bibliotecas se actualizan ...

Yuji 'Tomita' Tomita
fuente
Hmm Definitivamente no tendré problemas con las cosas que se compilan de manera diferente en diferentes entornos. Supongo que probablemente no valga la pena hacerlo solo para evitar el spam de confirmación.
Lyle Pratt
@LylePratt: Creo que es lo contrario: mejor no incluir virtualenv completo en el repositorio solo para evitar problemas al tener herramientas tan buenas como PyCrypto o PIL.
Tadeck
17

Creo que uno de los principales problemas que ocurren es que el virtualenv podría no ser utilizable por otras personas. La razón es que siempre usa rutas absolutas. Entonces, si virtualenv estaba, por ejemplo, en /home/lyle/myenv/él asumirá lo mismo para todas las demás personas que usan este repositorio (debe ser exactamente la misma ruta absoluta). No puede presumir que las personas usan la misma estructura de directorios que usted.

Una mejor práctica es que todos están configurando su propio entorno (ya sea con o sin virtualenv) e instalando bibliotecas allí. Eso también hace que el código sea más utilizable en diferentes plataformas (Linux / Windows / Mac), también porque virtualenv está instalado de manera diferente en cada una de ellas.

Torsten Engelbrecht
fuente
Esto es correcto en cuanto a por qué es una mala idea mantener un virtualenv en SCM, pero vale la pena considerar algo como la sugerencia de @ RJBrady o crear un script bootstrap.py , ya que tener algunos medios para recrear el mismo entorno en las máquinas es un Necesidad grave cuando se trabaja con otras personas.
ig0774
No estoy realmente seguro de que el problema que mencionaste sería exactamente un problema en mi situación. Mi aplicación Django contiene un archivo .wsgi que define dónde está virtualenv en relación con su ubicación (2 directorios arriba '../../env'). Entonces, en mi escenario, el problema del camino absoluto no debería afectarme negativamente ... ¿verdad?
Lyle Pratt
Si ejecuta su aplicación siempre con WSGI, entonces podría salirse con la suya. Si utiliza el servidor de desarrollo (a través de manage.py), seguramente tendrá problemas.
Torsten Engelbrecht
3

Utilizo lo que es básicamente la respuesta de David Sickmiller con un poco más de automatización. Creo un archivo (no ejecutable) en el nivel superior de mi proyecto activatecon el siguiente contenido:

[ -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"

(Según la respuesta de David, esto supone que está haciendo un pip freeze > requirements.txtpara mantener actualizada su lista de requisitos).

Lo anterior da la idea general; el script de activación real ( documentación ) que uso normalmente es un poco más sofisticado, ofrece una -qopción (silenciosa), usar pythoncuando python3no está disponible, etc.

Esto se puede obtener de cualquier directorio de trabajo actual y se activará correctamente, configurando primero el entorno virtual si es necesario. Mi script de prueba de nivel superior generalmente tiene código en estas líneas para que pueda ejecutarse sin que el desarrollador tenga que activar primero:

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

El abastecimiento ./activate, no activate, es importante aquí porque este último encontrará cualquier otro activateen su ruta antes de encontrar el que está en el directorio actual.

cjs
fuente
Me encanta este enfoque! Suena muy razonable, gracias por compartir.
Esolitos
Tuve que cambiar la primera línea para [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }detectar si el script se estaba ejecutando en lugar de fuente
Chris Snow
3

No es una buena idea incluir ningún componente o configuración dependiente del entorno en sus repositorios como uno de los aspectos clave del uso de un repositorio, es quizás compartirlo con otros desarrolladores. Así es como configuraría mi entorno de desarrollo en una PC con Windows (por ejemplo, Win10).

  1. Abra Pycharm y en la primera página, elija revisar el proyecto desde su Sistema de control de código fuente (en mi caso, estoy usando github)

  2. En Pycharm, navegue a la configuración y elija "Project Interpreter" y elija la opción para agregar un nuevo entorno virtual, puede llamarlo "venv".

  3. Elija el intérprete de Python base que se encuentra en C: \ Users {user} \ AppData \ Local \ Programs \ Python \ Python36 (asegúrese de elegir la versión adecuada de Python según lo que haya instalado)

  4. Tenga en cuenta que Pycharm creará el nuevo entorno virtual y copiará los binarios de Python y las bibliotecas requeridas en su carpeta venv dentro de su carpeta de proyecto.

  5. Deje que Pycharm complete su escaneo, ya que necesita reconstruir / actualizar su esqueleto de proyecto

  6. excluya la carpeta venv de sus interacciones git (agregue venv \ al archivo .gitignore en su carpeta de proyecto)

Bonificación: si desea que las personas instalen fácilmente (bueno, casi fácilmente) todas las bibliotecas que necesita su software, puede usar

pip freeze > requirements.txt

y ponga las instrucciones en su git para que las personas puedan usar el siguiente comando para descargar todas las bibliotecas necesarias a la vez.

pip install -r requirements.txt 
William Pourmajidi
fuente
2

Si sabe en qué sistemas operativos se ejecutará su aplicación, crearía un virtualenv para cada sistema y lo incluiría en mi repositorio. Luego haría que mi aplicación detecte en qué sistema se está ejecutando y use el virtualenv correspondiente.

El sistema podría identificarse, por ejemplo, utilizando el módulo de plataforma .

De hecho, esto es lo que hago con una aplicación interna que he escrito y a la que puedo agregar rápidamente un nuevo sistema virtual en caso de que sea necesario. De esta manera, no tengo que confiar en que pip podrá descargar con éxito el software que requiere mi aplicación. Tampoco tendré que preocuparme por la compilación de, por ejemplo, psycopg2 que uso.

Si no sabe en qué sistema operativo puede ejecutarse su aplicación, probablemente sea mejor usarlo pip freezecomo se sugiere en otras respuestas aquí.

fredrik
fuente
0

Creo que lo mejor es instalar el entorno virtual en una ruta dentro de la carpeta del repositorio, tal vez sea mejor incluir un subdirectorio dedicado al entorno (he eliminado accidentalmente todo mi proyecto cuando forcé la instalación de un entorno virtual en la raíz del repositorio carpeta, bueno que tenía el proyecto guardado en su última versión en Github).

El instalador automatizado o la documentación deben indicar la ruta virtualenv como una ruta relativa, de esta manera no tendrá problemas al compartir el proyecto con otras personas. Acerca de los paquetes, los paquetes utilizados deben ser guardados por pip freeze -r requirements.txt.

Lucioric2000
fuente
-1

Si solo configura el entorno de desarrollo, use el archivo pip freeze, caz, que hace que el repositorio git sea limpio.

Luego, si está realizando una implementación de producción, luego registre toda la carpeta venv. Eso hará que su implementación sea más reproducible, no necesite esos paquetes libxxx-dev y evitará los problemas de Internet.

Entonces hay dos repos. Uno para su código fuente principal, que incluye a required.txt. Y un repositorio env, que contiene toda la carpeta venv.

Shuo
fuente