Ist es schlecht, mein virtualenv-Verzeichnis in meinem Git-Repository zu haben?

284

Ich denke darüber nach, die virtuelle Umgebung für eine Django-Web-App, die ich erstelle, in mein Git-Repository für die App zu stellen. Es scheint eine einfache Möglichkeit zu sein, die Bereitstellung einfach und unkompliziert zu halten. Gibt es einen Grund, warum ich das nicht tun sollte?

Lyle Pratt
quelle

Antworten:

301

Ich verwende pip freeze, um die benötigten Pakete in eine requirements.txtDatei zu bekommen und diese meinem Repository hinzuzufügen. Ich habe versucht, einen Weg zu finden, warum Sie die gesamte virtuelle Umgebung speichern möchten, aber ich konnte nicht.

RyanBrady
quelle
81
Sie können den unnötigen Speicherplatz in Ihrem Repo sparen und dennoch mit einem einzigen Befehl auf einem neuen Server bereitstellen: virtualenv --no-site-packages --distribute .env && source .env / bin / enabled && pip install -r require.txt
RyanBrady
2
Ich gebe Ihnen die Antwort auf diese Frage, da es wahrscheinlich die "beste Praxis" ist und Sie sie zuerst angeboten haben. Ich bin definitiv auf einige der Probleme gestoßen, die jeder erwähnt hat. Ich schätze, ich gebe mir noch einen Tag Zeit, um damit herumzuspielen, bevor ich einfach das tue, was ihr die ganze Zeit vorgeschlagen habt, und pip und eine Anforderungsdatei verwende. Danke für Ihre Hilfe!
Lyle Pratt
11
Wenn Sie beispielsweise pip install mysql-pythonauf einem 64-Bit-Computer arbeiten und dann jemand mit einem 32-Bit-Computer versucht, ihn zu verwenden, funktioniert er nicht. Wie bei vielen Python-Modulen wird ein C-Modul verwendet, um die Leistung zu steigern. Ich stelle mir vor, Windows-> Linux würde auch nicht funktionieren.
Matt Williamson
7
Nur eine Bemerkung: Wir haben uns in der Vergangenheit etwas Zeit gelassen, weil Bibliotheken von pip (Version zu alt) nicht mehr verfügbar sind und ein Upgrade erzwingen, während die Site nicht verfügbar war. Also ... ich werde mich jetzt nie wieder darauf verlassen pip freeze, dies zu tun. Das Problem ist, dass während Ihrer erzwungenen erneuten Bereitstellung niemand dafür bezahlt und für Zwischen-Upgrades ("Best Practice" -Wartung) auch niemand.
sagt, ich habe Recht
5
Hinweis zum @ RayBrady-Kommentar: Die Optionen --distributeund --setuptoolssind jetzt nicht mehr verfügbar . (verteilen, das war eine Gabelung von Setuptools, die vor langer Zeit wieder zusammengeführt wurde). --no-site-packagesist DEPRECATED, es ist jetzt das Standardverhalten
JackNova
48

Wenn Sie das Verzeichnis virtualenv in git speichern, können Sie, wie bereits erwähnt, die gesamte App bereitstellen, indem Sie einfach einen git-Klon ausführen (plus Apache / mod_wsgi installieren und konfigurieren). Ein potenziell bedeutendes Problem bei diesem Ansatz ist, dass unter Linux der vollständige Pfad in den Aktivierungs-, django-admin.py-, easy_install- und pip-Skripten des venv fest codiert wird. Dies bedeutet, dass Ihre virtuelle Umgebung nicht vollständig funktioniert, wenn Sie einen anderen Pfad verwenden möchten, um möglicherweise mehrere virtuelle Hosts auf demselben Server auszuführen. Ich denke, die Website funktioniert möglicherweise tatsächlich mit den in diesen Dateien falschen Pfaden, aber Sie würden Probleme haben, wenn Sie das nächste Mal versuchen, pip auszuführen.

Die bereits gegebene Lösung besteht darin, genügend Informationen in git zu speichern, damit Sie während der Bereitstellung die virtuelle Umgebung erstellen und die erforderlichen Pip-Installationen durchführen können. Normalerweise werden Benutzer ausgeführt pip freeze, um die Liste abzurufen, und sie dann in einer Datei mit dem Namen require.txt gespeichert. Es kann mit geladen werden pip install -r requirements.txt. RyanBrady hat bereits gezeigt, wie Sie die Bereitstellungsanweisungen in einer einzigen Zeile aneinanderreihen können:

# 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

Persönlich habe ich diese einfach in ein Shell-Skript eingefügt, das ich nach dem Git-Klon oder Git-Pull ausführe.

Das Speichern des Verzeichnisses virtualenv macht es auch etwas schwieriger, Pip-Upgrades durchzuführen, da Sie die aus dem Upgrade resultierenden Dateien manuell hinzufügen / entfernen und festschreiben müssen. Bei einer Datei "resources.txt" ändern Sie einfach die entsprechenden Zeilen in "resources.txt" und führen sie erneut aus pip install -r requirements.txt. Wie bereits erwähnt, reduziert dies auch das "Festschreiben von Spam".

