Je suis nouveau dans le monde des dockers. Je dois appeler un script Shell qui prend des arguments de ligne de commande via un conteneur docker. Ex: Mon script Shell ressemble à:
#!bin/bash
echo $1
Dockerfile ressemble à ceci:
FROM ubuntu:14.04
COPY ./file.sh /
CMD /bin/bash file.sh
Je ne suis pas sûr de savoir comment passer les arguments lors de l'exécution du conteneur
Utilisez le même file.sh
#!bin/bash
echo $1
Construisez l'image en utilisant le fichier Dockerfile existant:
docker build -t test .
Exécutez l'image avec les arguments abc
ou xyz
ou quelque chose d'autre.
docker run -ti test /file.sh abc
docker run -ti test /file.sh xyz
avec ce script dans file.sh
#!/bin/bash
echo Your container args are: "$@"
et ceci Dockerfile
FROM ubuntu:14.04
COPY ./file.sh /
ENTRYPOINT ["/file.sh"]
CMD []
tu devrais être capable de:
% docker build -t test .
% docker run test hello world
Your container args are: hello world
Avec Docker, la bonne façon de transmettre ce type d’informations consiste à utiliser des variables d’environnement.
Donc, avec le même fichier Dockerfile, modifiez le script en
#!/bin/bash
echo $FOO
Après la construction, utilisez la commande suivante du menu fixe:
docker run -e FOO="hello world!" test
Il y a quelques choses qui interagissent ici:
docker run your_image arg1 arg2
remplacera la valeur de CMD
par arg1 arg2
. C'est un remplacement complet du CMD, sans lui ajouter de valeurs. C'est pourquoi vous voyez souvent docker run some_image /bin/bash
pour exécuter un shell bash dans le conteneur.
Lorsque vous définissez à la fois une valeur ENTRYPOINT et une valeur CMD, docker démarre le conteneur en concaténant les deux et en exécutant cette commande. Ainsi, si vous définissez votre point d'entrée comme étant file.sh
, vous pouvez maintenant exécuter le conteneur avec des arguments supplémentaires qui seront transmis comme arguments à file.sh
.
Entrypoints et Commands dans docker ont deux syntaxes, une syntaxe de chaîne qui lancera un shell et une syntaxe json qui effectuera un exec. Le shell est utile pour gérer des opérations telles que la redirection IO, la chaînage de plusieurs commandes (avec des éléments tels que &&
), la substitution de variable, etc. vous avez déjà vu un délai de 10 secondes pour arrêter un conteneur (c’est souvent la cause) et concaténer un point d’entrée et une commande ensemble. Si vous définissez votre point d'entrée en tant que chaîne, il exécutera /bin/sh -c "file.sh"
, ce qui seul suffira. Mais si vous avez également une commande définie en tant que chaîne, vous verrez quelque chose comme /bin/sh -c "file.sh" /bin/sh -c "arg1 arg2"
comme étant la commande lancée dans votre conteneur, ce qui n'est pas très bon. Voir le tableau ici pour plus d'informations sur l'interaction de ces deux options
L'option Shell -c
ne prend qu'un seul argument. Après cela, tout ce qui suit serait passé sous la forme $1
, $2
, etc., à cet argument unique, mais pas dans un script Shell intégré, à moins que vous n'ayez explicitement passé l'argument. C'est à dire. /bin/sh -c "file.sh $1 $2" "arg1" "arg2"
fonctionnerait, mais /bin/sh -c "file.sh" "arg1" "arg2"
ne fonctionnerait pas puisque file.sh
serait appelé sans argument.
En résumé, la conception commune est la suivante:
FROM ubuntu:14.04
COPY ./file.sh /
RUN chmod 755 /file.sh
# Note the json syntax on this next line is strict, double quotes, and any syntax
# error will result in a Shell being used to run the line.
ENTRYPOINT ["file.sh"]
Et vous exécutez ensuite cela avec:
docker run your_image arg1 arg2
Il y a un peu plus de détails à ce sujet à:
Ce que j'ai est un fichier de script qui exécute des choses. Ce fichier de script peut être relativement compliqué. Appelons cela "run_container". Ce script prend des arguments depuis la ligne de commande:
run_container p1 p2 p3
Un run_container simple pourrait être:
#!/bin/bash
echo "argc = ${#*}"
echo "argv = ${*}"
Ce que je veux faire, c'est qu'après "docker" ceci, je voudrais pouvoir démarrer ce conteneur avec les paramètres sur la ligne de commande de docker comme ceci:
docker run image_name p1 p2 p3
et que le script run_container soit exécuté avec p1 p2 p3 en tant que paramètres.
Ceci est ma solution:
Dockerfile:
FROM docker.io/ubuntu
ADD run_container /
ENTRYPOINT ["/bin/bash", "-c", "/run_container \"$@\"", "--"]
Si vous voulez l'exécuter @build time:
CMD /bin/bash /file.sh arg1
si vous voulez l'exécuter @ run time:
ENTRYPOINT ["/bin/bash"]
CMD ["/file.sh", "arg1"]
Puis dans le shell hôte
docker build -t test .
docker run -i -t test
Une autre option...
Pour que cela fonctionne
docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"
dans dockerfile
ENTRYPOINT ["/entrypoint.sh"]
dans entrypoint.sh
#!/bin/sh
entrypoint_params=$1
printf "==>[entrypoint.sh] %s\n" "entry_point_param is $entrypoint_params"
PARAM1=$(echo $entrypoint_params | cut -d':' -f1) # output is 1 must be 'bash' it will be tested
PARAM2=$(echo $entrypoint_params | cut -d':' -f2) # the real command separated by &&
printf "==>[entrypoint.sh] %s\n" "PARAM1=$PARAM1"
printf "==>[entrypoint.sh] %s\n" "PARAM2=$PARAM2"
if [ "$PARAM1" = "bash" ];
then
printf "==>[entrypoint.sh] %s\n" "about to running $PARAM2 command"
echo $PARAM2 | tr '&&' '\n' | while read cmd; do
$cmd
done
fi