web-dev-qa-db-fra.com

La bonne façon de garder le conteneur Docker démarré lorsqu'il est utilisé pour des tâches périodiques

J'ai un conteneur Docker avec un logiciel installé et configuré.

Il n'y a aucun programme censé être démarré/exécuté tout le temps.

Ce que je veux - sa capacité à démarrer une commande en fonction des événements externes. comme:

docker exec mysupercont /path/to/mycommand -bla -for

et

docker exec mysupercont /path/to/myothercommand 

Mais "exec" impossible lorsque le conteneur est arrêté, et ce conteneur contient également des données "de travail", qui sont utilisées pour ces commandes, donc je ne peux pas utiliser

docker run ...

à chaque fois, car il recrée le conteneur à partir de l'image et détruit mes données.

Quelle est la "bonne" et la "meilleure" façon de faire fonctionner un tel conteneur? Dans quelle commande je peux commencer à l'intérieur?

43
Korjavin Ivan

Vous n'avez pas besoin d'effectuer chaque fois docker run.

docker run est en fait une séquence de deux commandes: "créer" et "démarrer".

Lorsque vous exécutez le conteneur, vous devez spécifier le "-it ":

-i, --interactive = false Gardez STDIN ouvert même s'il n'est pas attaché
- t, --tty = false Attribuer un pseudo-ATS

Exemple:

docker run -it debian:stable bash

Une fois le travail terminé, la commande spécifiée au démarrage (dans mon exemple bash). Par exemple, vous effectuez la "sortie". Le conteneur s'arrête:

CONTAINER ID        IMAGE                      COMMAND                CREATED             STATUS                     PORTS               NAMES
1329c99a831b        debian:stable              "bash"                 51 seconds ago      Exited (0) 1 seconds ago                       goofy_bardeen

Vous pouvez maintenant recommencer

docker start 1329c99a831b

Le conteneur est démarré et exécute à nouveau la commande "bash".
Connectez-vous à cette session "bash" avec la commande

docker attach 1329c99a831b

Pour résumer : vous devez comprendre la différence entre le conteneur run et start.
En outre, consultez la documentation pour le rôle des paramètres "-i t" et "-d "pour le" Run "

49
MSemochkin

Toute cette affaire de savoir si vous pouvez ou non démarrer un conteneur arrêté, dépend de la façon dont le conteneur a été créé à l'origine, c'est-à-dire exécuté. Si vous avez exécuté une commande qui s'est terminée ou si vous quittez une commande interactive, par exemple bash, vous ne pouvez pas démarrer, redémarrer ou exécuter le conteneur arrêté. Tout ce que vous pouvez faire est de le supprimer. C'est de la camelote.

Mais le dernier commentaire de taranaki, utilisez '-itd', semble être ce que le docker a ordonné.

Le conteneur continue de fonctionner et vous pouvez exécuter ce que vous voulez, et vous pouvez arrêter, démarrer ou redémarrer le conteneur. Bien sûr, ce n'est qu'une découverte préliminaire basée sur l'image alpine. Notez que si vous vous attachez au conteneur, il s'arrêtera lorsque vous quitterez, mais vous pouvez le redémarrer.

7
Sue Parker

Puisque vous avez mentionné des tâches périodiques et que vous utilisez probablement quelque chose comme cron en raison de la façon dont vous souhaitez utiliser docker exec, J'ai juste le médicament pour vous. Au moins, j'ai fini par faire quelque chose comme ça.

  1. Dockerfile

    FROM <some base>
    CMD tail -f /dev/null
    
  2. Exécutez avec l'habituel docker run -d .... (J'ai utilisé docker-compose)

  3. Configurez les machines hôtes crontab, par exemple:

    * * * * * docker exec mysupercont foo >> /var/log/foo.log 2>&1
    * * * * * docker exec mysupercont bar >> /var/log/bar.log 2>&1
    

Je trouve cette solution agréable car nous pouvons compter sur l'ancien et prouvé crontab dans un environnement Linux assez par défaut, tandis que Docker gère les deps et les variables d'environnement les plus exotiques de votre logique métier. Vous pouvez également définir certaines limites si vos tâches périodiques sont bloquées et ont des fuites de mémoire ou autre.

6
elnygren

Tail provoquera toujours des opérations sur les fichiers de temps en temps.

Voici ma solution pour dormir pour toujours, sans aucun effet secondaire.

# Ah, ha, ha, ha, stayin' alive...
while true; do :; done & kill -STOP $! && wait $!

Comment ça marche

while true; do :; done & # do nothing(:) in background, in an endless loop
kill -STOP $!            # stop the background process of doing nothing
wait $!                  # wait forever, because doing nothing process is stopped
0
qoomon