2016-06-15 29 views
7

Ho un'immagine Docker che utilizza uno script (/bin/bash /init.sh) come un punto di accesso. Vorrei eseguire questo script solo al primo avvio di un contenitore. Deve essere omesso quando i contenitori vengono riavviati o riavviati dopo un arresto anomalo del daemon docker.Esegui comando nel contenitore mobile solo al primo avvio

Esiste un modo per farlo con la finestra mobile o se è necessario implementare qualche tipo di controllo nello script?

risposta

9

Il punto di ingresso per un contenitore finestra mobile indica al daemon docker cosa eseguire quando si desidera "eseguire" quel contenitore specifico. Facciamo le domande "che cosa deve eseguire il contenitore quando viene avviato la seconda volta?" o "cosa deve essere eseguito dal contenitore dopo il riavvio?"

Probabilmente, quello che stai facendo è seguire lo stesso approccio che fai con i meccanismi di "vecchia scuola". Il tuo script sta "installando" gli script necessari e tu eseguirai la tua app come un servizio systemd/upstart, giusto? Se lo fai, dovresti cambiarlo in una definizione più "dockerized".

Il punto di ingresso per tale contenitore deve essere uno script che avvia effettivamente l'app anziché impostare le cose. Supponiamo che sia necessario installare java per poter eseguire la tua app. Così nel dockerfile si imposta il contenitore di base per installare tutte le cose che avete bisogno come:

FROM alpine:edge 

RUN apk --update upgrade && apk add openjdk8-jre-base 
RUN mkdir -p /opt/your_app/ && adduser -HD userapp 

ADD target/your_app.jar /opt/your_app/your-app.jar 
ADD scripts/init.sh /opt/your_app/init.sh 

USER userapp 
EXPOSE 8081 

CMD ["/bin/bash", "/opt/your_app/init.sh"] 

I nostri contenitori, presso l'azienda per cui lavoro, prima di eseguire l'applicazione effettiva nello script init.sh che recuperano il configurazioni da console (invece di fornire un punto di mount e posizionare le configurazioni all'interno dell'host o incorporarle nel contenitore). Così lo script sarà simile:

#!/bin/bash 

echo "Downloading config from consul..." 
confd -onetime -backend consul -node $CONSUL_URL -prefix /cfgs/$CONSUL_APP/$CONSUL_ENV_NAME 
echo "Launching your-app..." 
java -jar /opt/your_app/your-app.jar 

Un consiglio che posso darvi è (a mio davvero breve esperienza di lavoro con i contenitori) trattare i contenitori come se fossero senza stato, una volta che sono accantonati (tutti i comandi si esegue prima del punto di ingresso).

+1

Completamente d'accordo sul considerare i container senza stato. Se ci sono dati da inizializzare, inseriscili in un volume. – BMitch

+2

Mi piacerebbe molto seguire il tuo consiglio, ma non è così facile. Ho pochissima influenza sui cambiamenti dell'app e dovevo essere modificato A LOT per usarlo come descritto. Ad esempio: ogni volta che si avvia un contenitore, lo script di inizializzazione imposta un database per l'app. Questo non dovrebbe accadere quando il container viene riavviato, poiché sovrascrive i dati già presenti ... Sfortunatamente è stato molto difficile insegnare agli sviluppatori della app come utilizzare la finestra mobile. Quindi sto cercando di mantenerlo estremamente semplice per loro. – christian

+0

come si esegue questo? – StarWind0

1

Volevo fare lo stesso su Windows Container. Può essere ottenuto utilizzando l'utilità di pianificazione su Windows. L'equivalente di Linux per l'Utilità di pianificazione è cron. Puoi usarlo nel tuo caso. Per fare questo modificare il dockerfile e aggiungere la seguente riga alla fine

WORKDIR /app 
COPY myTask.ps1 . 
RUN schtasks /Create /TN myTask /SC ONSTART /TR "c:\WINDOWS\system32\WindowsPowerShell\v1.0\powershell.exe C:\app\myTask.ps1" /ru SYSTEM 

Questo crea un compito con il nome MyTask gestisce ONSTART e il compito, di per sé per eseguire uno script PowerShell posto a "c: \ app \ myTask.ps1" .

Questo script myTask.ps1 eseguirà qualsiasi inizializzazione che è necessario eseguire all'avvio del contenitore. Assicurati di cancellare questa attività una volta che è stata eseguita correttamente, altrimenti verrà eseguita ad ogni avvio. Per cancellarlo puoi usare il seguente comando alla fine dello script myTask.ps1.

schtasks /Delete /TN myTask /F 
0

ho dovuto fare questo e ho finito per fare un docker run -d che ha appena creato un contenitore distaccato e ha iniziato bash (sullo sfondo) seguito da un docker exec, che ha fatto l'inizializzazione necessaria. ecco un esempio

docker run -itd --name=myContainer myImage /bin/bash 
docker exec -it myContainer /bin/bash -c /init.sh 

Ora, quando si riavvia il contenitore posso solo fare

docker start myContainer 
docker attach myContainer 

questo potrebbe non essere l'ideale, ma funziona bene per me.

Problemi correlati