script run into entrypoint container compose bash shell docker command-line-arguments

into - docker run entrypoint bash



Cómo pasar argumentos a Shell Script a través de Docker Run (7)

Soy nuevo en el mundo de los acopladores. Tengo que invocar un script de shell que toma argumentos de línea de comando a través de un contenedor acoplable. Ej: Mi script de shell se ve así:

#!bin/bash echo $1

Dockerfile se ve así:

FROM ubuntu:14.04 COPY ./file.sh / CMD /bin/bash file.sh

No estoy seguro de cómo pasar los argumentos mientras ejecuto el contenedor


Con Docker, la forma correcta de pasar este tipo de información es a través de variables de entorno.

Entonces, con el mismo Dockerfile, cambie el script a

#!/bin/bash echo $FOO

Después de compilar, use el siguiente comando docker:

docker run -e FOO="hello world!" test


Hay algunas cosas que interactúan aquí:

  1. docker run your_image arg1 arg2 reemplazará el valor de CMD con arg1 arg2 . Eso es un reemplazo completo de la CMD, sin agregarle más valores. Es por eso que a menudo ve que docker run some_image /bin/bash para ejecutar un shell bash en el contenedor.

  2. Cuando tiene definidos un ENTRYPOINT y un valor CMD, Docker inicia el contenedor concatenando los dos y ejecutando ese comando concatenado. Entonces, si define su punto de entrada como file.sh , ahora puede ejecutar el contenedor con args adicionales que se pasarán como args a file.sh

  3. Los puntos de entrada y los comandos en Docker tienen dos sintaxis, una sintaxis de cadena que lanzará un shell y una sintaxis json que ejecutará un exec. El shell es útil para manejar cosas como la redirección de E / S, encadenando múltiples comandos juntos (con cosas como && ), sustitución de variables, etc. Sin embargo, ese shell se interpone en el manejo de la señal (si alguna vez ha visto un retraso de 10 segundos para detener un contenedor, esta suele ser la causa) y con la concatenación de un punto de entrada y comando juntos. Si define su punto de entrada como una cadena, se ejecutará /bin/sh -c "file.sh" , lo cual está bien. Pero si también tiene un comando definido como una cadena, verá algo como /bin/sh -c "file.sh" /bin/sh -c "arg1 arg2" como el comando que se inicia dentro de su contenedor, no así bueno. Consulte la tabla aquí para obtener más información sobre cómo interactúan estas dos opciones.

  4. La opción shell -c solo toma un único argumento. Todo después de eso se pasaría como $1 , $2 , etc., a ese argumento único, pero no a un script de shell incrustado a menos que haya pasado explícitamente los argumentos. Es decir, /bin/sh -c "file.sh $1 $2" "arg1" "arg2" funcionaría, pero /bin/sh -c "file.sh" "arg1" "arg2" no funcionaría ya que se llamaría file.sh sin args.

En conjunto, el diseño común es:

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"]

Y luego ejecutas eso con:

docker run your_image arg1 arg2

Hay bastante más detalles sobre esto en:


Lo que tengo es un archivo de script que realmente ejecuta cosas. Este archivo de script podría ser relativamente complicado. Llamémoslo "run_container". Este script toma argumentos de la línea de comando:

run_container p1 p2 p3

Un simple run_container podría ser:

#!/bin/bash echo "argc = ${#*}" echo "argv = ${*}"

Lo que quiero hacer es, después de "acoplar" esto, me gustaría poder iniciar este contenedor con los parámetros en la línea de comando del acoplador como este:

docker run image_name p1 p2 p3

y que el script run_container se ejecute con p1 p2 p3 como parámetros.

Esta es mi solución:

Dockerfile:

FROM docker.io/ubuntu ADD run_container / ENTRYPOINT ["/bin/bash", "-c", "/run_container /"$@/"", "--"]


Otra opción...

Para que esto funcione

docker run -d --rm $IMG_NAME "bash:command1&&command2&&command3"

en dockerfile

ENTRYPOINT ["/entrypoint.sh"]

en 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


Si quieres ejecutarlo @build time:

CMD /bin/bash /file.sh arg1

si quieres ejecutarlo @ tiempo de ejecución:

ENTRYPOINT ["/bin/bash"] CMD ["/file.sh", "arg1"]

Luego en el host shell

docker build -t test . docker run -i -t test


Use el mismo file.sh

#!bin/bash echo $1

Cree la imagen utilizando el Dockerfile existente:

docker build -t test .

Ejecute la imagen con argumentos abc o xyz u otra cosa.

docker run -ti test /file.sh abc docker run -ti test /file.sh xyz


con este script en file.sh

#!/bin/bash echo Your container args are: "$@"

y este Dockerfile

FROM ubuntu:14.04 COPY ./file.sh / ENTRYPOINT ["/file.sh"] CMD []

deberias ser capaz de:

% docker build -t test . % docker run test hello world Your container args are: hello world