Come avviare automaticamente un servizio quando si esegue un contenitore finestra mobile?


157

Ho un Dockerfile per installare il server MySQL in un contenitore, che quindi inizio in questo modo:

sudo docker run -t -i 09d18b9a12be /bin/bash

Ma il servizio MySQL non si avvia automaticamente, devo eseguirlo manualmente (dall'interno del contenitore):

service mysql start

Come posso avviare automaticamente il servizio MySQL quando eseguo il contenitore docker?


1
no, per un semplice servizio, il supervisore non è necessario, rende complicato per l'utente iniziale
— Larry Cai

8
potresti voler copiare il file docker qui invece di collegarti a un file che non esiste più
— neo112,

L'articolo docker su supervisord è ora qui: docs.docker.com/config/containers/multi-service_container Ho usato il comando && tail per far funzionare il mio servizio - ma dovevo aggiungere "--cap-add SYS_PTRACE" alla docker esegui comando.
— Ted Cahall,

Risposte:


205

Innanzitutto, c'è un problema nel tuo Dockerfile:

RUN service mysql restart && /tmp/setup.sh

Le immagini Docker non salvano i processi in esecuzione. Pertanto, il RUNcomando viene eseguito solo durante la docker buildfase e si interrompe al termine della compilazione. Invece, è necessario specificare il comando all'avvio del contenitore usando i comandi CMDo ENTRYPOINTcome di seguito:

CMD mysql start

In secondo luogo, il contenitore docker necessita di un processo (ultimo comando) per continuare a funzionare, altrimenti il ​​contenitore verrà chiuso / arrestato. Pertanto, il normaleservice mysql start comando non può essere utilizzato direttamente nel Dockerfile.

Soluzione

Esistono tre modi tipici per mantenere il processo in esecuzione:

  • Usando il servicecomando e aggiungi il comando non-end dopo tale liketail -F

    CMD service mysql start && tail -F /var/log/mysql/error.log
    

Questo è spesso preferito quando si dispone di un singolo servizio in esecuzione in quanto rende il registro in uscita accessibile alla finestra mobile.

  • Oppure usa il comando foreground per farlo

    CMD /usr/bin/mysqld_safe
    

Funziona solo se esiste uno script simile mysqld_safe.

  • O avvolgi i tuoi script start.she mettili alla fine

    CMD /start.sh
    

Questo è meglio se il comando deve eseguire una serie di passaggi, di nuovo, /start.sh dovrebbe rimanere in esecuzione.

Nota

Per i principianti che usano supervisord non è raccomandato. Onestamente, è eccessivo. È molto meglio usare il singolo servizio / comando singolo per il contenitore.

A proposito: consultare https://registry.hub.docker.com per le immagini docker mysql esistenti come riferimento


Come riavvieresti il ​​servizio una volta avviato nel contenitore della finestra mobile?
— K - La tossicità in SO sta crescendo.

3
@KarlMorrisondocker exec -it <CONTAINER NAME> mysql /etc/init.d/mysqld restart
— kaiser

1
Non consiglierei di personalizzare il registro degli errori di MySQL per determinare se il database è in esecuzione o meno. Nella maggior parte delle configurazioni mysqld, il server si riprenderà da errori soe e nel processo in tal modo il registro degli errori verrà chiuso e quindi riaperto. Non sono sicuro che la tua coda -F funzionerà per te in tutti o anche in alcuni casi.
— Brian Aker,

Non sono sicuro del perché, ma la prima opzione di soluzione funziona bene per lo script di servizio. Quando non si usa tail, fallirà, anche se il servizio è avviato (almeno per il servizio tomcat7). Con la coda funziona. Per entrambi i casi devi usare switch cap_add (- cap-aggiungi SYS_PTRACE per l'esecuzione) con almeno SYS_PTRACE
— zhrist,


73

Nel tuo Dockerfile, aggiungi all'ultima riga

ENTRYPOINT service ssh restart && bash

Per me funziona

E questo è il risultato:

root@ubuntu:/home/vagrant/docker/add# docker run -i -t ubuntu
 * Restarting OpenBSD Secure Shell server sshd   [ OK ]                                                                      
root@dccc354e422e:~# service ssh status
 * sshd is running

2
è carino ma penso che non si possa avere un container staccato in questo modo.
— mdob,

1
Questo ha funzionato alla grande per me. Ho avuto problemi con l'avvio automatico di Nginx 1.8. Potresti trovare utile l'aggiunta di: RUN echo "daemon off;" >> /etc/nginx/nginx.conf RUN ln -sf / dev / stdout /var/log/nginx/access.log RUN ln -sf / dev / stderr /var/log/nginx/error.log
— Lionel Morrison

1
Ci sono degli svantaggi in questa soluzione?
— srph

2
L'avvio di Bash alla fine è una cattiva idea quando si desidera interrompere i propri servizi con garbo, perché in questo modo la finestra mobile non può essere fermata docker stopo docker restartaggraziata, solo può essere uccisa.
— Mohammed Noureldin,

Stavo lavorando su packer per creare immagini docker e questo sembra risolvere il mio problema con il conaitner nel file packer. "changes": ["ENTRYPOINT service nginx start && / bin / bash"]
— karthik101

8

Semplice! Aggiungi alla fine del file docker:

ENTRYPOINT service mysql start && /bin/bash

Questa è la migliore risposta che risolve il mio attuale problema Docker Contenitore: Docker version 18.09.7, build 2d0083dsenza && /bin/bashil servizio si fermerà immediatamente
— Lunga

7

C'è un altro modo per farlo che ho sempre trovato più leggibile.

Dì che vuoi avviare rabbitmq e mongodb quando lo esegui, CMDsembreresti qualcosa del genere:

CMD /etc/init.d/rabbitmq-server start && \
    /etc/init.d/mongod start

Dal momento che puoi avere solo uno CMDper Dockerfileil trucco è concatenare tutte le istruzioni &&e quindi utilizzare\ per ogni comando per iniziare una nuova riga.

Se finisci per aggiungere a molti di quelli ti suggerisco di mettere tutti i tuoi comandi in un file di script e avviarlo come suggerito da @ larry-cai:

CMD /start.sh

3

Nel mio caso, ho un'applicazione web PHP fornita da Apache2 all'interno del contenitore docker che si collega a un database back-end MYSQL. La soluzione di Larry Cai ha funzionato con lievi modifiche. Ho creato un entrypoint.shfile all'interno del quale gestisco i miei servizi. Penso che creare un entrypoint.shquando hai più di un comando da eseguire all'avvio del container sia un modo più pulito per la finestra mobile bootstrap.

#!/bin/sh

set -e

echo "Starting the mysql daemon"
service mysql start

echo "navigating to volume /var/www"
cd /var/www
echo "Creating soft link"
ln -s /opt/mysite mysite

a2enmod headers
service apache2 restart

a2ensite mysite.conf
a2dissite 000-default.conf
service apache2 reload

if [ -z "$1" ]
then
    exec "/usr/sbin/apache2 -D -foreground"
else
    exec "$1"
fi

Mettilo accanto al tuo Dockerfile. Quindi nel Dockerfile dovresti avere un'istruzione che copia questo file nella posizione desiderata. Quindi si punta l' ENTRYPOINT ['your location']istruzione al file di script. Ricorda di impostare le autorizzazioni di esecuzione sullo script. COPY entrypoint.sh /entrypoint.sh RUN chmod 755 /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"]. In questo esempio, ho copiato il mio punto di ingresso nella directory principale nel contenitore della finestra mobile.
— Mr. Doomsbuster,

dov'è Dockerfile?
— Viktor Joras,

3

Ho lo stesso problema quando voglio avviare automaticamente il servizio ssh. Ho trovato quell'appendice

/etc/init.d/ssh start
per
~ / .Bashrc
puoi risolverlo, ma solo tu lo apri con bash lo farà.


1

Aggiungo il seguente codice a /root/.bashrc per eseguire il codice una sola volta,

Commettere il contenitore sull'immagine prima di eseguire questo script, altrimenti il ​​file "docker_services" verrà creato nelle immagini e non verrà eseguito alcun servizio.

if [ ! -e /var/run/docker_services ]; then
    echo "Starting services"
    service mysql start
    service ssh start
    service nginx start
    touch /var/run/docker_services
fi

1

Ecco come avvio automaticamente il servizio MySQL ogni volta che viene eseguito il contenitore docker.

Nel mio caso, devo eseguire non solo MySQL ma anche PHP, Nginx e Memcached

Ho le seguenti righe in Dockerfile

RUN echo "daemon off;" >> /etc/nginx/nginx.conf
EXPOSE 80
EXPOSE 3306
CMD service mysql start && service php-fpm start && nginx -g 'daemon off;' && service memcached start && bash

L'aggiunta di && bash manterrebbe Nginx, MySQL, PHP e Memcached in esecuzione all'interno del contenitore.


1

Questo non funziona CMD service mysql start && /bin/bash

Questo non funziona CMD service mysql start ; /bin/bash ;

- Immagino che la modalità interattiva non supporti il ​​primo piano.

Questo funziona !! CMD service nginx start ; while true ; do sleep 100; done;

Questo funziona !! CMD service nginx start && tail -F /var/log/nginx/access.log

attenzione che si dovrebbe usare docker run -p 80:80 nginx_bashsenza parametro di comando.


0

La seguente documentazione dal sito Web Docker mostra come implementare un servizio SSH in un contenitore docker. Dovrebbe essere facilmente adattabile per il tuo servizio:

Una variazione su questa domanda è stata anche posta qui:


Lo strumento nsenter è un altro approccio per entrare in un contenitore, senza richiedere l'installazione del server SSH: github.com/jpetazzo/nsenter . Ma questo approccio richiede un accesso all'host Docker (in genere l'accesso SSH è sufficiente).
— Fabien Balageas,

Il collegamento docs.docker.com/sorry/#/examples/running_ssh_service non funziona. Puoi aggiornarlo per favore?
— Ankur,

0
docker export -o <nameOfContainer>.tar <nameOfContainer>

Potrebbe essere necessario potare il contenitore esistente usando la docker potatura ...

Importa con le modifiche richieste:

cat <nameOfContainer>.tar | docker import -c "ENTRYPOINT service mysql start && /bin/bash" - <nameOfContainer>

Esegui il contenitore ad esempio con l'opzione di riavvio sempre per assicurarti che riprenda automaticamente dopo il riciclo di host / daemon:

docker run -d -t -i --restart always --name <nameOfContainer> <nameOfContainer> /bin/bash

Nota a margine: a mio avviso ragionevole è avviare solo il servizio cron lasciando il contenitore il più pulito possibile, quindi modificare semplicemente crontab o cron.hourly, .daily ecc ... con gli script di controllo / monitoraggio corrispondenti. Il motivo è che fai affidamento solo su un demone e in caso di modifiche è più facile con ansible o burattino ridistribuire gli script cron invece di tenere traccia dei servizi che iniziano all'avvio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.