È male avere la mia directory virtualenv nel mio repository git?


285

Sto pensando di inserire virtualenv per un'app Web Django che sto realizzando nel mio repository git per l'app. Sembra un modo semplice per mantenere la distribuzione semplice e facile. C'è qualche motivo per cui non dovrei farlo?

Risposte:


302

Uso pip freezei pacchetti di cui ho bisogno in un requirements.txtfile e li aggiungo al mio repository. Ho provato a pensare a un modo per cui vorresti archiviare l'intero virtualenv, ma non ci sono riuscito.


81
Puoi salvare lo spazio non necessario nel tuo repository e comunque distribuirlo su un nuovo server in un unico comando: virtualenv --no-site-pacchetti --distribute .env && source .env / bin / activ && pip install -r Requisiti.txt
RyanBrady,

2
Ti sto dando la risposta a questa domanda, poiché è probabilmente la "migliore pratica" e tu l'hai offerta prima. Ho sicuramente riscontrato alcuni dei problemi che tutti hanno menzionato. Sto valutando che mi concedo un altro giorno a scherzare con esso prima di fare quello che voi ragazzi avete sempre suggerito e usare pip e un file di requisiti. Grazie per l'aiuto!
Lyle Pratt,

11
Se, diciamo pip install mysql-python, su una macchina a 64 bit, e quindi qualcuno con una macchina a 32 bit tenta di usarlo, non funzionerà. Utilizza un modulo C, come fanno molti moduli Python, per aumentare le prestazioni. Immagino che Windows-> Linux non funzionerebbe.
Matt Williamson,

7
solo un'osservazione: siamo diventati un po 'in passato perché in qualche modo le librerie non sono più disponibili da pip (versione troppo vecchia), forzando un aggiornamento mentre il sito era inattivo. quindi ... ora non farò mai più affidamento pip freezeper farlo. il problema è che durante la ridistribuzione dell'aggiornamento forzato, nessuno paga per questo, e per gli aggiornamenti intermedi (manutenzione "best practice") nessuno lo fa.
IL CONTRATTO DICE CHE SONO GIUSTO il

5
Nota sul commento di @RayanBrady: le opzioni --distributee --setuptoolsnon sono più disponibili. (distribuire, quello era un fork di setuptools è stato unito molto tempo fa). --no-site-packagesè DEPRECATO, ora è il comportamento predefinito
JackNova,

49

Memorizzare la directory virtualenv in git, come hai notato, ti permetterà di distribuire l'intera app semplicemente eseguendo un clone git (oltre a installare e configurare Apache / mod_wsgi). Un problema potenzialmente significativo con questo approccio è che su Linux l'intero percorso viene codificato negli script di attivazione, django-admin.py, easy_install e pip di venv. Ciò significa che virtualenv non funzionerà completamente se si desidera utilizzare un percorso diverso, forse per eseguire più host virtuali sullo stesso server. Penso che il sito Web potrebbe effettivamente funzionare con i percorsi sbagliati in quei file, ma potresti avere problemi la prossima volta che provi a eseguire pip.

La soluzione, già fornita, è di archiviare sufficienti informazioni in git in modo che durante la distribuzione sia possibile creare virtualenv ed eseguire le necessarie installazioni di pip. In genere le persone corrono pip freezeper ottenere l'elenco, quindi memorizzarlo in un file denominato requisito.txt. Può essere caricato con pip install -r requirements.txt. RyanBrady ha già mostrato come è possibile mettere insieme le istruzioni di distribuzione in una sola riga:

# 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, li ho appena inseriti in uno script di shell che eseguo dopo aver eseguito il clone git o git pull.

Memorizzare la directory virtualenv rende anche un po 'più complicato gestire gli aggiornamenti di pip, poiché dovrai aggiungere / rimuovere manualmente e eseguire il commit dei file risultanti dall'aggiornamento. Con un file Requisito.txt, basta modificare le righe appropriate in Requisito.txt ed eseguire nuovamente pip install -r requirements.txt. Come già notato, ciò riduce anche il "commit dello spam".


