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.
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.
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.
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.