Posso eseguire più programmi in un contenitore Docker?

Sto cercando di comprendere Docker dal punto di distribuzione di un’applicazione destinata agli utenti sul desktop. La mia applicazione è semplicemente un’applicazione web per flask e un database mongo. Normalmente installerei entrambi in una VM e inoltra una porta host all’app Web ospite. Mi piacerebbe provare Docker, ma non sono sicuro di come intendevo usare più di un programma. Le documentazioni dicono che ci può essere solo ENTRYPOINT, quindi come posso avere Mongo e la mia applicazione di flask. O hanno bisogno di essere contenuti separati, nel qual caso come parlano tra loro e in che modo questo rende facile distribuire l’app?

Può esserci solo un ENTRYPOINT, ma quell’objective è solitamente uno script che avvia tutti i programmi necessari. È inoltre ansible utilizzare ad esempio Supervisord o simili per occuparsi di avviare più servizi all’interno di un singolo contenitore. Questo è un esempio di un container mobile che esegue mysql, apache e wordpress all’interno di un singolo contenitore .

Di ‘, hai un database che viene utilizzato da una singola applicazione web. Quindi è probabilmente più facile da eseguire in un unico contenitore.

Se si dispone di un database condiviso utilizzato da più di un’applicazione, è consigliabile eseguire il database nel proprio contenitore e le applicazioni nei relativi contenitori.

Esistono almeno due possibilità su come le applicazioni possono comunicare tra loro quando sono in esecuzione in contenitori diversi:

  1. Utilizzare le porte IP esposte e connettersi tramite esse.
  2. Le versioni recenti della finestra mobile supportano il collegamento .

Avevo requisiti simili per l’esecuzione di uno stack LAMP, di Mongo DB e dei miei servizi

Docker è virtualizzazione basata su OS, motivo per cui isola il suo contenitore attorno a un processo in esecuzione, quindi richiede almeno un processo in esecuzione in FOREGROUND.

Quindi fornisci il tuo script di avvio come punto di ingresso, quindi lo script di avvio diventa uno script di immagine Docker esteso, in cui puoi impilare qualsiasi numero di servizi fino a che non viene avviato il SERVIZIO DI ALMENO UN PRIMO PIANO, CHE ANCHE VERSO LA FINE

Quindi il mio file di immagine Docker ha due righe sotto alla fine:

COPY myStartupScript.sh /usr/local/myscripts/myStartupScript.sh CMD ["/bin/bash", "/usr/local/myscripts/myStartupScript.sh"] 

Nel mio script eseguo tutti MySQL, MongoDB, Tomcat ecc. Alla fine eseguo il mio Apache come thread in primo piano.

 source /etc/apache2/envvars /usr/sbin/apache2 -DFOREGROUND 

Ciò mi consente di avviare tutti i miei servizi e mantenere attivo il contenitore con l’ultimo servizio iniziato in primo piano

Spero che sia d’aiuto

AGGIORNAMENTO : Dall’ultima volta che ho risposto a questa domanda, sono venute fuori nuove cose come Docker Compose , che può aiutarti a eseguire ogni servizio sul proprio contenitore, e tuttavia associarli tutti insieme come dipendenze tra questi servizi, prova a saperne di più sulla finestra mobile-compose e usalo, è un modo più elegante a meno che il tuo bisogno non corrisponda ad esso.

Possono essere in contenitori separati e, in effetti, se l’applicazione fosse pensata anche per l’esecuzione in un ambiente più ampio, probabilmente lo sarebbero.

Un sistema multi-contenitore richiederebbe un po ‘più di orchestrazione per essere in grado di richiamare tutte le dipendenze richieste, sebbene in Docker v0.6.5 +, ci sia una nuova funzionalità per aiutare con quella incorporata nella Docker stessa – Collegamento . Con una soluzione multi-macchina, tuttavia, è ancora qualcosa che deve essere organizzato dall’esterno dell’ambiente Docker.

Con due contenitori diversi, le due parti comunicano ancora su TCP / IP, ma a meno che le porte non siano state bloccate in modo specifico (non consigliato, dato che non potresti eseguire più di una copia), dovresti passare la nuova porta che il database è stato esposto all’applicazione, in modo che possa comunicare con Mongo. Questo è ancora, qualcosa a cui Linking può aiutare.

Per un’installazione più semplice e di piccole dimensioni, in cui tutte le dipendenze vanno nello stesso contenitore, è ansible anche il runtime di database e Python avviato dal programma inizialmente chiamato ENTRYPOINT. Questo può essere semplice come uno script di shell o qualche altro controller di processo: Supervisord è piuttosto popolare e esistono un certo numero di esempi nei Dockerfiles pubblici.

Sono d’accordo con le altre risposte che l’utilizzo di due contenitori è preferibile, ma se hai il cuore impostato sul bunding di più servizi in un singolo contenitore puoi usare qualcosa come supervisord.

in Hipache, ad esempio, il Dockerfile incluso esegue supervisord, e il file supervisord.conf specifica per l’esecuzione sia di hipache che di redis-server.

Docker fornisce un paio di esempi su come farlo. L’opzione leggera è:

Metti tutti i tuoi comandi in uno script wrapper, completo di informazioni di test e di debug. Esegui lo script wrapper come CMD . Questo è un esempio molto ingenuo. Innanzitutto, lo script del wrapper:

 #!/bin/bash # Start the first process ./my_first_process -D status=$? if [ $status -ne 0 ]; then echo "Failed to start my_first_process: $status" exit $status fi # Start the second process ./my_second_process -D status=$? if [ $status -ne 0 ]; then echo "Failed to start my_second_process: $status" exit $status fi # Naive check runs checks once a minute to see if either of the processes exited. # This illustrates part of the heavy lifting you need to do if you want to run # more than one service in a container. The container will exit with an error # if it detects that either of the processes has exited. # Otherwise it will loop forever, waking up every 60 seconds while /bin/true; do ps aux |grep my_first_process |grep -q -v grep PROCESS_1_STATUS=$? ps aux |grep my_second_process |grep -q -v grep PROCESS_2_STATUS=$? # If the greps above find anything, they will exit with 0 status # If they are not both 0, then something is wrong if [ $PROCESS_1_STATUS -ne 0 -o $PROCESS_2_STATUS -ne 0 ]; then echo "One of the processes has already exited." exit -1 fi sleep 60 done 

Successivamente, il file Docker:

 FROM ubuntu:latest COPY my_first_process my_first_process COPY my_second_process my_second_process COPY my_wrapper_script.sh my_wrapper_script.sh CMD ./my_wrapper_script.sh 

Sono fortemente in disaccordo con alcune soluzioni precedenti che consigliavano di eseguire entrambi i servizi nello stesso contenitore. Esistono buoni casi d’uso per supervisord o programmi simili ma l’esecuzione di un database di applicazioni Web + non fa parte di essi.

Dovresti assolutamente usare docker-compose per farlo.