4
Si noti che --distribute è ora deprecato (almeno in 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC

1
--no-site-packagesè deprecato anche in 15.1.0, poiché ora è l'impostazione predefinita.
cjs

35

Facevo lo stesso fino a quando non ho iniziato a utilizzare librerie compilate in modo diverso a seconda dell'ambiente come PyCrypto. Il mio Mac PyCrypto non funzionerebbe su Cygwin non funzionerebbe su Ubuntu.

Diventa un vero incubo gestire il repository.

In entrambi i casi ho trovato più facile gestire il congelamento del pip e un file dei requisiti piuttosto che avere tutto in git. È anche più pulito poiché puoi evitare lo spam di commit per migliaia di file mentre quelle librerie vengono aggiornate ...


Hmm. Sicuramente non avrò problemi con le cose compilate in modo diverso in ambienti diversi. Immagino che probabilmente valga la pena non farlo solo per evitare lo spam commesso.
Lyle Pratt,

@LylePratt: penso il contrario: meglio non includere virtualenv nel repository solo per evitare problemi con strumenti fantastici come PyCrypto o PIL.
Tadeck,

17

Penso che uno dei principali problemi che si verificano sia che virtualenv potrebbe non essere utilizzabile da altre persone. Il motivo è che utilizza sempre percorsi assoluti. Quindi, se virtualenv era per esempio /home/lyle/myenv/, assumerà lo stesso per tutte le altre persone che usano questo repository (deve essere esattamente lo stesso percorso assoluto). Non puoi presumere che le persone utilizzino la tua stessa struttura di directory.

La migliore pratica è che ognuno stia configurando il proprio ambiente (sia esso con o senza virtualenv) e vi installi librerie. Ciò rende anche il codice più utilizzabile su piattaforme diverse (Linux / Windows / Mac), anche perché virtualenv è installato in modo diverso in ciascuna di esse.


Questo è il motivo per cui è una cattiva idea mantenere un virtualv in SCM, ma vale la pena considerare qualcosa come il suggerimento di @ RJBrady o l'evento uno script bootstrap.py , in quanto avere dei mezzi per ricreare lo stesso ambiente su macchine è un grave necessità quando si lavora con altre persone.
ig0774,

Non sono davvero sicuro che il problema che hai citato sarebbe esattamente un problema nella mia situazione. La mia app Django contiene un file .wsgi che definisce la posizione di virtualenv rispetto alla sua posizione (2 directory su '../../env'). Quindi, nel mio scenario, il problema del percorso assoluto non dovrebbe influenzarmi negativamente ... giusto?
Lyle Pratt,

Se esegui la tua app sempre con WSGI, potresti cavartela. Se si utilizza il server di sviluppo (tramite manage.py), si verificheranno sicuramente dei problemi.
Torsten Engelbrecht,

3

Uso quella che è sostanzialmente la risposta di David Sickmiller con un po 'più di automazione. Creo un file (non eseguibile) al livello superiore del mio progetto denominato activatecon i seguenti contenuti:

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

(Secondo la risposta di David, questo presuppone che tu stia facendo un pip freeze > requirements.txtper mantenere aggiornato il tuo elenco di requisiti.)

Quanto sopra dà l'idea generale; l'effettivo script di attivazione ( documentazione ) che normalmente utilizzo è un po 'più sofisticato, offre -qun'opzione (silenziosa), da utilizzare pythonquando python3non è disponibile, ecc.

Questo può quindi provenire da qualsiasi directory di lavoro corrente e si attiverà correttamente, impostando prima l'ambiente virtuale se necessario. Il mio script di test di livello superiore di solito ha un codice su queste righe in modo che possa essere eseguito senza che lo sviluppatore debba prima attivare:

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

Il sourcing ./activate, no activate, è importante qui perché quest'ultimo troverà qualsiasi altro activatenel tuo percorso prima di trovare quello nella directory corrente.


Adoro questo approccio! Sembra molto ragionevole, grazie per averlo condiviso.
Esolitos,

Ho dovuto cambiare la prima riga per [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }rilevare se la sceneggiatura era stata eseguita anziché originata
Chris Snow,

3

Non è una buona idea includere qualsiasi componente o impostazione dipendente dall'ambiente nei repository come uno degli aspetti chiave dell'utilizzo di un repository, è forse condividerlo con altri sviluppatori. Ecco come impostare il mio ambiente di sviluppo su un PC Windows (diciamo Win10).

  1. Apri Pycharm e nella prima pagina, scegli di controllare il progetto dal tuo sistema di controllo del codice sorgente (nel mio caso, sto usando github)

  2. In Pycharm, vai alle impostazioni e scegli "Interprete di progetto" e scegli l'opzione per aggiungere un nuovo ambiente virtuale, puoi chiamarlo "venv".

  3. Scegli l'interprete Python di base che si trova in C: \ Users {utente} \ AppData \ Local \ Programmi \ Python \ Python36 (assicurati di scegliere la versione appropriata di Python in base a ciò che hai installato)

  4. Si noti che Pycharm creerà il nuovo ambiente virtuale e copierà i binari di Python e le librerie richieste nella cartella venv all'interno della cartella del progetto.

  5. Lascia che Pycharm completi la sua scansione quando è necessario ricostruire / aggiornare lo scheletro del progetto

  6. escludere la cartella venv dalle vostre interazioni Git (aggiungere \ venv a .gitignore file nella cartella del progetto)

Bonus: se vuoi che le persone installino facilmente (bene, quasi facilmente) tutte le librerie di cui il tuo software ha bisogno, puoi usare

pip freeze > requirements.txt

e metti le istruzioni su git in modo che le persone possano usare il seguente comando per scaricare contemporaneamente tutte le librerie richieste.

pip install -r requirements.txt 

2

Se sai su quali sistemi operativi funzionerà la tua applicazione, creerei un virtualenv per ciascun sistema e lo includerei nel mio repository. Quindi farei rilevare alla mia applicazione su quale sistema è in esecuzione e utilizzerei il virtualenv corrispondente.

Il sistema potrebbe ad esempio essere identificato utilizzando il modulo piattaforma .

In effetti, questo è ciò che faccio con un'applicazione interna che ho scritto e alla quale posso aggiungere rapidamente la virtualenv di un nuovo sistema nel caso fosse necessaria. In questo modo, non devo fare affidamento sul fatto che pip sarà in grado di scaricare correttamente il software richiesto dalla mia applicazione. Inoltre non dovrò preoccuparmi della compilazione di ad esempio psycopg2 che utilizzo.

Se non si conosce il sistema operativo su cui è possibile eseguire l'applicazione, probabilmente è meglio utilizzare pip freezecome suggerito nelle altre risposte qui.


0

Penso che la cosa migliore sia installare l'ambiente virtuale in un percorso all'interno della cartella del repository, forse è meglio includere una sottodirectory dedicata all'ambiente (ho eliminato accidentalmente l'intero progetto quando ho forzato l'installazione di un ambiente virtuale nella radice del repository cartella, bene che ho salvato il progetto nell'ultima versione in Github).

L'installatore automatico o la documentazione dovrebbero indicare il percorso virtualenv come percorso relativo, in questo modo non si verificheranno problemi durante la condivisione del progetto con altre persone. Per quanto riguarda i pacchetti, i pacchetti utilizzati devono essere salvati da pip freeze -r requirements.txt.


-1

Se stai solo configurando env di sviluppo, usa il file pip freeze, caz che rende pulito il repository git.

Quindi se si esegue la distribuzione di produzione, quindi controllare l'intera cartella venv. Ciò renderà la tua distribuzione più riproducibile, non avrà bisogno di quei pacchetti libxxx-dev ed eviterà i problemi di Internet.

Quindi ci sono due repository. Uno per il tuo codice sorgente principale, che include un requisito.txt. E un repo env, che contiene l'intera cartella venv.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.