2015-07-05 8 views
5

Próbuję zintegrować doker z moim przepływem pracy django i mam wszystko skonfigurowane z wyjątkiem jednego naprawdę irytującego problemu. Jeśli chcę dodać zależności do mojego pliku requirements.txt, muszę po prostu odbudować cały obraz kontenera, aby te zależności się utrzymały.Jaki jest dobry sposób dodawania zależności Pythona do kontenera Docker?

Na przykład poszedłem za przykładem dokera-komponowania dla django here. plik yaml jest skonfigurowany tak:

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

a plik Docker wykorzystane do budowy kontenera WWW jest skonfigurowany tak:

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

Więc gdy obraz jest zbudowany na tej wymagań kontenerowych. txt jest instalowany z wszystkimi zależnościami, które są na nim początkowo.

Jeśli używam tego jako środowiska programistycznego, bardzo trudno jest dodać nowe zależności do pliku requirements.txt, ponieważ będę musiał przebudować kontener, aby zmiany w pliku requirements.txt zostały zainstalowane.

Czy istnieje jakaś dobra praktyka w społeczności django, aby sobie z tym poradzić? Jeśli nie, powiedziałbym, że docker wygląda bardzo ładnie, aby upakować aplikację po jej ukończeniu, ale nie jest zbyt dobry do użycia jako środowisko programistyczne. Zbudowanie kontenera zajmuje dużo czasu, więc marnuje się dużo czasu.

Doceniam każdy wgląd. Dzięki.

Odpowiedz

3

Można zamontować requirements.txt jako wolumin przy użyciu docker run (niesprawdzone, ale masz GIST):

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

Następnie można osadzić skrypt z kontenera, który będzie działał pip install -r requirements.txt przed uruchomieniem aplikacji, a użyj tego jako swojego ENTRYPOINT. Uwielbiam niestandardowe podejście do skryptów z punktami wejścia, pozwala mi to wykonać trochę dodatkowej pracy bez konieczności tworzenia nowego kontenera.

Mimo to, jeśli zmieniasz swoje zależności, prawdopodobnie zmieniasz aplikację i prawdopodobnie powinieneś utworzyć nowy kontener i oznaczyć go późniejszą wersją, nie? :)

+0

Tak, dobry pomysł. Mogę po prostu mieć to zainstalowanie zależności przy każdym uruchomieniu kontenera. Mam zamiar spróbować. –

+1

@SpencerCooley W zależności od tego, ile masz zależności, możesz chcieć, aby kontener miał te, które wiesz, że zawsze będziesz miał, a następnie po prostu dodaj możliwość dodawania kolejnych. Nie chciałbyś, aby kontener potrzebował kilku minut na uruchomienie. – 2rs2ts

+0

prawda, więc obraz podstawowy miałby wszystkie podstawy, a skrypt startowy instalowałby zależności, których używam podczas procesu tworzenia, jak rodzaj tymczasowej listy zależności. Kiedy jestem gotowy, aby to wszystko wypchnąć, mogę po prostu przejść przez zależności, które zdecyduję, będą trwałe dla systemu. Czasami eksperymentuję z bibliotekami, których nie używam. To jest jak środowisko deweloperów zależnych. final_requirments.txt temp_requirements.txt –

3

Więc zmieniłem plik YAML do tego:

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

Zrobiłem prosty skrypt powłoki startup.sh:

#!/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 

a następnie popełnił dev-requirements.txt który jest zainstalowane przez powyższy skrypt powłoki jako rodzaj środowiska pomostowego zależności.

kiedy jestem zadowolony z zależności w dev-requirements.txt, po prostu przeniosę ją do pliku requirements.txt, aby zatwierdzić następną kompilację obrazu. Daje mi to swobodę gry podczas dodawania i usuwania zależności podczas tworzenia.

0

Myślę, że najlepszym sposobem jest zignorowanie tego, co jest obecnie najczęstszym sposobem instalowania zależności Pythona (pip install -r requirements.txt) i określanie wymagań bezpośrednio w pliku Dockerfilm, skutecznie pozbywając się pliku requirements.txt. Dodatkowo buforowanie warstwy dokerów jest bezpłatne.

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/ 

Jeśli pojemnik doker jest jedynym sposobem zgłoszenie zostanie kiedykolwiek biegać, to proponuję zrobić to w ten sposób. Jeśli chcesz wesprzeć inne sposoby konfigurowania kodu (na przykład virtualenv), to oczywiście nie jest to dla ciebie i powinieneś spróbować użyć pliku wymagań lub użyć procedury setup.py. Tak czy inaczej, znalazłem w ten sposób najprostszą i prostą bez zajmowania się wszystkimi problemami dystrybucji pakietów python.

+0

Mogę się mylić, ale uważam, że takie podejście jest wadliwe, ponieważ nie zapewnia, że ​​ktoś inny, kto buduje z tego pliku docker, będzie miał te same wersje bibliotek. to znaczy nie tworzy odtwarzalnej wersji. – jshen

+0

Jakiś czas temu użyłem takiego okna. Czy możesz rozwinąć? –