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?
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 "
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.
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.
Dockerfile
FROM <some base>
CMD tail -f /dev/null
Exécutez avec l'habituel docker run -d ....
(J'ai utilisé docker-compose
)
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.
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