web-dev-qa-db-fra.com

Réutiliser le CMD ou le POINT D'ENTRÉE de l'image héritée

Comment puis-je inclure mon propre script Shell CMD au démarrage/redémarrage/attachement du conteneur, sans supprimer le CMD utilisé par une image héritée?

J'utilise ceci, qui exécute bien mon script, mais semble remplacer le PHP CMD:

FROM php

COPY start.sh /usr/local/bin

CMD ["/usr/local/bin/start.sh"]

Que dois-je faire différemment? J'évite la perspective de copier/coller le POINT D'ENTRÉE ou le CMD de l'image parente, et ce n'est peut-être pas une bonne approche.

16
Johnathan Elmore

Comme mentionné dans les commentaires, il n'y a pas de solution intégrée à cela. À partir du Dockerfile, vous ne pouvez pas voir la valeur de CMD ou ENTRYPOINT en cours. Avoir un run-parts la solution est bien si vous contrôlez l'image de base en amont et y incluez ce code, permettant aux composants en aval d'apporter leurs modifications. Mais il y a un problème inhérent à Docker qui causera des problèmes: les conteneurs ne doivent exécuter qu'une seule commande qui doit s'exécuter au premier plan. Donc, si l'image en amont démarre, elle continuera à fonctionner sans donner à vos étapes ultérieures une chance de s'exécuter, vous êtes donc confronté à des difficultés pour déterminer l'ordre d'exécution des commandes afin de vous assurer qu'une seule commande s'exécute finalement sans quitter.

Ma préférence personnelle est une option beaucoup plus simple et codée en dur, pour ajouter ma propre commande ou point d'entrée, et faire la dernière étape de ma commande à exec la commande en amont. Vous devrez toujours identifier manuellement le nom du script à appeler à partir du Dockerfile en amont. Mais maintenant, dans votre start.sh, tu aurais:

#!/bin/sh

# run various pieces of initialization code here
# ...

# kick off the upstream command:
exec /upstream-entrypoint.sh "$@"

En utilisant un appel exec, vous transférez le pid 1 au point d'entrée en amont afin que les signaux soient traités correctement. Et la fin "$@" passe par tous les arguments de la ligne de commande. Vous pouvez utiliser set pour ajuster la valeur de $@ s'il y a des arguments que vous voulez traiter et extraire dans votre propre start.sh script.

20
BMitch

Si l'image de base n'est pas la vôtre, vous devez malheureusement appeler manuellement la commande parent.

Si vous possédez l'image parent, vous pouvez essayer ce que les gens de camptocamp suggèrent ici .

Ils utilisent essentiellement un script générique comme point d'entrée qui appelle run-parts sur un répertoire. Cela permet d'exécuter tous les scripts de ce répertoire dans l'ordre lexicographique. Ainsi, lorsque vous étendez une image, il vous suffit de placer vos nouveaux scripts dans ce même dossier.

Cependant, cela signifie que vous devrez maintenir l'ordre en préfixant vos scripts qui pourraient potentiellement devenir incontrôlables. (Imaginez que l'image parent décide d'ajouter un nouveau script plus tard ...).

Quoi qu'il en soit, cela pourrait fonctionner.

Mise à jour # 1

Il y a une longue discussion sur ce problème de composition de docker sur l'approvisionnement après l'exécution du conteneur. Une suggestion est d'envelopper votre commande docker run ou compose dans un script Shell, puis d'exécuter docker exec sur vos autres commandes.

Si vous souhaitez utiliser cette approche, vous conservez essentiellement le CMD parent en tant que commande d'exécution et vous placez le vôtre en tant qu'exécutable de docker après votre exécution de docker.

4
Morgan Kobeissi