2015-08-15 5 views
26

Utilizzo un contenitore Docker per lo sviluppo di Django e il contenitore esegue Gunicorn con Nginx. Mi piacerebbe che le modifiche al codice venissero caricate automaticamente, ma l'unico modo per caricarle è ricostruire con docker-compose (docker-compose build). Il problema con "build" è che esegue nuovamente tutte le mie installazioni di pip.Ripristino automatico delle modifiche al codice con lo sviluppo di Django in Docker con Gunicorn

Sto usando la bandiera Gunicorn --reload, che apparentemente dovrebbe fare ciò che voglio. Qui sono i miei Docker file di configurazione:

## Dockerfile: 
FROM python:3.4.3 
RUN mkdir /code 
WORKDIR /code 
ADD . /code/ 
RUN pip install -r /code/requirements/docker.txt 

## docker-compose.yml: 
web: 
    restart: always 
    build: . 
    expose: 
    - "8000" 
    links: 
    - postgres:postgres 
    volumes: 
    - /usr/src/app/static 
    env_file: .env 
    command: /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload 

nginx: 
    restart: always 
    build: ./config/nginx 
    ports: 
    - "80:80" 
    volumes: 
    - /www/static 
    volumes_from: 
    - web 
    links: 
    - web:web 

postgres: 
    restart: always 
    image: postgres:latest 
    volumes: 
    - /var/lib/postgresql 
    ports: 
    - "5432:5432" 

che ho provato alcuni degli altri comandi Docker (docker-compose restart, docker-compose up), ma il codice non verrà aggiornata.

Cosa mi manca?

+0

hai condiviso il volume con il tuo codice? Puoi pubblicare parte del tuo docker-compose.yml per visualizzare lo scenario? – kikicarbonell

+0

Non capisco il tuo "Il problema con" build "è che esegue di nuovo tutte le mie installazioni di pip." Forse puoi fare prima tutte le installazioni di pip, in modo che 'docker build' carichi solo le modifiche al codice. Puoi mostrare il tuo Dockerfile? Puoi anche avere un Dockerfile che inizia con 'FROM mypipinstalls' – user2915097

+0

kikicarbonell, la tua domanda mi ha aiutato a capire che avevo bisogno di un volume per il mio codice, e questo sembra aver risolto il problema, quindi grazie per avermi condotto alla soluzione! –

risposta

21

Grazie a kikicarbonell, ho cercato un volume per il mio codice, e dopo aver esaminato lo Docker Compose recommended Django setup, ho aggiunto volumes: - .:/code al mio contenitore web in docker-compose.yml e ora qualsiasi modifica al codice che applico automaticamente.

## docker-compose.yml: 
web: 
    restart: always 
    build: . 
    expose: 
    - "8000" 
    links: 
    - postgres:postgres 
    volumes: 
    - /usr/src/app/static 
    - .:/code 
    env_file: .env 
    command: /usr/local/bin/gunicorn myapp.wsgi:application -w 2 -b :8000 --reload 

Aggiornamento: Per un esempio completo di utilizzo di Gunicorn e Django con Docker, Checkout Questo example project from Rackspace, che mostra anche come utilizzare finestra mobile macchina per lanciare il programma di installazione su server remoti come Rackspace Cloud.

Caveat: attualmente, questo metodo non funziona quando il codice è in locale e l'host della docker è remoto (ad esempio, su un provider cloud come Digital Ocean o Rackspace). Questo vale anche per le macchine virtuali se il tuo file system locale non è montato sulla VM. Si noti che esistono driver di volume separati (ad esempio, flocker) e che lo potrebbe essere essere qualcosa là fuori per soddisfare questa esigenza. Per ora, la "correzione" è rsync/scp i file fino a una directory sull'host del docker remoto. Quindi, il flag --reload si ricaricherà automaticamente gunicorn dopo ogni scp/rsync. Aggiornamento: Se si spinge il codice per rimuovere l'host di docker, trovo molto più semplice ricostruire semplicemente il contenitore di finestra mobile (ad esempio, docker-compose build web && docker-compose up -d). Questo può essere più lento rispetto all'approccio rsync se la cartella src è grande.

+0

Ho pensato che inotify non funzionasse con i volumi di Docker. https://github.com/docker/docker/issues/18246 Qualche idea del perché funziona? –

+1

@EricIhli - Questo metodo non funziona quando l'host della finestra mobile è remoto (poiché le dichiarazioni di volume nel file Compose sono relative all'host della finestra mobile). Ho aggiornato la mia risposta con un disclaimer che chiarisce questo. –

+1

Ah. Grazie. Ho risolto il mio problema di dover guardare le modifiche ai file e fare qualche azione all'interno di un container usando 'fswatch' su Mac, collegando a 'xargs' ed eseguendo 'docker exec ', nel caso qualcuno stia cercando quella. –

14

Hai un altro problema: Docker memorizza nella cache ogni livello che crea. Non dovresti dover rieseguire l'installazione di pip ogni volta!

ADD . /code/ 
RUN pip install -r /code/requirements/docker.txt 

questo è il vostro problema-Docker controlla ogni ADD dichiarazione per vedere se tutti i file sono cambiati e invalida la cache per esso e ogni passo in seguito se ne ha. Il modo corretto per farlo è ...

ADD ./requirements/docker.txt /code/requirements/ 
RUN pip install -r /code/requirements/docker.txt 
ADD ./code/ 

Quale invaliderà solo il tuo pip installare linea Se i requisiti modifiche dei file!

+0

Mi chiedevo perché l'ADD era ridondante. Grazie per avermi fatto sapere –