2015-07-05 21 views
5

Sto cercando di integrare la finestra mobile nel mio flusso di lavoro django e ho tutto pronto tranne un problema davvero fastidioso. Se voglio aggiungere dipendenze al mio file requirements.txt, in pratica, devo solo ricostruire l'intera immagine del contenitore affinché queste dipendenze si incollino.Qual è un buon modo per aggiungere dipendenze python a un contenitore Docker?

Ad esempio, ho seguito l'esempio di docker-comporre per django here. il file YAML è impostato in questo modo:

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

e il file Docker utilizzato per costruire il contenitore web è impostato in questo modo:

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

Così, quando l'immagine è costruita per questo requisiti relativi al serbatoio. txt è installato con qualunque dipendenza ci sia inizialmente.

Se utilizzo questo come ambiente di sviluppo, diventa molto difficile aggiungere nuove dipendenze a quel file requirements.txt perché dovrò ricostruire il contenitore per le modifiche in requirements.txt da installare.

Esiste qualche sorta di best practice nella comunità django per occuparsi di questo? In caso contrario, direi che la finestra mobile è molto utile per il confezionamento di un'app una volta completata, ma non è molto buona da utilizzare come ambiente di sviluppo. Ci vuole molto tempo per ricostruire il contenitore, quindi viene sprecato un sacco di tempo.

Apprezzo qualsiasi intuizione. Grazie.

risposta

3

Si potrebbe montare requirements.txt come volume quando si utilizzano docker run (non testato, ma si ottiene il succo):

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

allora si potrebbe impacchettare uno script con il vostro contenitore che si svolgerà pip install -r requirements.txt prima di iniziare la vostra applicazione, e usalo come ENTRYPOINT. Adoro l'approccio di script di inserimento personalizzato, mi consente di fare un piccolo lavoro extra senza dover creare un nuovo contenitore.

Detto questo, se stai cambiando le tue dipendenze, probabilmente stai cambiando la tua applicazione e probabilmente dovresti creare un nuovo contenitore e taggarlo con una versione successiva, no? :)

+0

Sì, buona idea. Potrei semplicemente installare le dipendenze ogni volta che il contenitore si avvia. Ho intenzione di fare un tentativo. –

+1

@SpencerCooley A seconda del numero di dipendenze che si potrebbe desiderare, è necessario che il contenitore abbia quelle che si sa di avere sempre, quindi aggiungere semplicemente la possibilità di aggiungerne altre. Non vorrai che il contenitore impieghi diversi minuti per avviarsi. – 2rs2ts

+0

true, quindi l'immagine di base avrebbe tutte le basi e lo script di avvio installerebbe le dipendenze che sto usando durante il processo di sviluppo, come una sorta di elenco di dipendenze temporanee. Quando sono pronto a spingere tutto fuori posso solo spostare le dipendenze che deciderò sarà permanente per il sistema. A volte sto solo sperimentando con le librerie che non uso. È come un ambiente di sviluppo delle dipendenze. final_requirments.txt temp_requirements.txt –

3

così ho cambiato il file YAML a questo:

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

Ho fatto un semplice script di shell 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 

e poi ha fatto un dev-requirements.txt che è installato dallo script di shell sopra come una sorta di ambiente di gestione temporanea delle dipendenze.

quando sono soddisfatto di una dipendenza in dev-requirements.txt lo sposterò semplicemente verso il requisito.txt per essere impegnato per la successiva generazione dell'immagine. Ciò mi dà la possibilità di giocare con l'aggiunta e la rimozione delle dipendenze durante lo sviluppo.

0

Penso che il modo migliore sia ignorare quello che è attualmente il modo più comune per installare le dipendenze python (pip install -r requirements.txt) e specificare i requisiti direttamente nel Dockerfile, eliminando efficacemente il file requirements.txt. Inoltre, si ottiene la memorizzazione nella cache dei dockers gratuitamente.

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/ 

Se il contenitore di finestra mobile è l'unico modo in cui viene eseguita l'applicazione, quindi suggerirei di farlo in questo modo. Se vuoi supportare altri mezzi per impostare il tuo codice (ad es. Virtualenv), questo ovviamente non fa per te e dovresti ricorrere a un file dei requisiti o usare una routine setup.py. Ad ogni modo, ho trovato questo modo per essere più semplice e diretto senza affrontare tutti i problemi di distribuzione del pacchetto python incasinato.

+0

Potrei sbagliarmi, ma penso che questo approccio sia difettoso in quanto non garantisce che qualcun altro che costruisce da questo file docker ottenga le stesse versioni delle librerie. cioè non crea una build riproducibile. – jshen

+0

È da un po 'che ho usato la finestra mobile come questa. Puoi elaborare? –

Problemi correlati