4
votes

Utiliser la sortie de la console dans Dockerfile

Je veux utiliser une sortie de console comme nom de mon image de base du docker.

Plus précisément, j'ai une chaîne de fichiers de construction de docker dépendants, donc j'essaie d'automatiser ce processus. Ainsi, par exemple, le Dockerfile d'une image dérivée1 dépend de l'image de base base_image_name dans le scénario suivant:

BASE=base_image_name
Sending build context to Docker daemon   5.12kB
Step 1/3 : FROM company:$BASE
invalid reference format

Lorsque l'image de base se construit, elle récupère son nom dans son dossier actuel en utilisant $ {PWD ## * /} . Dans ce cas, le dossier de l'image de base s'appelle base_image_name , et donc l'image de base s'appelle company: base_image_name .

Ensuite, lorsque les images dérivées se construisent, elles devraient simplement être capables de comprendre le nom de l'image de base en remontant un répertoire et en regardant le nom de ce répertoire. Ainsi, par exemple, lors de la construction de l'image company: derived1 , elle doit rechercher un répertoire, voir qu'il s'appelle base_image_name , et à partir de là déduire qu'il doit utiliser le image de base company:base_image_name.

Je voudrais avoir cette structure plusieurs couches profondes, donc je veux l'automatiser. Pour ce faire, j'ai essayé plusieurs permutations de la syntaxe

FROM company:$BASE

mais je n'arrive pas à faire les choses correctement. Pour comprendre ce que fait la commande $ (cd $ PWD /../; echo $ {PWD ## * /}) , tapez-la simplement dans votre terminal.

build.sh:

BASE=$(cd $PWD/../../; echo ${PWD##*/})
echo "BASE="$BASE
docker build --build-arg BASE=${BASE} -t company:"${PWD##*/}" . 

renvoie simplement le nom du répertoire d'un niveau supérieur. Cependant, lorsque j'essaye d'utiliser ceci dans un Dockerfile, j'obtiens l'erreur

Error response from daemon: Dockerfile parse error line 1: FROM requires either one or three arguments

Quelqu'un pourrait-il me fournir la syntaxe correcte?

EDIT:

J'ai également essayé de construire les images dérivées avec un build-arg , mais cela ne semble pas non plus fonctionner:

echo $(cd $PWD/../;  echo ${PWD##*/})

à quoi ressemble le Dockerfile

FROM company:$(cd $PWD/../;  echo ${PWD##*/})

Plus précisément, cela génère l'erreur de construction:

base_image_name/ 
    Dockerfile
    derived1/
        Dockerfile
    derived2/
        Dockerfile

Il semble donc que docker n'interprète pas correctement cet argument de construction.


2 commentaires

Votre complexité vient du fait que vous essayez d'utiliser un fichier docker pour la création et le déploiement. Créez vos images séparément à l'aide de scripts simples, puis utilisez votre fichier de composition uniquement pour définir la façon dont vos services sont déployés.


@Alkaline Qui a déjà dit quoi que ce soit à propos de Compose ou de déploiement?


3 Réponses :


1
votes

Vous essayez d'utiliser la substitution de commande bash dans quelque chose qui n'est pas consommé par bash.

La [Référence Dockerfile [( https://docs.docker.com/engine/) reference / builder / ) indique que la substitution de variable d'environnement est prise en charge par l'instruction FROM .

Vous devrez à la place simplement utiliser une variable d'environnement dans FROM que vous calculez en dehors du Dockerfile et passez à docker build .


1 commentaires

Oh. C'est dommage



3
votes

Les fichiers Dockerfiles ne prennent pas en charge la syntaxe du shell en général, à l'exception de certains très expansion limitée des variables d'environnement .

Ils prennent en charge les ARG qui peuvent être transmis à partir de la ligne de commande, et un ARG peut être utilisé pour définir l'image FROM . Vous pouvez donc démarrer votre Dockerfile avec

docker build --build-arg tag=$(cd $PWD/../;  echo ${PWD##*/}) .

puis créer l'image avec

ARG tag
FROM company:${tag:-latest}

(ce qui est suffisamment impliqué pour peut vouloir l'écrire dans un script shell).

À un niveau très bas, il convient également de se rappeler que docker build fonctionne en créant un fichier tar du répertoire courant, en envoyant via une connexion HTTP au démon Docker et exécutez la compilation là-bas. Une fois ce processus terminé, toute notion du nom du répertoire hôte est perdue. En d'autres termes, même si la syntaxe fonctionnait, docker build n'a pas non plus la capacité de savoir dans quel répertoire hôte se trouve le Dockerfile.


1 commentaires

Oops. J'ai posté ma réponse à quelques secondes de la vôtre



2
votes

Aha. Je l'ai trouvé.

Comme le souligne Jonathon, il semble que vous ne puissiez pas facilement extraire des éléments de votre environnement dans le système de construction. Il semble que vous deviez utiliser les build-arg s Docker.

La solution était d'évaluer la variable dans le terminal et de la passer en tant que build-arg:

ARG BASE
FROM company:$BASE

Puis à l'intérieur le Dockerfile de l'image dérivée:

build.sh:

BASE=$(cd $PWD/../; echo ${PWD##*/})
echo "BASE="$BASE
docker build --build-arg BASE=${BASE} -t company:"${PWD##*/}" . 


0 commentaires