David Sickmiller
quelle
4
Beachten Sie, dass --distribute jetzt veraltet ist (mindestens in 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC
1
--no-site-packagesist auch in 15.1.0 veraltet, da dies jetzt die Standardeinstellung ist.
cjs
35

Früher habe ich dasselbe gemacht, bis ich angefangen habe, Bibliotheken zu verwenden, die je nach Umgebung wie PyCrypto unterschiedlich kompiliert werden. Mein PyCrypto-Mac würde unter Cygwin unter Ubuntu nicht funktionieren.

Es wird zu einem Albtraum, das Repository zu verwalten.

In beiden Fällen war es für mich einfacher, das Einfrieren von Pip und eine Anforderungsdatei zu verwalten, als alles in Git zu haben. Es ist auch sauberer, da Sie den Commit-Spam für Tausende von Dateien vermeiden können, wenn diese Bibliotheken aktualisiert werden ...

Yuji 'Tomita' Tomita
quelle
Hmm. Ich werde definitiv keine Probleme damit haben, Dinge in verschiedenen Umgebungen unterschiedlich zu kompilieren. Ich denke, es lohnt sich wahrscheinlich, es nicht nur zu tun, um den Commit-Spam zu vermeiden.
Lyle Pratt
@LylePratt: Ich denke das Gegenteil: Besser nicht die gesamte virtuelle Umgebung in das Repository aufnehmen, nur um Probleme mit so großartigen Tools wie PyCrypto oder PIL zu vermeiden.
Tadeck
17

Ich denke, eines der Hauptprobleme ist, dass die virtuelle Umgebung möglicherweise nicht von anderen Personen verwendet werden kann. Grund ist, dass immer absolute Pfade verwendet werden. Wenn Sie also beispielsweise in virtualenv waren /home/lyle/myenv/, wird für alle anderen Personen, die dieses Repository verwenden, dasselbe angenommen (es muss genau derselbe absolute Pfad sein). Sie können nicht davon ausgehen, dass Personen dieselbe Verzeichnisstruktur wie Sie verwenden.

Besser ist es, wenn jeder seine eigene Umgebung (mit oder ohne Virtualenv) einrichtet und dort Bibliotheken installiert. Dadurch können Sie Code auch auf verschiedenen Plattformen (Linux / Windows / Mac) besser verwenden, da virtualenv in jeder Plattform unterschiedlich installiert ist.

Torsten Engelbrecht
quelle
Dies ist genau richtig, warum es eine schlechte Idee ist, eine virtuelle Umgebung in SCM zu behalten, aber es lohnt sich, entweder etwas wie den Vorschlag von @ RJBrady oder ein Ereignis für ein bootstrap.py-Skript in Betracht zu ziehen , da es eine Möglichkeit gibt, dieselbe Umgebung auf allen Computern neu zu erstellen ernsthafte Notwendigkeit bei der Arbeit mit anderen Menschen.
ig0774
Ich bin mir nicht sicher, ob das von Ihnen erwähnte Problem genau in meiner Situation ein Problem darstellt. Meine Django-App enthält eine .wsgi-Datei, die definiert, wo sich die virtuelle Umgebung relativ zu ihrem Speicherort befindet (2 Verzeichnisse nach oben '../../env'). In meinem Szenario sollte mich das absolute Pfadproblem also nicht negativ beeinflussen ... richtig?
Lyle Pratt
Wenn Sie Ihre App immer mit WSGI ausführen, kommen Sie möglicherweise damit durch. Wenn Sie den Entwicklungsserver (über manage.py) verwenden, werden Sie mit Sicherheit auf Probleme stoßen.
Torsten Engelbrecht
3

Ich verwende die Antwort von David Sickmiller mit etwas mehr Automatisierung. Ich erstelle eine (nicht ausführbare) Datei auf der obersten Ebene meines Projekts activatemit dem folgenden Inhalt:

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

(Gemäß Davids Antwort wird davon ausgegangen pip freeze > requirements.txt, dass Sie Ihre Liste der Anforderungen auf dem neuesten Stand halten.)

Das Obige gibt die allgemeine Idee; Das eigentliche Aktivierungsskript ( Dokumentation ), das ich normalerweise verwende, ist etwas ausgefeilter und bietet eine -q(leise) Option, die Verwendung, pythonwenn sie python3nicht verfügbar ist usw.

Dies kann dann aus jedem aktuellen Arbeitsverzeichnis bezogen werden und wird ordnungsgemäß aktiviert, wobei bei Bedarf zuerst die virtuelle Umgebung eingerichtet wird. Mein Testskript der obersten Ebene enthält normalerweise Code in dieser Richtung, sodass er ausgeführt werden kann, ohne dass der Entwickler ihn zuerst aktivieren muss:

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

Die Beschaffung ist hier ./activatenicht activatewichtig, da letztere andere activateauf Ihrem Weg finden, bevor sie die im aktuellen Verzeichnis finden.

cjs
quelle
Ich liebe diesen Ansatz! Klingt sehr vernünftig, danke fürs Teilen.
Esolitos
Ich musste die erste Zeile ändern, [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }um festzustellen, ob das Skript im Gegensatz zu Sourcing ausgeführt wurde
Chris Snow,
3

Es ist keine gute Idee, umgebungsabhängige Komponenten oder Einstellungen in Ihre Repos aufzunehmen, da einer der Schlüsselaspekte bei der Verwendung eines Repos darin besteht, sie möglicherweise mit anderen Entwicklern zu teilen. So würde ich meine Entwicklungsumgebung auf einem Windows-PC einrichten (z. B. Win10).

  1. Öffnen Sie Pycharm und wählen Sie auf der ersten Seite das Projekt aus Ihrem Versionsverwaltungssystem aus (in meinem Fall verwende ich Github).

  2. Navigieren Sie in Pycharm zu den Einstellungen, wählen Sie "Projektinterpreter" und wählen Sie die Option zum Hinzufügen einer neuen virtuellen Umgebung. Sie können sie "venv" nennen.

  3. Wählen Sie den Basis-Python-Interpreter aus, der sich unter C: \ Users {user} \ AppData \ Local \ Programs \ Python \ Python36 befindet (stellen Sie sicher, dass Sie die entsprechende Version von Python basierend auf Ihrer Installation auswählen).

  4. Beachten Sie, dass Pycharm die neue virtuelle Umgebung erstellt und Python-Binärdateien und erforderliche Bibliotheken in Ihren venv-Ordner in Ihrem Projektordner kopiert.

  5. Lassen Sie Pycharm den Scanvorgang abschließen, um Ihr Projektskelett neu zu erstellen / zu aktualisieren

  6. Schließen Sie den venv-Ordner von Ihren Git-Interaktionen aus (fügen Sie venv \ zur .gitignore- Datei in Ihrem Projektordner hinzu).

Bonus: Wenn Sie möchten, dass Benutzer alle (einfach, fast einfach) alle Bibliotheken installieren, die Ihre Software benötigt, können Sie sie verwenden

pip freeze > requirements.txt

und fügen Sie die Anweisung in Ihr Git ein, damit Benutzer den folgenden Befehl verwenden können, um alle erforderlichen Bibliotheken gleichzeitig herunterzuladen.

pip install -r requirements.txt 
William Pourmajidi
quelle
2

Wenn Sie wissen, auf welchen Betriebssystemen Ihre Anwendung ausgeführt wird, würde ich für jedes System eine virtuelle Umgebung erstellen und diese in mein Repository aufnehmen. Dann würde ich meine Anwendung erkennen lassen, auf welchem ​​System sie ausgeführt wird, und die entsprechende virtuelle Umgebung verwenden.

Das System könnte zB anhand des Plattformmoduls identifiziert werden .

Tatsächlich mache ich das mit einer von mir geschriebenen internen Anwendung, zu der ich bei Bedarf schnell die virtuelle Umgebung eines neuen Systems hinzufügen kann. Auf diese Weise muss ich mich nicht darauf verlassen, dass pip die für meine Anwendung erforderliche Software erfolgreich herunterladen kann. Ich muss mich auch nicht um die Kompilierung von zB psycopg2 kümmern, die ich benutze.

Wenn Sie nicht wissen, auf welchem ​​Betriebssystem Ihre Anwendung ausgeführt werden kann, sollten Sie wahrscheinlich besser verwenden, pip freezewie in anderen Antworten hier vorgeschlagen.

fredrik
quelle
0

Ich denke, das Beste ist, die virtuelle Umgebung in einem Pfad innerhalb des Repository-Ordners zu installieren. Vielleicht ist es besser, ein der Umgebung zugeordnetes Unterverzeichnis zu verwenden (ich habe versehentlich mein gesamtes Projekt gelöscht, als ich die Installation einer virtuellen Umgebung im Repository-Stamm erzwang Ordner, gut, dass ich das Projekt in seiner neuesten Version in Github gespeichert hatte).

Entweder das automatisierte Installationsprogramm oder die Dokumentation sollten den Pfad für die virtuelle Umgebung als relativen Pfad angeben. Auf diese Weise treten keine Probleme auf, wenn Sie das Projekt für andere Personen freigeben. Über die Pakete sollten die verwendeten Pakete von gespeichert werden pip freeze -r requirements.txt.

Lucioric2000
quelle
-1

Wenn Sie nur die Entwicklungsumgebung einrichten, verwenden Sie die Pip-Freeze-Datei caz, die das Git-Repo sauber macht.

Wenn Sie dann eine Produktionsbereitstellung durchführen, checken Sie den gesamten venv-Ordner ein. Dadurch wird Ihre Bereitstellung reproduzierbarer, Sie benötigen diese libxxx-dev-Pakete nicht und vermeiden Internetprobleme.

Es gibt also zwei Repos. Eine für Ihren Hauptquellcode, die eine Anforderungen.txt enthält. Und ein env repo, das den gesamten venv-Ordner enthält.

Shuo
quelle