2015-07-05 12 views
5

Ich versuche, Docker in meinem Django-Workflow zu integrieren und ich habe alles außer einem wirklich nervigen Problem eingerichtet. Wenn ich Abhängigkeiten zu meiner requirements.txt Datei hinzufügen möchte, muss ich im Grunde nur das gesamte Container-Image für diese Abhängigkeiten neu erstellen.Was ist eine gute Möglichkeit, Python-Abhängigkeiten zu einem Docker-Container hinzuzufügen?

Zum Beispiel folgte ich dem Docker-komponieren Beispiel für Django here. die YAML-Datei ist wie folgt aufgebaut:

db: 
    image: postgres 
web: 
    build: . 
    command: python manage.py runserver 0.0.0.0:8000 
    volumes: 
    - .:/code 
    ports: 
    - "8000:8000" 
    links: 
    - db 

und die Docker Datei, um die Web-Container zu bauen verwendet wird, wie folgt aufgebaut: ist

FROM python:2.7 
ENV PYTHONUNBUFFERED 1 
RUN mkdir /code 
WORKDIR /code 
ADD requirements.txt /code/ 
RUN pip install -r requirements.txt 
ADD . /code/ 

Also, wenn das Bild für diese Container Anforderungen gebaut. txt wird mit den ursprünglich vorhandenen Abhängigkeiten installiert.

Wenn ich dies als meine Entwicklungsumgebung benutze, wird es sehr schwierig neue Abhängigkeiten zu dieser requirements.txt Datei hinzuzufügen, da ich den Container für die Änderungen in der zu installierenden requirements.txt neu erstellen muss.

Gibt es eine Art Best Practice in der Django-Community, um damit umzugehen? Wenn nicht, würde ich sagen, dass docker sehr schön aussieht, um eine App zu packen, sobald sie fertig ist, aber nicht sehr gut als Entwicklungsumgebung verwendet werden kann. Der Wiederaufbau des Containers dauert sehr lange, so dass viel Zeit verschwendet wird.

Ich schätze jeden Einblick. Vielen Dank.

Antwort

3

Sie könnten requirements.txt als Volume aktivieren, wenn docker run mit (nicht getestet, aber Sie erhalten den Kern):

docker run container:tag -v /code/requirements.txt ./requirements.txt 

Dann könnten Sie ein Skript mit Ihrem Container bündeln, die pip install -r requirements.txt laufen wird, bevor die Anwendung starten, und Verwenden Sie das als Ihre ENTRYPOINT. Ich liebe den Ansatz des benutzerdefinierten Einstiegspunkt-Scripts, mit dem ich ein wenig mehr arbeiten kann, ohne einen neuen Container erstellen zu müssen.

Das heißt, wenn Sie Ihre Abhängigkeiten ändern, ändern Sie wahrscheinlich Ihre Anwendung und Sie sollten wahrscheinlich einen neuen Container erstellen und es mit einer späteren Version markieren, nein? :)

+0

Ja, gute Idee. Ich könnte nur Abhängigkeiten installieren lassen, wann immer der Container startet. Ich werde es versuchen. –

+1

@SpencerCooley Je nachdem, wie viele Abhängigkeiten Sie haben, möchten Sie vielleicht, dass der Container diejenigen enthält, von denen Sie wissen, dass Sie sie immer haben werden, und dann einfach die Fähigkeit hinzufügen, mehr hinzuzufügen. Sie möchten nicht, dass der Container mehrere Minuten zum Starten benötigt. – 2rs2ts

+0

true, also würde das Basisimage alle Grundlagen haben und das Startskript würde Abhängigkeiten installieren, die ich während des Entwicklungsprozesses verwende, wie eine Art temporäre Abhängigkeitsliste. Wenn ich bereit bin, alles rauszuschieben, kann ich einfach die Abhängigkeiten verschieben, von denen ich feststelle, dass sie für das System permanent sind. Manchmal experimentiere ich nur mit Bibliotheken, die ich nicht benutze. Es ist wie eine Dependency-Dev-Umgebung. final_requirments.txt temp_requirements.txt –

3

Also änderte es die YAML-Datei dazu:

#!/bin/bash 

#restart this script as root, if not already root 
[ `whoami` = root ] || exec sudo $0 $* 

pip install -r dev-requirements.txt 

python manage.py runserver 0.0.0.0:8000 

und dann einen Entwickler-requirements.txt das ist:

db: 
    image: postgres 
web: 
    build: . 
    command: sh startup.sh 
    volumes: 
    - .:/code 
    ports: 
    - "8000:8000" 
    links: 
    - db 

ich einen einfachen Shell-Skript startup.sh gemacht Diese Shell wird vom obigen Shell-Skript als eine Art Staging-Umgebung für Abhängigkeiten installiert.

Wenn ich mit einer Abhängigkeit in der Datei dev-requirements.txt zufrieden bin, werde ich sie einfach in die requirements.txt verschieben, um sie dem nächsten Build des Images zu übergeben. Dies gibt mir die Flexibilität, mit dem Hinzufügen und Entfernen von Abhängigkeiten während der Entwicklung zu spielen.

0

Ich denke, der beste Weg ist zu ignorieren, was derzeit die gängigste Möglichkeit ist, Python-Abhängigkeiten zu installieren (pip install -r requirements.txt) und spezifizieren Sie Ihre Anforderungen direkt in der Dockerfile, effektiv loszuwerden die requirements.txt Datei. Zusätzlich erhalten Sie Docker Layer Caching kostenlos.

FROM python:2.7 
ENV PYTHONUNBUFFERED 1 
RUN mkdir /code 
WORKDIR /code 
# make sure you install requirements before the ADD, since everything after ADD is not cached 
RUN pip install flask==0.10.1 
RUN pip install sqlalchemy==1.0.6 
... 
ADD . /code/ 

Wenn die Docker Behälter der einzige Weg, um Ihre Anwendung ist immer läuft, dann würde ich vorschlagen, dass Sie es auf diese Weise tun. Wenn Sie andere Mittel zur Einrichtung Ihres Codes (z. B. virtualenv) unterstützen möchten, ist dies natürlich nicht für Sie und Sie sollten entweder auf eine Anforderungsdatei zurückgreifen oder eine setup.py-Routine verwenden. So oder so, ich fand diesen Weg am einfachsten und unkompliziertsten, ohne sich mit all den verpatzten Python-Paket-Verteilungsproblemen herumschlagen zu müssen.

+0

Ich könnte mich irren, aber ich denke, dieser Ansatz ist insofern fehlerhaft, als er nicht sicherstellt, dass jemand anderes, der aus dieser Dockerdatei baut, die gleichen Versionen von Bibliotheken bekommt. d.h. es erzeugt keinen reproduzierbaren Aufbau. – jshen

+0

Es ist eine Weile her, dass ich Docker so verwendet habe. Kannst du es ausarbeiten? –

Verwandte Themen