web-dev-qa-db-fra.com

Docker ENTRYPOINT avec variable ENV et arguments facultatifs

J'ai un Dockerfile avec un ENTRYPOINT qui utilise une variable ENV. Je ne peux pas obtenir la structure ENTRYPOINT afin que le conteneur puisse également accepter des arguments de ligne de commande supplémentaires. Voici la partie pertinente du Dockerfile:

ARG MODULE_NAME
ENV MODULE_NAME=$MODULE_NAME
ENTRYPOINT /usr/bin/python3 -m ${MODULE_NAME}

Cela fonctionne bien si je veux simplement lancer le conteneur sans arguments supplémentaires:

docker run my-image

Mais je dois pouvoir passer des arguments de ligne de commande supplémentaires (par exemple, un indicateur "--debug") au processus python comme ceci:

docker run my-image --debug

Avec la forme de ENTRYPOINT ci-dessus, l'argument "--debug" n'est pas transmis au processus python. J'ai essayé à la fois la forme exécutive et la forme Shell de ENTRYPOINT mais je ne peux pas obtenir pour qu'il fonctionne à la fois avec la variable ENV et argument de ligne de commande. Quelques autres formes que j'ai essayées:

Cela s'exécute mais n'accepte pas d'arguments supplémentaires:

ENTRYPOINT ["/bin/bash", "-c", "/usr/bin/python3 -m ${MODULE_NAME}"]

Cela donne "/ usr/bin/python3: Aucun module nommé $ {MODULE_NAME}":

ENTRYPOINT ["/usr/bin/python3", "-m ${MODULE_NAME}"]

Cela donne "/ usr/bin/python3: Aucun module nommé $ {MODULE_NAME}":

ENTRYPOINT ["/usr/bin/python3", "-m", "${MODULE_NAME}"]
8
bogatron

Il semble qu'il ne soit pas possible de créer un ENTRYPOINT qui prend directement en charge l'expansion des variables et arguments de ligne de commande supplémentaires. Bien que la forme Shell de ENTRYPOINT développe les variables ENV au moment de l'exécution, elle n'accepte pas les arguments supplémentaires (ajoutés) de docker run commande. Bien que la forme exécutable de ENTRYPOINT prenne en charge des arguments de ligne de commande supplémentaires, elle ne crée pas d'environnement Shell par défaut, les variables ENV ne sont donc pas développées.

Pour contourner ce problème, bash peut être appelé explicitement dans le formulaire exec pour exécuter un script qui développe ensuite les variables ENV et transmet les arguments de ligne de commande au processus python. Voici un exemple Dockerfile qui fait cela:

FROM ubuntu:16.04
ARG MODULE_NAME=foo
ENV MODULE_NAME=${MODULE_NAME}

RUN apt-get update -y && apt-get install -y python3.5

# Create the module to be run
RUN echo "import sys; print('Args are', sys.argv)" > /foo.py

# Create a script to pass command line args to python
RUN echo "/usr/bin/python3.5 -m $MODULE_NAME \$@" > /run_module.sh

ENTRYPOINT ["/bin/bash", "/run_module.sh"]

Sortie de l'image docker:

$ docker run my-image
Args are ['/foo.py']

$ docker run my-image a b c
Args are ['/foo.py', 'a', 'b', 'c']

Notez que l'expansion des variables se produit pendant les commandes RUN (car elles utilisent le formulaire Shell), donc le contenu de run_script.py dans l'image est:

/usr/bin/python3.5 -m foo $@

Si la commande finale RUN est remplacée par ceci:

    RUN echo "/usr/bin/python3.5 -m \$MODULE_NAME \$@" > /run_module.sh

alors le run_script.sh contiendrait

/usr/bin/python3.5 -m $MODULE_NAME $@

Mais la sortie du conteneur en cours d'exécution serait la même puisque l'expansion des variables se produira au moment de l'exécution. Un avantage potentiel de la deuxième version est que l'on pourrait remplacer le module à exécuter au moment de l'exécution sans remplacer le POINT D'ENTRÉE.

9
bogatron