Moby: Autoriser la spécification d'un fichier docker en tant que chemin, pas d'insertion.

Créé le 8 oct. 2013  ·  160Commentaires  ·  Source: moby/moby

Ce serait bien de pouvoir spécifier docker build -t my/thing -f my-dockerfile . pour que je puisse AJOUTER des fichiers et avoir plusieurs fichiers docker.

Commentaire le plus utile

Alors c'est docker build -f Dockerfile.dev . ? éditer : ouais

Tous les 160 commentaires

je cherchais juste ça

Utilisation : docker build [OPTIONS] CHEMIN | URL | -

donc si tu cours

docker build -t ma/chose mon-fichier docker

se plaint que le fichier tar est trop court.

Il me semble que l'option 'PATH' n'est pas documentée, elle pourrait donc avoir une signification héritée?

Donc - je me demande si détecter si PATH est un fichier et n'est pas un fichier Tar.

personnellement, j'ai un ensemble de Dockerfiles que j'utilise pour tester, et je préférerais de loin les avoir tous dans un seul répertoire et avoir également un contexte complet.

Ce PATH fait référence à un répertoire, pas à un Dockerfile spécifique.

oh, et puis goudrons ce répertoire pour l'envoyer au serveur - cool !

il est donc possible de détecter un fichier isa, de remonter le répertoire, puis de remplacer le fichier Dockerfile de cette archive par le fichier spécifié.

ou pour utiliser -f de la même manière - permettant à vos définitions Dockerfile de vivre séparément de la charge utile

maintenant pour comprendre comment fonctionnent les tests, essayez-le et voyez si cela fonctionne pour moi

Il ne goudronne rien - le PATH est un répertoire dans lequel il suppose qu'il y a un Dockerfile

ce n'est pas tout ce qu'il fait avec ce PATH - en lisant le code, le "contexte" est envoyé au serveur en tarant le répertoire.

(ok, donc je ne sais toujours pas y aller, et je ne lis le code que depuis quelques minutes, alors prenez-le avec un grain de scepticisme)

Correct, donc tous les fichiers non distants référencés via ADD doivent également se trouver dans ce même répertoire ou le démon ne pourra pas y accéder.

Ah, je vois ce que vous dites - oui - c'est exactement ce que je veux - un moyen de spécifier un fichier docker avec -f, puis le répertoire PATH qui pourrait être séparé.

donc je pourrais avoir :

docker build -t my/thing fooproj
docker build -t my/thing -f debug-dockerfile fooproj

2108 (ajout d'une directive d'inclusion à Dockerfiles) ajoute une ride intéressante

si l'include est relative au fichier docker spécifié, ou au PATH. pas encore important cependant.

amusant:

docker build -t my/thing fooproj
docker build -t my/thing -f ../../debug-dockerfile fooproj
docker build -t my/thing -f /opt/someproject/dockerfiles/debug-dockerfile fooproj

comme bonus supplémentaire - il n'y a pas encore de tests CmdBuild, alors devinez ce que j'apprends en premier :)

@SvenDowideit travaillez-vous là-dessus ? Je pensais peut-être à le pirater aujourd'hui

Je me familiarise lentement avec le code et c'est parti, alors allez-y - je m'amuse trop à écrire les tests unitaires (vous pouvez peut-être utiliser les commits de test pour vous aider :)

Je ferai :)

J'aimerais aussi voir cette fonctionnalité. Nous avons un système qui peut fonctionner dans 3 modes différents et nous aimerions déployer 3 conteneurs différents -- 1 pour chaque mode. Cela signifie 3 fichiers docker pratiquement identiques, seul le CMD étant différent. Mais comme les chemins ne sont que des répertoires et que les répertoires sont le contexte des commandes ADD, je ne peux pas faire fonctionner cela pour le moment.

Donc : +1 de ma part !

On dirait que cela peut avoir le même objectif final que #1618 (bien qu'avec des approches différentes). L'idée est d'utiliser un seul Dockerfile avec plusieurs instructions TAG qui donnent plusieurs images, plutôt que plusieurs Dockerfiles et un système d'inclusion comme indiqué ici. Les pensées?

Il semble que si vous pouvez diriger un fichier Docker, vous devriez également pouvoir spécifier un chemin. Intéressé de voir ce qui vient de #1618 mais je pense que cela offre beaucoup plus de possibilités.

J'ai été surpris par le fait que la documentation n'indique pas clairement que le répertoire contenant le Dockerfile est le contexte de construction - j'ai fait la fausse hypothèse que le contexte de construction était le répertoire de travail actuel, donc si je passais un chemin vers le Docerfile à la place qu'il se trouve dans le répertoire actuel, les fichiers que j'ai essayé d'AJOUTER à partir du répertoire de travail actuel ont été bombardés avec des erreurs "aucun fichier ou répertoire de ce type".

J'obtiens la même erreur, toutes les idées

docker construire Dockerfile


Contexte de téléchargement

2013/12/11 21:52:32 Erreur : Erreur de build : Tarball trop court

@bscott essaye docker build . . Build prend un répertoire, pas un fichier, et c'est le "contexte de construction". :)

A travaillé Thx !, je voudrais juste choisir entre différents fichiers Docker.

+1 de moi.

J'ai besoin de créer plusieurs images à partir de ma source. Chaque image est une préoccupation distincte qui a besoin du même contexte pour être construite. Polluer un seul Dockerfile (comme suggéré dans #1618) est bancal. Ce serait beaucoup plus propre pour moi de garder 3 fichiers <image-name>.docker séparés dans ma source.

J'aimerais voir quelque chose comme ça mis en œuvre.

C'est plus difficile à mettre en œuvre qu'il n'y paraît au premier abord. Il semble que ./Dockerfile soit assez cuit. Après une enquête initiale, au moins ces fichiers sont impliqués :

api/client.go
archive/archive.go
buildfile.go
server.go

Le client utilise archive pour tar build context et l'envoie au server qui utilise ensuite archive pour détarer build context et remettez les octets à buildfile .

L'implémentation la plus simple semble consister à modifier client et archive pour écraser le ./Dockerfile du tar avec le fichier spécifié via cette option. Je vais enquêter plus loin.

@thedeeno, je vais jeter un coup d'œil très rapidement et vous montrer où le changement doit être effectué. Je pense que ce n'est qu'à un seul endroit.

+1 de moi !

J'ai suivi à la fois #1618 et #2112 et c'est la solution la plus élégante.

Il y a un cas d'utilisation particulier dans mon développement où cette fonctionnalité serait incroyablement pratique... Lorsque vous travaillez sur des applications qui ont à la fois des rôles "web" et "worker". Je voudrais créer deux fichiers docker pour cette situation "Dockerfile-web" et "Dockerfile-worker". Je pourrais ensuite les créer tous les deux, les marquer et les envoyer dans mon référentiel d'images. J'exécuterais ensuite plusieurs instances Web frontales derrière un équilibreur de charge et plusieurs travailleurs pour gérer les tâches poussées dans les files d'attente.

+1 comme alternative au #2745.

+1

J'ai été étonné de constater que Dockerfile est codé en dur, ainsi que que le contexte de construction est forcé d'être le répertoire du Dockerfile et ne peut pas être remplacé même avec des indicateurs de ligne de commande. Cela limite considérablement l'utilité et la flexibilité de Docker en tant qu'outil de développement, de test et de déploiement.

+1
j'apprécierais ce changement

+1
Vraiment besoin de ça.

5033 devrait autoriser cette fonctionnalité. cc/@crosbymichael

@shykes que pensez-vous de ce changement ? Je ne pense pas que vous soyez d'accord ou que vous connaissiez peut-être une meilleure solution pour résoudre le même problème.

J'hésite.

D'une part, je ne veux pas limiter la capacité des gens à personnaliser leur build.

D'un autre côté, je crains que la même chose ne se produise qu'avec _run -v /host:/container_ et _expose 80:80_. En d'autres termes, cela permettra aux 1% qui savent ce qu'ils font d'ajouter une personnalisation sympa - et les 99% restants se tirent alors une balle dans le pied assez mal.

Par exemple, nous avons beaucoup de nouveaux utilisateurs de Docker qui commencent avec des volumes montés sur l'hôte au lieu de volumes normaux. Et nous avons dû déprécier complètement la syntaxe _expose 80:80_ car trop de personnes ont publié des images qui ne pouvaient pas être exécutées plus d'une fois par hôte, sans raison valable.

Ma question est donc la suivante : ne risquons-nous pas d'avoir beaucoup de référentiels sources qui ne peuvent pas être construits de manière répétée avec _docker build

_, parce que maintenant vous devez lire un README qui vous dit d'exécuter un script shell qui exécute ensuite 'docker build -f ./path/to/my/dockerfile', simplement parce que vous n'aviez pas envie de mettre un Dockerfile à la racine du dépôt ? Ou peut-être parce que vous êtes un utilisateur débutant et que vous venez de copier-coller cette technique à partir d'un didacticiel non officiel ?

Pouvoir supprimer un référentiel source et le faire construire automatiquement sans ambiguïté ni découverte humaine est l'une des raisons pour lesquelles les Dockerfiles sont utiles. Cette pull request n'introduit-elle pas le risque de casser dans autant de cas, sans raison valable ?

@shykes Je rencontre le problème que vous décrivez _à cause_ de cette limitation Dockerfile. Voici quelques cas d'utilisation :

  1. J'ai un environnement de construction basé sur Docker qui produit un artefact (fichier JAR dans ce cas). L'environnement de construction est différent de l'environnement d'exécution (dépendances différentes, image plus grande, etc., donc je ne veux pas hériter de l'environnement de construction dans l'environnement d'exécution. Il est plus logique pour moi d'avoir la construction Dockerfile et exécutez l'environnement d'exécution autour du JAR. J'ai donc un fichier Dockerfile.build séparé qui génère et exécute l'environnement de génération et crée le JAR. Mais, comme je ne peux pas spécifier le fichier Docker, j'ai dû créer un scripts/build fichier qui effectue un docker build < Dockerfile.build puis monte le volume hôte avec docker run -v ... pour exécuter la construction (puisque je ne peux pas utiliser ADD avec des fichiers Docker intégrés). J'aimerais plutôt pouvoir exécuter docker build -t foobar/builder -f Dockerfile.build , docker run foobar/builder , docker build -t foobar/runtime , docker run foobar/runtime et simplement utiliser les commandes ADD dans les deux Dockerfiles.
  2. Avec les instructions ONBUILD, j'aimerais pouvoir mettre Dockerfiles dans des sous-répertoires (ou avoir des fichiers Dockerfile.env, etc. à la racine) qui ont la racine Dockerfile dans leur instruction FROM, mais peuvent toujours utiliser la racine du projet comme leur contexte de construction. Ceci est utile, par exemple, pour importer des paramètres de configuration pour différents environnements. Le Dockerfile racine produirait toujours un conteneur utile, mais les autres créeraient différentes variantes dont nous avons besoin.

Donc, je suppose que ce que j'aimerais vraiment, c'est pouvoir séparer les concepts de "contexte de construction" de "emplacement/nom du fichier Docker". Il existe de nombreuses façons de le faire, bien sûr, mais cela me semble relativement simple.

@cap10morgan avez-vous une chance de m'indiquer votre exemple 1, ou quelque chose qui s'en rapproche? Je peux donc jouer et m'assurer que nous parlons de la même chose.

@shykes https://github.com/shykes n'est-ce pas exactement ce rêve de portabilité
qu'est-ce que l'index d'image est pour? Pourquoi les environnements de construction doivent-ils être
portable aussi ?

Certains processus de construction nécessitent plus que ce qui est possible avec vanilla
Dockerfile. De plus, l'application d'un Dockerfile par contexte (ce qui est
cette requête vise à corriger) est très limitatif.

Cela affecte vraiment notre équipe. Dans notre configuration, nous aimerions produire plusieurs
images du même "contexte". En ajoutant l'option --file nous pouvons faire
ce que nous voulons vraiment faire - qui est d'ajouter foo.docker et bar.docker
dans notre racine de référentiel. Au lieu de cela, nous finissons par écrire des scripts bash à copier
des tonnes de fichiers dans des emplacements temporaires pour établir un contexte et renommer notre
fichiers docker nommés dans la magie Dockerfile juste pour que docker build puissent
travail.

Pour moi, ces cerceaux existent sans raison valable. Si quelqu'un de notre équipe veut
pour créer nos images, ils doivent exécuter des scripts personnalisés pour faire le travail -
la chose exacte que vous pensez pouvoir éviter en respectant cette limitation.

Le lundi 7 avril 2014 à 16h23, Solomon Hykes [email protected] a écrit :

@cap10morgan https://github.com/cap10morgan toute chance que vous pourriez pointer
moi à votre exemple 1, ou quelque chose qui s'en rapproche? Alors je peux jouer
autour et assurez-vous que nous parlons de la même chose.

Répondez directement à cet e-mail ou consultez-le sur Gi tHubhttps://github.com/dotcloud/docker/issues/2112#issuecomment -39778691
.

@shykes puisque cela semble être « pas corrigé », pouvez-vous indiquer des documents ou une explication de la manière certifiée Docker de traiter ce problème ?

Mon cas d'utilisation est que j'ai une application que je voudrais créer avec docker où les tests ont des exigences différentes de celles d'une image de production. Je pense que c'est assez courant.

Ceci et le problème .dockerignore (https://github.com/dotcloud/docker/pull/3452) (en copiant l'intégralité de mon répertoire .git dans le contexte de construction) sont les premiers points sensibles que j'ai rencontrés lors de l'essai de docker pour un de nos projets au cours des derniers jours et ne me semblent pas évidents, mais il semble y avoir un recul sur ces questions.

+1 pour avoir également besoin de cela - nous avons une base de code unique avec plusieurs micro-services en cours de développement. Nous aimerions pouvoir générer plusieurs images, par exemple une image contenant services/base/* et services/fooservice/* ; et une autre image contenant services/base/* et services/barservices/* ainsi que staticfiles/*.
Nous ne pouvons pas placer Dockerfiles dans le dossier de service car Docker traite alors ce dossier comme un contexte et nous ne pouvons pas AJOUTER quoi que ce soit de plus haut dans la structure des dossiers. On ne peut pas placer deux Dockerfiles en root car ils auraient le même nom.
La seule solution que nous avons est de placer le Dockerfile dans le dossier de service, puis d'écrire un script personnalisé pour analyser le Dockerfile sélectionné, déterminer les chemins qu'il voudra ajouter (tous spécifiés par rapport à la racine du projet), puis les copier dans un nouveau dossier temporaire, copiez le fichier Docker sélectionné à la racine de ce nouveau dossier et exécutez enfin le "docker build tempfolder". Est-ce vraiment nécessaire?
Cela aurait été tellement plus simple si vous pouviez simplement dire à "docker build" séparément où se trouve le Dockerfile et où se trouve le contexte.

Je rencontre également ce problème. J'adorerais voir une sorte de solution.

+1, le codage autour de cette limitation est une énorme douleur.

+1 pour l'indicateur -f qui spécifie le chemin Dockerfile séparé du contexte de construction

Docker est un si bon outil, mais ce couplage étroit du contexte et du Dockerfile spécifique entache définitivement un peu l'équipe Docker. La structure du répertoire ne reflète pas toujours exactement la structure du « conteneur/sous-système ».

À quel point cela peut-il être difficile à réparer ? Et, il y a eu quelques PR pour cela, mais ils ont été ignorés.

Un ajout simple connexe est d'avoir un fichier ignore pour les choses que nous ne voulons pas ajouter au contexte - oui, je vous regarde, .git ...

Cela pourrait en fait m'amener à ignorer Docker pour le moment et à revenir à Vagrant + Ansible. Joli.

@davber .dockerignore est dans -> #6579

Mais, oui, la gestion des contributions est un peu pénible en ce moment et l'une des rares choses décourageantes à propos de docker jusqu'à présent. Je pense qu'ils sont juste un peu dépassés, espérons-le.

Équipe Docker, comment les gens peuvent-ils faire réviser et intégrer ce genre de choses ? S'il y a une idée claire de pourquoi c'est vraiment mauvais, et comment les projets devraient éviter ce problème, nous aimerions l'entendre, mais cela semble être un problème simple à décrire et un problème simple à résoudre.

/cc @shykes @creack @crosbymichael @vieux

+1 pour l'indicateur -f. Également une variable d'environnement DOCKERFILE pour remplacer les paramètres de construction.

@jakehow oui, il y a certainement un élément d'être submergé, pour chaque responsable, il y a au moins 1 000 personnes qui demandent activement quelque chose et exigent une explication détaillée de la raison pour laquelle cela n'a pas encore été fait. Nous faisons vraiment de notre mieux, et si vous visitez les canaux irc #docker et #docker-dev, vous serez témoin direct du firehose.

Mais dans ce cas, il y a eu une réponse claire quant à la raison pour laquelle il est préférable de conserver le mappage 1-1 de Dockerfile et du répertoire source. Je le répète encore une fois : nous voulons préserver la propriété d'auto-description des builds docker. Le fait que vous puissiez pointer vers un répertoire de code source, _sans aucune autre information hors bande_, et en construire une image exactement selon les spécifications du développeur en amont, est très puissant et un différenciateur clé de Docker.

Bien sûr, pouvoir combiner dynamiquement le répertoire X avec Dockerfile Y à la volée est légèrement pratique (bien que je n'en ai jamais ressenti un besoin urgent et que j'utilise beaucoup Docker). Mais il est beaucoup trop facile de faire quelque chose de stupide - à savoir, de briser la nature auto-descriptive de votre construction. Et cela semble être un compromis extrêmement médiocre. D'où la décision de ne pas implémenter cette fonctionnalité.

En ce qui concerne les exemples "1 source repo, plusieurs images", oui, je suis tout à fait d'accord que cela est nécessaire. Ce dont nous avons besoin, c'est d'un moyen standard Docker pour qu'un seul répertoire source définisse plusieurs cibles de construction. Cela pourrait être fait avec un Dockerfile en plusieurs parties, ou avec plusieurs Dockerfiles _tant qu'il existe une convention de nom de fichier bien définie qui permet à ces Dockerfiles d'être répertoriés et sélectionnés de manière non ambiguë_.

Si quelqu'un veut contribuer à cela, nous aimerions le fusionner. Et comme d'habitude, nous serons heureux d'aider les contributeurs pour la première fois, venez nous saluer sur IRC et nous vous aiderons à démarrer.

@davber J'avais l'impression que Vagrant a la même restriction de 1 fichier de description par projet (vraisemblablement pour des raisons similaires). Comment le retour à Vagrant résoudra-t-il exactement votre problème ?

@gabrtv voulez-vous essayer de ramener plusieurs images ? Voici une proposition provisoire :

$ ls | grep Dockerfile
Dockerfile
db.Dockerfile
frontend-prod.Dockerfile
frontend-dev.Dockerfile
$ docker build -t shykes/myapp .
Successfully built shykes/myapp/db
Successfully built shykes/myapp/frontend-dev
Successfully built shykes/myapp/frontend-prod
Successfully built shykes/myapp
$ docker build -t shykes/myapp2 --only frontend-dev .
Successfully built shykes/myapp2/frontend-dev

Cette proposition fonctionnerait bien pour nous et je peux voir qu'elle résout d'autres problèmes pour d'autres personnes également.

@shykes Je ne pense pas que j'achète que l'augmentation de la complexité du format Dockerfile est un compromis valable pour conserver un seul Dockerfile.

Prenez par exemple les makefiles - il est plus courant qu'autrement pour un projet d'avoir un 'Makefile' mais make vous permet également de spécifier avec '-f' un makefile différent.

Je pense également que le mappage 1:1 entre le dossier source et l'image est moins utile que vous ne le pensez. minimum, et donc des images plus petites.

vous dites "Alors ma question est: ne risquons-nous pas d'avoir beaucoup de référentiels de sources qui ne peuvent pas être construits de manière répétée avec docker build ,"

Mais je pense que c'est déjà le cas, certaines exigences de projets signifient qu'une seule façon de construire n'est pas pratique, et la syntaxe Dockerfile ne permet pas beaucoup de configurabilité (de par sa conception et je ne voudrais pas que cela change ...).

Je n'aime pas particulièrement la suggestion --only. Je pense que la valeur par défaut que les gens /veulent/ lorsqu'ils construisent est qu'un certain contexte soit construit, pas tout - lorsque je lance docker build, je veux que /seulement/ le Dockerfile soit exécuté. Mais je veux aussi avoir la possibilité d'avoir une autre image qui /peut/ être construite.

D'après ce que je comprends, le problème ici réside dans le fait que lorsque
canaliser un Dockerfile (cat Dockerfile | docker build -) nous perdons le travail
répertoire pour ADD et CP.

Résoudra le problème en ajoutant un indicateur pour la construction de docker qui nous permet de
spécifier où réside le contenu du dossier source ?

cat Dockerfile | docker build --cwd=~/my_docker_data_files -

Dans cette proposition, l'indicateur --cwd spécifie le dossier de base pour ADD et CP
commandes.

29/06/2014 19:42 GMT+10:00 Peter Braden [email protected] :

vous dites "Alors ma question est : ne risquons-nous pas d'avoir beaucoup de sources
référentiels qui ne peuvent pas être construits de manière répétée avec docker build , "

Mais je pense que c'est déjà le cas, certaines exigences du projet font que
une seule façon de construire n'est pas pratique, et la syntaxe Dockerfile ne l'est pas
permettre beaucoup de configurabilité (par conception et je ne voudrais pas
que changer...).

Je n'aime pas particulièrement la suggestion --only. je pense que la valeur par défaut
que les gens /veulent/ lorsqu'ils construisent, c'est pour qu'un certain contexte soit construit,
pas tout - quand je lance docker build, je veux /seulement/ le Dockerfile pour
Être exécuté. Mais je veux aussi la possibilité d'avoir une autre image qui /peut/être
construit.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/dotcloud/docker/issues/2112#issuecomment -47449994.

@llonchj en fait https://github.com/dotcloud/docker/pull/5715 résout cela (d'une certaine manière) et cela est déjà fusionné avec master.

@shykes est définitivement ouvert à un autre PR multi-image, bien qu'après avoir regardé #5715, je me demande si ce PR particulier est plus pertinent.

Selon le commentaire original de @peterbraden ...

Ce serait bien de pouvoir spécifier [commande expurgée] afin que je puisse AJOUTER des fichiers et également avoir plusieurs fichiers docker.

Par @cap10morgan...

Donc, je suppose que ce que j'aimerais vraiment, c'est pouvoir séparer les concepts de "contexte de construction" de "emplacement/nom du fichier Docker".

N'est-ce pas exactement ce que fait le #5715 ? Si je comprends bien:

$ cd myapp
$ ls Dockerfile
Dockerfile
$ docker build -t gabrtv/myimage
Successfully built gabrtv/myimage
$ ls subfolder/Dockerfile
Dockerfile
$ tar -C subfolder -c . | docker build -t gabrtv/myotherimage -
Successfully built gabrtv/myotherimage

Je sais que cela ne résout pas les constructions multi-images à partir de la racine du référentiel (ce qui, je suis d'accord, serait bien), mais je me demande si cette PR/implémentation particulière peut être mise au repos maintenant avec #5715 .

@gabrtv Il me semble que #5715 ne correspond pas aux critères de @shykes d'avoir une seule commande qui fonctionnera toujours. tar -C subfolder -c . | docker build -t gabrtv/myotherimage - est, pour moi, extrêmement peu évident.

De plus, cela impose des contraintes gênantes (sinon onéreuses) au développeur en ce qui concerne la mise en page du repo. Pas irréparable, mais "Oh, et je vais devoir réorganiser tout le repo" n'aidera personne à convaincre son patron de passer à Docker.

Personnellement , j'aime assez la suggestion la plus récente de

Selon l'implémentation, on pourrait télécharger le contexte de construction une seule fois pour cela sur toutes les images, ce qui réduirait le coût de construction de plusieurs images. Parce que je n'ai pas de .dockerignore, mon contexte de construction fait plusieurs centaines de mégaoctets et je dois attendre un bon moment pour que mon contexte soit téléchargé, donc ce serait bien.

@rattrayalex croyez-moi, je suis d'accord avec l'objectif "d'avoir une seule commande qui fonctionnera toujours". Il y a de fortes chances que je finisse par écrire le code et soumettre le PR. :clin d'œil:

Mon point de vue est que du point de vue de l'organisation du projet, nous devrions avoir cette discussion ailleurs plutôt que sur un problème interminable intitulé Allow specifying of a dockerfile as a path, not piping in :

  1. La plupart des discussions ici est sans rapport avec @shykes nouvelle proposition https://github.com/dotcloud/docker/issues/2112#issuecomment -47.448.314
  2. Le problème sous-jacent d'origine (séparer le contexte de construction de Dockerfile) est résolu par #5715, mais peut-être pas du goût de tout le monde

Citant @llonchj...

D'après ce que je comprends, le problème ici réside dans le fait que lors de la transmission d'un Dockerfile (cat Dockerfile | docker build -), nous perdons le répertoire de travail pour ADD et CP.

En d'autres termes, si vous étiez d'accord avec docker build -t <image> -f <path-to-dockerfile> , vous pouvez utiliser tar -C <path-to-context> -c . | docker build -t <image> - comme solution de contournement fonctionnellement équivalente jusqu'à ce que nous puissions mettre en place un PR pour la proposition @shykes .

Je suggère que nous fermions ceci et commencions une nouvelle discussion ailleurs (liste de diffusion ? nouveau problème ?).

Merci à tous ceux qui sont intervenus sur ce problème aujourd'hui :

@shykes merci pour le raisonnement. Je pense que notre raisonnement pour vouloir cela (d'autres personnes peuvent intervenir) est dans notre expérience : chaque application nécessite des informations hors bande pour s'exécuter dans un contexte choisi. Toutes nos applications ont plus d'un contexte. La façon dont docker build a été structuré a forcé les développeurs d'applications à déplacer la connaissance de ces informations dans leur structure de référentiel, ou à créer des scripts de build personnalisés remplaçant le comportement de docker build qui contient les informations.

@gabrtv Je pense que presque toutes les discussions ici sont spécifiquement liées à ce problème, et je suis heureux de le voir enfin discuté ici. Le titre du numéro et quelques-uns des articles de « découverte » sont probablement légèrement hors de propos, donc un nouveau numéro ou une nouvelle communication avec un bon départ qui fait référence à celui-ci est probablement bon.

La proposition du commentaire de @shykes me semble être une solution, y a-t-il eu des travaux antérieurs sur ce point quelque part qui peuvent être repris ou consultés à titre de référence ?

"Dockerfile.frontend-prod" ne serait-il pas mieux pour que tous les fichiers Dockerfile
dans un répertoire naturellement trier ensemble?

Désolé, mais c'est juste idiot. Si mon dépôt crée 100 services, je ne veux certainement pas avoir 100 Dockerfiles à la racine. (Exemple : le référentiel dotCloud PAAS.)

Je ne veux pas non plus d'un seul énorme Dockerfile avec 100 sections.

Je veux 100 Dockerfiles, et je les veux dans des répertoires séparés.

(Et non, je ne peux pas simplement créer chaque service dans son propre répertoire, car presque tous les services utiliseront du code et des bibliothèques communs vivant _à l'extérieur_ du répertoire de chaque service.)

Encore une fois, je ne comprends pas pourquoi avoir un indicateur supplémentaire pour spécifier le chemin d'accès au fichier Docker (par défaut à seulement Dockerfile ) est un gros problème ?

De plus, la proposition actuelle ( <imagename>.Dockerfile ) ne correspond pas du tout à la conception actuelle des builds automatisés. Si un dépôt sur l'un de mes systèmes de construction est compromis, l'attaquant pourrait surcharger tous mes dépôts... ?

@jpetazzo comme la plupart des gens raisonnables, traité d' idiot. Veuillez faire un effort pour présenter vos arguments sans insulter l'intelligence de vos pairs. Merci.

_Encore une fois, je ne comprends pas pourquoi avoir un indicateur supplémentaire pour spécifier le chemin d'accès au Dockerfile (par défaut uniquement Dockerfile) est un gros problème ?_

J'ai avancé un argument précis ci-dessus. N'hésitez pas à le lire et à présenter un contre-argument.

Re: encombrement. @gabrtv avait le même souci sur IRC. Après discussion, nous avons trouvé cette alternative :

$ ls Dockerfile Dockerfiles/*
Dockerfile
Dockerfiles/frontend-prod
Dockerfiles/frontend-dev

Même idée, mais moins de fichiers individuels qui traînent dans le dépôt racine.

De plus, la proposition actuelle (.Dockerfile) ne correspond pas du tout à la conception actuelle des builds automatisés. Si un dépôt sur l'un de mes systèmes de construction est compromis, l'attaquant pourrait surcharger tous mes dépôts... ?

Eh bien, comment s'appellent-ils maintenant? Si vous avez un référentiel nommé "abc" avec juste un simple Dockerfile, alors il serait logique que l'image générée par celui-ci soit nommée "abc". Si vous avez un référentiel "xyz" contenant "Dockerfile.abc" et "Dockerfile.zzz", il serait alors logique que vous nommiez les versions à partir de celles-ci comme "xyz-abc" et "xyz-zzz".

Je suis dans une situation similaire à la vôtre (beaucoup de services chacun dans leurs propres sous-dossiers avec des parties communes) et une option explicite pour définir un Dockerfile à utiliser au moment de la construction me faciliterait la réflexion, mais je peux aussi voir comment je peux combiner la proposition "Dockerfile.*" avec le "fichier tar comme contexte" déjà publié pour pouvoir obtenir ce que je veux - les fichiers docker racine pour chaque service généreraient leurs images de construction (avec des compilateurs et autres) et quand ceux-ci sont exécutés, ils généreraient un tar de contexte avec des exécutables déjà compilés et un fichier Docker de production (tiré du dossier de service lui-même) qui décrirait une image avec uniquement les dépendances d'exécution.

En fait, je suis même en train d'écrire ceci avec un seul Dockerfile racine car mon environnement de construction est plus ou moins le même pour tous les services et je peux simplement lui transmettre un paramètre au moment de l'exécution pour lui dire quel tar de contexte de version de service je veux qu'il crée.

@shykes bien, si nous sommes arrivés jusqu'à avoir Dockerfile/* , alors pourquoi ne pas aller plus loin et demander à "docker build" de rechercher simplement les fichiers nommés "Dockerfile.*" dans tous les sous-dossiers du répertoire actuel, de manière récursive, et les exécuter tous dans le contexte du répertoire actuel ? Et pendant que nous en sommes à if, fournissez une option pour simplement en construire un ... comme "-f"? :)

... n'aime pas être traité d'idiot

Je ne savais pas que « idiot » pouvait être considéré comme offensant ; Je voulais simplement dire "maladroit" peut-être, et je m'excuse donc d'avoir mal utilisé le mot.

Je pense que votre argument spécifique était "Je ne veux pas que les gens commencent à mettre des Dockerfiles à des endroits aléatoires et à utiliser systématiquement -f quand ce n'est pas strictement nécessaire". Est-ce correct? Dans ce cas, il est logique de mandater un Dockerfile en haut du référentiel, répertoriant les autres Dockerfiles. Si ce fichier est absent, le constructeur peut refuser de fonctionner (ou émettre un avertissement), et s'il ne répertorie qu'un seul Dockerfile, le constructeur peut également émettre un avertissement. Je ne pense pas que le parallèle avec -v et -p soit approprié ici.

@aigarius si nous faisions cela, il serait moins évident de mapper chaque sous-Dockerfile à une image enfant. L'avantage de ./Dockerfile.* et de ./Dockerfiles/* est qu'ils correspondent à un seul espace de noms que nous pouvons utiliser pour nommer les images résultantes. En revanche, si j'ai ./foo/Dockerfile.db et ./bar/Dockerfile.db , et que j'ai docker build -t shykes/myapp . , lequel s'appelle shykes/myapp/db ?

lequel s'appelle shykes/myapp/db ?

Ni. Dans un tel scénario, vous encoderiez un chemin complet vers le Dockerfile dans le nom, vous auriez donc "shykes/myapp/bar/db" et "shykes/myapp/foo/db". Cela se rapproche inconfortablement de l'espacement de noms Java, mais je laisserai aux autres le soin de décider si c'est bon ou mauvais.

@shykes : en ce qui concerne Vagrant, eh bien moi, et probablement pas mal d'autres, j'utilise Vagrant pour certaines fonctionnalités de chevauchement de Docker. Donc, pour moi, je dois être convaincu que mes versions multi-machines actuelles - ce que je fais dans Vagrant, avec plusieurs définitions de machines - ne deviennent pas plus gênantes lors de l'utilisation de Dockerfiles. Le fait est que le "contexte" est beaucoup plus flexible dans Vagrant, où je peux obtenir le contexte à la volée à partir de n'importe quel endroit par des répertoires partagés, tout comme le langage, donc si je veux juste créer un service (ou une machine) Je peux définir une variable d'environnement et la « vagabonder/fournir ». J'utilise cette méthode quotidiennement pour créer ou mettre en service quelques-uns des services de mon système. Et, si je suis trop irrité par un fichier Vagrant en pleine croissance, je peux facilement « charger » un sous-fichier Vagrant décrivant un service ou un aspect individuel.

Concernant les suggestions concrètes pour gérer plusieurs Dockerfiles, oui, cela nous permettrait de diviser notre logique pour des services individuels. Super. Mais, je veux ou dois souvent créer un service de manière isolée, donc je suis toujours obligé de spécifier un Dockerfile spécifique ...

Donc, mes problèmes ici sont doubles :

  1. Ne pas obtenir un énorme fichier en désordre pour tous les services
  2. Être capable de créer un service spécifique dans ce fichier/cluster de fichiers

Encore une fois, Docker est une idée et un outil de génie, donc JE VEUX que les gens comme moi abandonnent Vagrant pour certains types de fonctionnalités ou de cas d'utilisation.

Désolé si je répète quelque chose traité en détail ci-dessus, mais je ne vois pas en quoi une solution est meilleure que de prendre en charge une option '-f'. C'est-à-dire, des problèmes d'implémentation modulo dus à une dépendance profondément enracinée sur le Dockerfile résidant dans la racine de contexte, je n'y vois aucun inconvénient.

Avec une option '-f', on pourrait certainement structurer les sous-répertoires et les sous-dossiers Docker comme on veut, comme les approches Dockerfiles/ ci-dessus. Oui, il faudrait alors un simple basher à une ligne pour imiter le comportement exact...

Il semble y avoir une tension entre le partage et la flexibilité.

Si le partage est la fonctionnalité la plus importante, alors oui, un fichier docker standard
logique.

Je ne pense pas que le partage soit la caractéristique la plus importante. Le partage est atteint
via des images.

De plus, nous utilisons docker sur des projets qui ne sont explicitement PAS partageables. Dans
dans ces cas, la flexibilité est beaucoup plus précieuse pour nous. On dirait beaucoup dans
le fil tous sont dans cette même position.

L'option -f prévue nous donne la flexibilité dont nous avons besoin. D'un autre côté,
être capable de spécifier un chemin absolu pour le contexte de construction serait également
travail.
Le 3 juillet 2014 à 18h00, "David Bergman" [email protected] a écrit :

Désolé si je répète quelque chose traité à fond ci-dessus, mais je ne vois pas
comment toute solution est meilleure que la prise en charge d'une option '-f'. c'est-à-dire modulo
problèmes de mise en œuvre dus à une dépendance profondément enracinée
Dockerfile résidant dans la racine du contexte, je ne vois aucun inconvénient à
ce.

Avec une option '-f', on pourrait certainement structurer les sous-répertoires
et les sous Dockerfiles comme on veut, comme les Dockerfiles/
approches ci-dessus. Oui, il faudrait alors un simple basher à une ligne pour
imiter le comportement exact...

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/dotcloud/docker/issues/2112#issuecomment -47989616.

Convenu que -f offre le plus de flexibilité avec un minimum de "surprise" (j'ai personnellement supposé qu'il y avait un tel indicateur et je l'ai essayé avant de venir sur ce fil).
L'ajout d'un -c , d'un répertoire ou d'un tar, pour fournir également le contexte semble également être un ajout formidable. Cela supprimerait les cd constants des processus de construction volumineux, par exemple ; dans les entreprises.

De plus, un fichier README qui contient des instructions pour docker build -f foo/bar/Dockerfile -c foo/ ne semble tout simplement pas rebutant pour moi.
Également convenu que docker build pouvait facilement rechercher Dockerfile s. De cette façon, un repo structuré comme tel :

-- README
-- foo/
---- Dockerfile
---- etc
-- bar/
---- Dockerfile
---- etc
---- subbar/
------ Dockerfile
-- context/
---- etc

éviterait tout conflit de nom possible ( repo/bar/subbar ), serait facile à raisonner et devrait avoir du sens dans de nombreux contextes de développement. Cela permettrait une utilisation facile à la fois de docker build , qui créerait de nombreux contextes, et de docker build -f , qui pourrait supprimer les Dockerfile superflus dans la plupart des contextes.

Si -f est un fichier plutôt qu'un répertoire contenant Docker, cela devrait également fonctionner, de sorte qu'un développeur puisse avoir un fichier docker qui n'est pas construit lorsque docker build est exécuté.

Juste pour que cela ne se perde pas, hier, lors d'une discussion IRC avec @shykes, il a eu une autre idée sur l'implémentation de ceci :

  • Il existe un fichier maître Dockerfile à la racine du référentiel qui ne contient que plusieurs lignes dans un nouveau format tel que "INCLUDE foo/bar/Dockerfile AS bar-foo" pour chaque image à générer
  • Chaque sous-projet (comme le module bar du sous-projet foo), qui a besoin d'une image séparée, maintient un Dockerfile régulier dans foo/bar/Dockerfile. Les chemins dans ce Dockerfile (pour ADD et COPY) sont toujours relatifs à la racine de contexte, qui est la racine du référentiel (où réside le Dockerfile principal)
  • Appel régulier à "docker build -t mycorp/myapp ." va construire toutes les images enregistrées dans le Dockerfile racine et leur attribuer des noms tels que "mycorp/myapp/bar-foo" dans cet exemple
  • Une option de ligne de commande supplémentaire pour "docker build" devrait être introduite pour ne construire que certaines des images déclarées, telles que "docker build -t mycorp/myapp --only bar-foo,baz-db"

Juste au cas où les gens recherchent toujours une solution de contournement :

#!/bin/bash
ln -s Dockerfile-dev Dockerfile
docker build -t image/name-dev:latest .
rm Dockerfile

@shykes ping? S'il existe une approbation du développeur de base pour une solution de conception spécifique, il est alors beaucoup plus probable que quelqu'un essaie de l'implémenter et fasse une demande d'extraction.

+1 à la solution -f, Bien que je convienne que chaque repo devrait en théorie déployer son propre service. Certaines personnes n'ont pas le luxe de cette solution. Mon problème particulier est que j'ai un dépôt de chef contenant plusieurs livres de cuisine et que je dois pouvoir créer de nombreux services. Mais je dois pouvoir AJOUTER les répertoires ci-dessus. Donc, garder le contexte à la racine et pointer vers un fichier docker dans un sous-répertoire est optimal.

"-f" ne sera probablement pas implémenté pour les raisons déjà données.

Il est impératif qu'une construction fonctionne exactement de la même manière d'un hôte à l'autre, et avoir des choses qui reposent sur la configuration de l'hôte d'une manière particulière (c'est-à-dire, Dockerfile à un endroit aléatoire et un contexte à un autre endroit) rompt ce contrat.

Je pense que #7115 est probablement la bonne solution pour cela

Il y a aussi #7204 qui conviendrait également à une grande partie du cas d'utilisation pour cela, je pense.

Je n'aime pas les deux solutions proposées impliquant l'ajout de syntaxe au fichier docker. Aucun d'eux ne semble simple. #7115 ne semble toujours pas résoudre le cas d'utilisation où je voulais générer plusieurs types d'images à partir d'un seul référentiel, comme je le fais, par exemple, dans l'un de mes projets pour générer une image "test" et une image « prod ». #7204 semble être une solution trop compliquée qui résout un problème différent. -f permet la _configurabilité_ d'un build, alors que ces deux solutions traitent des _sub_builds_.

J'aimerais vraiment avoir des explications sur "Il est impératif qu'une version fonctionne exactement de la même manière d'un hôte à l'autre". Je ne vois pas pourquoi c'est un principe aussi clé.

En l'état, j'utilise make pour générer l'environnement docker comme solution de contournement à tout ce problème, qui semble déjà violer votre impératif d'exécution d'hôte à hôte.

Pour moi, -f semble être une solution pragmatique, mais si ce n'est pas acceptable, alors peut-être pouvons-nous penser à une solution qui n'implique pas de transformer le fichier docker en une syntaxe de programmation à part entière.

Il est impératif qu'une version fonctionne exactement de la même manière d'un hôte à l'autre

J'aimerais moi aussi en savoir plus sur les raisons pour lesquelles c'est essentiel. Notre équipe est actuellement
forcé de scripter le processus de construction - la chose exacte que vous essayez d'éviter.

Lorsque je télécharge une image à partir d'un registre, cela fonctionne. je n'ai pas besoin de
construit le. N'est-ce pas atteindre la répétabilité d'hôte à hôte ? Pourquoi les constructions
doivent également être reproductibles d'hôte à hôte ?

Le lundi 28 juillet 2014 à 10h43, Peter Braden [email protected]
a écrit:

Je n'aime pas les deux solutions proposées consistant à ajouter de la syntaxe au
fichier docker. Aucun d'eux ne semble simple. #7115
https://github.com/docker/docker/issues/7115 n'en a toujours pas l'air
résoudrait le cas d'utilisation où je voulais générer plusieurs types d'image
à partir d'un seul repo, comme je le fais par exemple dans un de mes projets pour
générer une image 'test' et une image 'prod'. #7204
https://github.com/docker/docker/pull/7204 semble être un
solution trop compliquée qui résout un problème différent -f permet
_configurabilité_ à un build, alors que ces deux solutions adressent
_sous_constructions_.

J'aimerais vraiment avoir des explications sur "Il est impératif qu'un build fonctionne
exactement la même d'un hôte à l'autre". Je ne vois pas pourquoi c'est une telle clé
principe.

En l'état, j'utilise make pour générer l'environnement docker en tant que
solution de contournement à tout ce problème, qui semble déjà enfreindre votre
d'hôte à hôte exécutez le même impératif.

Pour moi, -f semble être une solution pragmatique, mais si ce n'est pas acceptable,
alors peut-être pouvons-nous penser à une solution qui n'implique pas de
dockerfile dans une syntaxe de programmation à part entière.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/docker/docker/issues/2112#issuecomment -50347483.

Pour autant que je sache, l'idée clé est que vous pouvez extraire un dépôt git et si vous y voyez un fichier Docker, vous pouvez exécuter "docker build -t mytag ." dedans et obtenez la version complète attendue. La clé ici est qu'il n'y a pas d'instructions de construction personnalisées que les gens pourraient se tromper ou ne pas connaître.
Ce qui _pourrait_ être un compromis est un moyen de définir plusieurs images Docker dans un seul contexte où, par défaut, elles sont toutes construites avec des sous-étiquettes prédéfinies et vous pourriez alors avoir la possibilité de créer une seule des nombreuses images possibles.
De cette façon, la syntaxe de construction commune est préservée tout en permettant à la fois : 1) de générer un grand nombre d'images différentes à partir d'un même contexte ; 2) choisissez seulement de générer l'un d'entre eux avec une option "avancée".
La syntaxe proposée est décrite dans mon commentaire ci-dessus - https://github.com/docker/docker/issues/2112#issuecomment -48015917

@algarius merci, je pense qu'à ce stade, nous devrions ouvrir une nouvelle proposition de conception pour la syntaxe _INCLUDE_. Pour des exemples de propositions de conception, voir #6802 ou #6805.

Le processus ressemble à ceci :

  • Soumettre une proposition de conception
  • Discuter de la proposition de conception
  • J'approuve la proposition de conception
  • Envoyer PR pour proposition de conception

Soyons honnêtes, les builds ne sont pas vraiment reproductibles maintenant.

Si j'ai RUN apt-get update && apt-get install build-essentials ruby python whatever dans mon Dockerfile, alors je suis déjà à la merci de
tout ce qui est "dernier" dans les dépôts au moment où je construis l'image. Si
VOUS construisez l'image une semaine plus tard, vous pourriez bien obtenir différentes versions de
dépendances à celles que j'ai.

@codeaholics Mais c'est à vous de ne pas rattacher une version et est complètement hors du contrôle de Docker.

Probablement un commentaire juste

@codeaholics, vous avez raison de dire que la répétabilité des versions n'est pas parfaite, bien qu'il existe des options pour la contrôler (comme l'épinglage de version) et nous devrions en fournir plus. Mais au moins, la construction a toujours le même _point d'entrée_, ce qui signifie que nous _pouvons_ introduire une meilleure répétabilité sur la route. Cependant, une fois que votre build dépend d'un outil tiers en amont de Docker lui-même, il n'y a pas de retour en arrière : la répétabilité de votre build est pratiquement nulle, et aucune amélioration future de Docker ne pourra y remédier.

Il ne s'agit pas seulement de répétabilité non plus. Si votre build dépend d'un ensemble particulier d'arguments, non détectable par _docker build_, alors votre outil personnalisé est le seul outil de build au monde qui peut le construire : vous ne pouvez plus bénéficier des divers outils et plugins CI/CD qui supposent un _docker build_ natif et découvrable.

@peterbraden dans #7115, une fois que vous avez ajouté la possibilité de plusieurs appels PUBLISH , vous pouvez désormais produire plusieurs images. Ensuite, vous pouvez ajouter de la configurabilité en permettant de sélectionner les sous-images à créer. La clé est que la configurabilité a lieu _dans l'ensemble de sous-images découvrables par Docker_. De cette façon, vous préservez la découvrabilité.

@shykes > une fois que votre build dépend d'un outil tiers en amont de Docker
lui-même ... la répétabilité de votre build est fondamentalement nulle.

Je suis d'accord. Je pense que la plupart de mes Dockerfiles dépendent d'apt et des référentiels apt
sont en constante évolution. Une construction aujourd'hui n'est pas la même chose qu'une construction
hier. Une image construite est le seul imo de référence.

Si la répétabilité n'est pas la principale raison de la restriction, le plug-in CI
le support semble être une solution de repli assez faible. Les outils de construction sont conçus pour
prendre en charge les cas d'utilisation idiosyncratiques. Un plugin qui ne fait rien de plus que
configurer un docker build cmd semble assez inutile. Mon outil de construction est
déjà un environnement de script. Pire, pelleter tout le potentiel
les cas d'utilisation dans les heures supplémentaires de Dockerfile semblent être un mauvais moyen d'architecte
ce. Le Dockerfile doit rester concentré sur la simple production d'une nouvelle image en
ajouter des calques à une image de base. D'autres travaux semblent hors de portée.

J'adore Docker jusqu'à présent. Super boulot les gars ! Ce problème particulier se produit simplement
être un point douloureux.

Le lundi 28 juillet 2014 à 12h25, Solomon Hykes [email protected]
a écrit:

@peterbraden https://github.com/peterbraden dans #7115
https://github.com/docker/docker/issues/7115 , une fois que vous ajoutez la capacité
pour plusieurs appels PUBLIER, vous pouvez désormais produire plusieurs images. Alors vous
peut ajouter de la configurabilité en permettant de sélectionner les sous-images à créer.
Leur clé est que la configurabilité a lieu _dans l'ensemble de
sous-images découvrables par Docker_. De cette façon, vous préservez la découvrabilité.

-
Répondez directement à cet e-mail ou consultez-le sur GitHub
https://github.com/docker/docker/issues/2112#issuecomment -50361586.

@thedeeno l'objectif du Dockerfile est de spécifier comment transformer un référentiel de code source en quelque chose que Docker peut exécuter.

Que diriez-vous de « l'objectif de _a_ Dockerfile est de spécifier comment transformer un référentiel de code source en quelque chose que Docker peut exécuter ».

Je pense que nous pouvons convenir qu'il existe un réel besoin d'un moyen d'avoir plusieurs mappages repo->image. Dans l'état actuel des choses, beaucoup d'entre nous abusent des scripts shell et des makefiles pour faire cela. D'après mon expérience, je n'ai pas vu beaucoup de Makefiles nommés personnalisés - la configuration et les valeurs par défaut sont une force puissante. Pour cette raison, je ne suis pas convaincu que les gens qui abusent des conventions soient un scénario réaliste.

L'alternative que vous proposez, en ajoutant un mot-clé à la syntaxe Dockerfile, rend la création de Dockerfiles plus complexe. Je suis en faveur de garder cette syntaxe aussi simple que possible. PUBLISH et al, semblent inélégants par rapport au reste de la syntaxe Dockerfile.

Il y a aussi l'idée de suivre les conventions d'outils existantes. Comme cela a été mentionné, -f est un modèle si courant que les gens l'essaient sans même savoir que cela fonctionne. Une interface utilisateur doit être intuitive et les utilisateurs _get_ -f drapeaux. Grokker la nouvelle syntaxe Dockerfile n'est pas aussi intuitive.

@peterbraden @shykes Je suis d'accord pour dire que -f est plus simple et intuitif. J'ai initialement trouvé ce problème parce que je m'attendais à ce que Docker ait déjà cette fonctionnalité et je l'ai recherchée (vraisemblablement quand elle ne fonctionnait pas par défaut) le premier jour où j'ai commencé à la tester pour nos applications.

Ce n'est pas un cas limite, sauf si vous êtes dans une situation où vous ne testez pas votre logiciel ou n'exécutez pas votre logiciel dans plusieurs environnements. Chaque repo que j'ai touché au cours des 10 dernières années doit pouvoir s'exécuter dans différents contextes. Je pense que beaucoup de personnes sur ce fil ont le même problème. Nous sommes tous d'accord (je pense) qu'avoir une convention est évidemment utile pour le contexte par défaut de votre application (en supposant que vous en ayez une).

J'ai lu #7115 (rapidement) et je ne comprends pas comment cela résout ce problème pour nous, c'est peut-être un problème de documentation sur le PR mais s'il est difficile de communiquer, cela provoquera de la frustration et des erreurs IMO, tandis que -f ou un indicateur similaire nécessiterait peu d'efforts pour être expliqué et utilisé correctement.

Création d'une nouvelle proposition avec cette idée INCLUDE - https://github.com/docker/docker/issues/7277

En passant, il vaut peut-être la peine de penser à une commande "APT" plus efficace au lieu de "RUN apt-get install -y ..." (puis par la suite YUM, EMERGE, PACMAN et tout le reste)

Oh et étant donné que beaucoup de gens essaient de toute façon l'option "-f", ce serait mignon si chaque fois que vous essayez de l'utiliser, vous obtenez un joli message d'erreur vous dirigeant vers une page de la documentation décrivant la nouvelle solution.

Je pense vraiment que nous ignorons tous l'éléphant dans la pièce.

@shykes dit des choses comme "Le fait que vous puissiez pointer vers un répertoire de code source, sans aucune autre information hors bande, et en construire une image exactement selon les spécifications du développeur en amont, est très puissant et un différenciateur clé de Docker."

Je suis presque sûr que cela équivaut à dire "taper docker build . dans un répertoire devrait absolument toujours faire la bonne chose", ce qui équivaut à dire "Si vous avez un projet où il n'y a pas de bonne chose évidente pour docker build . à faire, tu te trompes"

Je ne peux pas parler des motivations des autres personnes abonnées à ce numéro, mais mes propres motivations pour ce numéro sont exactement les cas où docker build . n'a pas de comportement évident. Est-ce que je voulais une version de débogage ou une version finale ? Est-ce que je voulais que postgres soit intégré ou devrais-je émettre des images d'application et de postgres séparées ? Est-ce que je voulais qu'il soit chargé avec des données de test ou des données de production ? Est-ce que je voulais faire les tests ?

Bien sûr, j'aimerais vivre dans un monde où les gens n'auraient pas à répondre à ces questions pour obtenir une construction. Mais je ne vis pas dans ce monde. Bien sûr, je pourrais choisir arbitrairement des réponses à ces questions et définir un comportement pour docker build . . Mais le fait est que construire quelque chose d'arbitraire lorsque l'utilisateur tape docker build . ne "fait pas ce qu'il faut".

La réalité de la situation est qu'il y a des projets où il n'y a pas de bonne chose évidente à construire. Il existe de nombreuses façons de résoudre ce problème dans docker, comme la prise en charge de -f , ou en laissant l'utilisateur choisir parmi une liste de cibles importées d'ailleurs, ou diverses autres propositions. Mais ils ont tous la propriété que docker build . casse, par conception. Il y a un décalage d'impédance fondamental ici, vous ne pouvez pas simplement proposer votre solution.

L'idée que chaque projet puisse choisir quelque chose de sensé à faire pour docker build . est un fantasme. Les projets qui ne peuvent pas faire quelque chose de sensé existent, et en nombre. La seule question à ce stade est de savoir si Docker va prendre en charge la nature multi-produits de ces projets directement ou s'ils se rabattront sur des outils de construction traditionnels comme make ou même des scripts shell. C'est ce qui se passe maintenant : par exemple Discourse, l'un des plus grands projets distribués sur Docker, utilise en partie un système de construction maison pour résoudre ce problème.

@drewcrawford vous voyez, c'est exactement le problème. "création docker." devrait construire _l'image. La seule et unique vraie image. Vous êtes censé modifier les paramètres d'exécution du docker pour ajuster le comportement de la seule et unique image à différents environnements.
Dans ce contexte, vous voulez probablement une version finale, juste l'application, rien d'autre. Toutes les autres choses, comme "l'image postgres" sont des choses différentes qui sont liées à votre application au moment de l'exécution. Vous pouvez prendre la même image de version et l'exécuter avec une commande autre que celle par défaut pour y exécuter vos tests.
Idéalement, avec la prise en charge de plusieurs images, vous n'avez même pas à choisir entre les versions "release", "debug" et "with tests" - vous les avez toutes avec une version de base et 3 versions de petite différence en plus.
Si vous essayez de plier Docker à l'ancienne façon de penser, vous allez passer un mauvais moment. N'essayez pas de marteler une vis avec un tournevis.

@algarius Je pense que le problème est que cette réflexion ne s'applique pas aux applications réelles, et personne n'a expliqué comment cela se passe si nous sommes vraiment censés avoir un changement de paradigme ici.

Autoriser plusieurs images est le moyen le plus simple et le plus intuitif de répondre aux exigences de la plupart des applications accessibles en réseau du monde réel (environnements multiples avec différentes dépendances). Est-il souhaitable de compliquer la grammaire d'une manière qui ne peut pas être communiquée afin de résoudre ce problème ? En fin de compte, vous réorganisez et masquez le fait que vous avez > 1 environnement avec différentes dépendances qui pourraient facilement être exprimées de manière simple, comme plusieurs fichiers Docker qui ne nécessitent presque aucune explication aux utilisateurs finaux du logiciel.

@drewcrawford a fourni un exemple concret de la façon dont cela est traité dans une application populaire actuelle du monde réel qui est distribuée avec le support Docker. Comment devraient-ils faire cela?

@aigarius Ce n'est pas que je ne comprends pas "la manière docker". Je pense juste que c'est faux.

Par exemple, les tests peuvent nécessiter une version différente - une _recompile_ honnête envers Dieu - parce que certains codes de journalisation trop lents pour la production doivent être compilés de manière conditionnelle.

Si cela ressemble à un travail pour un système de fabrication, vous avez raison - et c'est en fait ce que font les gens comme moi, ils trouvent des moyens de scripter les builds docker en utilisant des systèmes de build réels.

Le problème ici est qu'un Dockerfile ne peut pas être à la fois l'interface utilisateur préférée pour la construction et aussi sensiblement moins puissant que par exemple make . Il peut s'agir soit de l'interface utilisateur préférée pour la construction, avec une puissance de fabrication, soit d'un outil de bas niveau avec make etc. comme véritable interface utilisateur. Mais les "vrais" systèmes de build ne sont pas arbitrairement compliqués - ils sont compliqués parce que les gens utilisent les fonctionnalités, et aucune quantité de builds docker simplifiés ne va changer cela. Tout ce qui se passera, c'est que docker deviendra le nouveau cc , que les gens invoqueront avec make .

@shykes @drewcrawford @aigarius J'ai rédigé une proposition pour une option -f simple de la même manière que @shykes décrit plus tôt dans ce fil ici : #7284

@drewcrawford vous avez raison, pour être l'interface utilisateur préférée pour la construction, docker build doit être au moins aussi puissant que par exemple. make . Il y a 2 façons de le faire :

  • 1) Nous pourrions essayer de réimplémenter toutes les fonctionnalités de chaque variation de make, ainsi que toutes les alternatives possibles : Maven, scons, rake, et bien sûr les bons vieux scripts shell.

OU

  • 2) Nous pourrions reconnaître que ces outils de construction sont eux-mêmes des programmes exécutables, ce qui signifie qu'ils ont des dépendances d'exécution et ont eux-mêmes été construits à partir de dépendances de construction - et ainsi de suite. Et nous pourrions vous fournir un moyen d'_utiliser réellement_ votre outil de construction préféré. Nous n'aurions donc pas besoin de ré-implémenter make car nous pouvons réellement construire et exécuter make.

Quand vous dites make , à quelle saveur de marque faites-vous référence ? Quelle version ? Construit à partir de quel svn checkout exactement ? Avec quelles options de build ? A quelle libc est-il lié ? Même question pour cc que vous mentionnez également. Peut-être que cela n'a pas d'importance - peut-être que votre application se révélera exactement la même, quelle que soit la version aléatoire de make je finirai par l'utiliser pour construire. Mais encore une fois, peut-être que ça compte. Peut-être que la seule façon pour moi d'obtenir exactement le même build que vous, est d'utiliser exactement le même build de Make et Cc que vous avez utilisé. Et il n'y a pas de moyen facile de le faire aujourd'hui - mais c'est ce que j'aimerais faire.

Je ne pense pas vraiment à docker build comme un outil de construction, exactement - plutôt comme un outil de méta-construction : un point de départ connu à partir duquel vous pouvez reconstituer n'importe quel environnement de construction, de manière fiable. C'est la motivation du #7115.

@shykes Je ne pense pas qu'il soit nécessaire de répliquer vraiment chaque fonctionnalité de make, Maven, rake, etc. Après tout, ces outils ne reproduisent pas toutes les fonctionnalités les unes des autres et, d'une manière ou d'une autre, ils s'entendent.

Cependant, il est nécessaire (si Docker doit être l'interface utilisateur préférée pour créer des images) que le Dockerfile devienne un langage plus expressif qu'il ne l'est actuellement.

La proposition dans ce numéro est vraiment un mouvement plutôt modeste dans ce sens : elle dit "Nous avons besoin d'un équivalent pour faire des _cibles_". La question de "quelle version de make" n'entre pas vraiment dans le tableau - le concept de "cible" est commun à make, Maven, rake et tout autre système de construction sérieux. Ils ont une syntaxe différente, mais le fait que la fonctionnalité elle-même soit universelle devrait être un indice que c'est une chose que les gens font fréquemment lorsqu'ils construisent des choses.

Peu importe si la chose qu'ils construisent est un programme C, une image Docker ou quelque chose entre les deux - vous construisez toujours une cible. L'idée d'une cible de build est si fondamentale qu'elle couvre les implémentations du système de build, elle couvre les langages de programmation, elle couvre les systèmes d'exploitation. Nous ne parlons pas ici de reproduire une obscure fonctionnalité spécifique à GNU Make, nous parlons de quelque chose qui a l'accord le plus large possible.

Vous essayez d'introduire ici un concept d'"outil de méta-construction" mais il n'y a rien de tel. Tout comme docker peut orchestrer des builds make, il peut aussi orchestrer des builds docker, et en fait make est utilisé actuellement de cette manière, car il n'y a aucun moyen de spécifier une cible de build à Docker. Mais de toute façon, aucun système n'est intrinsèquement plus ou moins méta que l'autre, ce ne sont que des systèmes de construction, qui construisent des cibles, mais dans le cas de Docker, vous n'en avez qu'un seul, ce qui est le problème.

Des propositions comme #7115 sont intéressantes, mais à moins que je manque quelque chose, elles ne remplacent pas efficacement les cibles. Une cible vous dit quoi construire. #7115 vous offre un DSL plus flexible qui ne peut toujours construire qu'une seule chose. C'est quelque chose, mais ce n'est pas ce qui est demandé ici.

docker build -t my_project_builder .
# Builds the builder container
docker run my_project_builder my_target | docker build -t my_project/my_target -< Dockerfile_MyTarget
# target is built, tarballed, and sent to stdout, then piped into a new docker build as the context and custom Dockerfile name

@drewcrawford juste pour confirmer, si docker autorisait quelque chose d'équivalent aux cibles Make, afin que vous puissiez 1) spécifier quelle cible construire, par exemple. make clean; make foo , 2) par défaut pour construire _toutes_ les cibles, et 3) avoir un moyen d'énumérer les cibles... Cela vous satisferait ?

Ce serait satisfaisant... Je préférerais utiliser par défaut une cible choisie par le développeur au lieu de toutes les cibles par défaut, mais j'accepterais l'une ou l'autre solution

C'est très bien.

@shykes @drewcrawford :+1:

Tout ce qui se passera, c'est que docker deviendra le nouveau cc, que les gens invoqueront avec make.

La proposition dans ce numéro est vraiment un pas assez modeste dans ce sens : elle dit "Nous avons besoin d'un équivalent pour atteindre nos objectifs". La question de "quelle version de make" n'entre pas vraiment dans le tableau - le concept de "cible" est commun à make, Maven, rake et tout autre système de construction sérieux. Ils ont une syntaxe différente, mais le fait que la fonctionnalité elle-même soit universelle devrait être un indice que c'est une chose que les gens font fréquemment lorsqu'ils construisent des choses.

@drewcrawford :+1: +1 000 000

Voici la situation que je rencontre sans cesse :

Je souhaite créer deux conteneurs Docker à partir de mon référentiel. Peut-être que l'un est le serveur, l'autre la base de données. Ou peut-être que l'un est le serveur et l'autre est un client qui exécute des tests automatisés sur le serveur via des appels API.

Dans tous les cas, il y a des fichiers dans le référentiel que je dois AJOUTER pour ces deux conteneurs. En l'état, il est impossible de le faire sans avoir recours à la copie des fichiers Docker séparés un par un dans un script bash, à la construction, puis au remplacement ou à la suppression du fichier Docker.

J'ai besoin soit :

  1. La commande -f pour spécifier le fichier à utiliser comme fichier Docker.
  2. La possibilité d'AJOUTER un fichier non descendant du Dockerfile.

Comme il a été dit à plusieurs reprises que le numéro un est interdit, et je suppose que le numéro deux est encore plus difficile techniquement, quelle est la "bonne" façon de procéder ?

@ShawnMilo

Le dernier commentaire de qu'auparavant , mais je pense que nous ne savons toujours pas quelle proposition existante serait appropriée ou ce qui devrait changer si aucune ne l'est.

@jakehow Merci pour la mise à jour. Il semble donc qu'une solution officielle au problème soit encore loin. En attendant, y a-t-il une "bonne façon" de le faire ? La meilleure idée que j'ai est un script bash qui copie les fichiers un par un dans "Dockerfile" à la racine du référentiel et crée les images. Cela fonctionnera mais c'est sale.

@ShawnMilo oui, je pense que la plupart des gens utilisent un outil de construction (make, rake, etc.) ou tout simplement un vieux script bash pour ce faire.

Ci-dessus, quelqu'un a montré un extrait où il a une image de constructeur qui traite également de cela.

Voici ma façon de traiter ce problème. Je dois créer une image pour différentes versions d'une plate-forme, disons v2 et v3. J'ai donc un Dockerfile.v2 et un Dockerfile.v3 Quand je veux faire un build, je lance d'abord ln -s ./Dockerfile.v3 ./Dockerfile puis docker build . En fait, j'ai un script et je lance juste ./build v3 ou ./build v2

Bien que j'utilise actuellement un script qui lie un Dockerfile spécifié à ./Dockerfile , ce serait une fonctionnalité intéressante.

J'ai créé un PR #7995 pour essayer de résoudre ce problème. Certaines des solutions qui sont discutées dans ce fil (long :-) ) semblent terriblement pénibles à utiliser pour les gens. L'un des principaux arguments de vente de Docker (pour moi) était sa facilité d'utilisation et donc demander aux gens de sauter à travers ce genre de cerceaux pour ce qui semble être une demande assez facile ne semble pas correct.

Maintenant, il est possible qu'il me manque quelque chose, mais y a-t-il une raison technique pour laquelle il doit être nommé « Dockerfile » ? Lors de la création du PR, je n'en ai pas trouvé et j'ai été agréablement surpris de voir à quel point il était facile de changer.

@duglin vous avez tout mon soutien.

C'est ce que nous faisons pour contourner l'absence d'une option -f dans notre projet actuel.

# build.sh
...
mv specialDockerfile Dockerfile
docker build -t $(PROJECT) .

Considérez cela comme un +1 pour ajouter -f .

Actuellement, je gère aussi des choses comme kikito. J'ai écrit quelques scripts shell pour créer différentes images à partir du même contexte, mais j'aimerais voir un moyen de spécifier un fichier docker à partir de l'argument CLI, comme déjà suggéré. +1 pour cette demande.

+1000

Je suis tombé sur cela aujourd'hui en essayant de créer un projet de golang multiplateforme à l'aide de docker. Cela fonctionne, voir boot2docker , mais j'ai besoin d'un Makefile pour assembler l'intérieur et l'extérieur du processus de construction de docker, par exemple docker cp les artefacts de l'intérieur de docker dans mon répertoire de construction.

Cependant, si j'essaie de l'utiliser dans un sous-répertoire de mon référentiel, mon GOPATH est cassé, car le dossier .git à la racine du référentiel est manquant. J'ai besoin de ADD la racine du référentiel, puis de construire dans mon sous-répertoire, mais cela n'est pas autorisé par docker.

Après avoir lu ce long fil, j'ai vu un souci de ne pas pouvoir reproduire les builds. Une façon d'atténuer cela est d'autoriser uniquement l'option -f à pointer dans le contexte de construction ou vers le bas. De cette façon, vous pouvez avoir plusieurs Dockerfiles dans des sous-répertoires et les construire à partir de la racine du référentiel. De plus, vous pouvez limiter cela à l'intérieur des limites du référentiel, par exemple au même niveau que .git/.hg/.foo et inférieur mais pas en dehors du référentiel.

Voici ce que je pense

FROM scratch
BUILD myname1 path/to/dockerfile/in/context
BUILD myname2 path/to/dockerfile2/in/context
docker build -t myimage .

Cela produirait 3 images :

  1. Image principale appelée "myimage", qui n'a vraiment rien dedans à titre d'exemple
  2. Une image appelée myimage-myname1
  3. Une image appelée myimage-myname2

Le mot-clé BUILD prendrait un nom et un chemin vers un fichier Docker. Ce Dockerfile doit être dans le contexte d'origine.
Chaque instruction de construction aurait accès au contexte complet de la construction principale.
Bien qu'il puisse être utile de limiter le contexte à l'arborescence dir dans laquelle le Dockerfile est contenu.

-1

Vous pouvez utiliser un alimentateur de contexte pour docker build - comme dockerfeed pour ce cas particulier.

@itsafire Le but est d'apporter ce type de fonctionnalité dans Docker afin que cela puisse être un moyen pris en charge de construire votre projet. Je suis sûr que les gens aimeraient que cela fonctionne également avec des versions automatisées.

Je suis perdu ici. Nous avons plusieurs demandes d'extraction pour cette fonctionnalité ajoutée, n'est-ce pas ? Et cela ne semble pas difficile à faire... On pourrait même appliquer la règle mentionnée par @maxnordlund : restreindre le chemin pour qu'il soit relatif au contexte/à la racine. Cela le rendrait au moins plus fluide avec boot2docket et autres, et le rendrait "portable".

C'est de loin la lacune la plus irritante dans Docker, et comme de plus en plus d'outils commencent à utiliser Docker dans le cadre de ses fonctionnalités, il est important que nous ajoutions rapidement la capacité d'un indicateur '-f' afin que ces outils soient préparés pour cela avant de devenir trop final... Connexe : avoir un Dockerfile multi-images ne le coupe pas, puisque ces outils "méta" connexes supposent souvent _une_ image par Dockerfile ! De plus, l'utilisation de '-' ne le coupe pas avec ces outils et limite considérablement la fonctionnalité, comme nous le savons tous.

Quelqu'un d'autorité peut-il expliquer pourquoi ce correctif n'est pas encore fusionné, ou du moins pourquoi cette fonctionnalité qui fait cruellement défaut n'est toujours pas là ?

Commencer à se sentir comme Twilight Zone.

Je suppose qu'il y a un décalage dans la façon dont l'équipe Docker utilise Docker / veut que Docker soit utilisé et comment une grande partie de la communauté utilise Docker. Corrige moi si je me trompe.

L'équipe docker veut construire un référentiel de logiciels pas très différent du référentiel du projet Debian. Où les gens peuvent obtenir leur logiciel préféré et l'exécuter facilement. Le processus de construction du logiciel doit être reproductible et évident.

D'autres souhaitent automatiser leur déploiement de logiciel interne existant, qui peut déjà être très complexe avec de nombreux outils de construction, système CI, etc. Pour eux, Docker n'est qu'un autre outil qui doit s'intégrer à leur infrastructure. Et ils ont besoin d'un peu plus de flexibilité dans la façon dont ils peuvent utiliser Docker.

Je pense que Docker (comme .deb) peut satisfaire les besoins des deux parties, mais des compromis devront être faits.

Le problème de base est : où cela s'arrête-t-il ? L'exhaustivité de Turing pour Dockerfile ? Probablement pas. Il y aura toujours besoin de plus de flexibilité pour résoudre les cas particuliers. Certaines idées entreront dans le langage Dockerfile, d'autres non. Étant donné que docker est capable de manger un contexte via stdin sur une construction, les fonctionnalités manquantes peuvent être implémentées via un pré-processeur.

@itsafire La dernière fois que j'ai vérifié, docker est capable de manger un Dockerfile mais pas un contexte. En fait, le contexte est ignoré lorsque vous fournissez un Dockerfile de cette façon. S'ils ajoutaient un support pour ce que vous avez suggéré, ce serait un problème clos.

Je n'ai pas regardé depuis un moment, mais la requête de base est la suivante : donnez-nous un moyen explicite de fournir à la fois un Dockerfile ET un context pendant la construction. Honnêtement choqué, c'est comme 8 mois plus tard et toujours ouvert.

@thedeeno c'est en effet possible
cat mystuff.tar.gz | docker build -

@ cpuguy83 mais je ne peux pas fournir un Dockerfile explicite avec cette commande. Droit?

@thedeeno oui, vous goudronnez n'importe quel Dockerfile que vous voulez avec le contexte que vous voulez.

@cpuguy83 @thedeeno Non, cela ne fonctionne pas, car vous ne pouvez alors AJOUTER aucun fichier car aucun n'est dans la portée "cwd" que vous obtenez habituellement avec un Dockerfile.

Edit : cette déclaration est fausse ; J'ai mal compris l'exemple de @cpuguy83 .

@ShawnMilo oui c'est ça. Tout ce qui se trouve dans le goudron est dans le contexte.

@ cpuguy83 Désolé, mon erreur. Je l'ai lu à la hâte comme une simple pipe dans le Dockerfile, pas un tarball entier.

@cpuguy83 Sympa ! Je vote près alors si cela fonctionne comme vous le suggérez.

Question secondaire, dans ma solution personnalisée, les horodatages ont éclaté le cache lors du tarage. C'est toujours un problème ? Si je tar le même dossier plusieurs fois, utilisera-t-il le cache lors de la construction ?

Continuez ce bon travail!

Diriger tout un contexte n'atténue pas du tout ce dont nous parlons ci-dessus.

Ce que nous voulons et avons besoin, c'est d'un moyen d'utiliser le _même_ contexte avec divers Dockerfiles. Tels que « construire avec journalisation » et « construire sans journalisation », comme des images individuelles. J'ai beaucoup d'autres cas d'utilisation où cela est nécessaire.

Je ne vois pas comment tar-baller un répertoire aiderait à cela. Oui, on pourrait créer un répertoire spécial et y copier le Dockerfile spécifique, puis tout le répertoire contextuel, ou tar et ajouter un nouveau Dockerfile, puis gzipping. Mais comment est-ce plus facile que la solution de contournement [assez terrible] que nous devons actuellement utiliser pour avoir un script de pré-processeur mettant le bon Dockerfile en place avant d'exécuter docker ?

Et, cela n'aidera pas avec l'écologie Docker, comme je l'ai noté ci-dessus.

Ai-je raté quelque chose ?

Encore une fois, une simple option '-f'. S'il te plaît. S'il vous plaît, joli s'il vous plaît. Forcez-le à être un chemin relatif du contexte. C'est bon.

@davber Ce que vous voulez vraiment, c'est que Docker gère l'archivage du contexte et du Dockerfile pour vous.
Et je ne suis pas totalement contre. Bien que je pense que les builds imbriqués peuvent être une meilleure solution à cela.

@cpuguy83 : oui, donc je veux que Docker s'en charge pour moi, oui, ce qui inclurait de choisir la partie contextuelle d'un endroit et le Dockerfile d'un autre endroit potentiellement, ou avec un nom non standard. C'est-à-dire pour prendre en charge un drapeau '-f' séparé :-)

Les builds imbriqués ne résolvent pas les problèmes auxquels nous sommes confrontés, ce qui a déclenché ce fil, et le maintient.

C'est-à-dire que nous voulons toujours utiliser le même contexte racine.

Oui, nous pouvons copier des fichiers, et, oui, nous le faisons pour contourner ce couplage étrange de contexte avec un Dockerfile exact nommé 'Dockerfile'. Mais ce n'est pas idéal, et configurer rsync pour s'assurer que les fichiers sont bien identiques à ceux d'origine est tout simplement étrange.

@cpuguy83 : pouvez-vous expliquer en quoi les versions imbriquées pourraient m'aider, ou l'un des autres "whiners" ici ? :-)

@davber
Mon avis est celui-ci :

FROM scratch
BUILD myname1 path/to/dockerfile
BUILD myname2 path/to/another/dockerfile

Et ça:

docker build -t myimage .

Donnerait 3 images, "myimage", "myimage-myname1", "myimage-myname2".
Chaque build interne aurait accès au contexte de build complet en tant que chemins absolus. Les chemins relatifs seraient relatifs au Dockerfile.
Et le "myimage" pourrait avoir ses propres trucs bien au-delà des simples instructions BUILD.

Comme je l'ai mentionné plus tôt, de nombreux nouveaux outils de la plus grande (et géniale !) écologie Docker supposent que chaque Dockerfile est associé à exactement une image Docker. Les différents outils d'orchestration de type "Fig". Et de nombreuses solutions cloud nouvelles et anciennes prenant en charge spécifiquement Docker ont également cette hypothèse un à un. Certes, ils devraient dans le monde créé par une option '-f' non seulement obtenir un contexte - comme une boule de goudron par exemple - mais aussi un Dockerfile, potentiellement séparé. Mais chaque téléchargement de ce type correspondrait toujours à exactement une image Docker.

Si nous choisissons de séparer potentiellement le Dockerfile de la racine de contexte, j'espère que ces outils commenceront à vivre avec ce scénario :

Each deployment/use of a Docker image is done with an upload of either:

   1. a Dockerfile solely, when no contextual operations are needed
   2. a context tar ball only, containing the context with a top-level Dockerfile
   3. both a context tar ball and a separate Dockerfile

Plus nous restons longtemps avec ce couplage fort de 'Dockerfile' au plus haut niveau de contexte, plus cela sera enraciné dans l'écologie. C'est-à-dire que nous devrions agir maintenant, alors que le monde Docker évolue rapidement, en raison de la génialité générale.

Et, honnêtement, c'est une hypothèse raisonnable et conceptuellement attrayante, d'avoir un isomorphisme entre Dockerfiles et images, même si le premier serait strictement un espace produit de répertoires de contexte (taré...) et Dockerfiles, par défaut (null, file) si seul Dockerfile est fourni et (context, context/'Dockerfile') si seul le contexte est fourni.

Et même pour un déploiement local : disons que nous voulons utiliser Fig pour au moins une orchestration locale : comment s'y prendrait-on ? Ce qu'il faudrait faire, c'est de pré-créer les images à partir d'un tel fichier Docker multi-build, puis de se référer à ces images dans la figure. Pas optimal.

un isomorphisme entre Dockerfiles et images

Cette hypothèse est déjà rompue dans la façon dont les personnes de ce fil utilisent Dockerfiles. C'est-à-dire en utilisant des scripts pour remplacer manuellement le fichier Dockerfile avant d'exécuter la construction de docker. Ils ont probablement aussi leur propre orchestration en place. Cette demande de fonctionnalité ne vise pas à changer le paysage de docker, mais à faire fonctionner docker pour un type d'utilisation spécifique.

@hanikesn : deux commentaires :

  1. pourquoi cette hypothèse est-elle brisée en devant copier Dockerfiles en place avant la construction ; ce serait toujours un Dockerfile <-> une image ?
  2. ce que je dis, c'est que je veux que la solution que nous proposons ici _travaille avec_ le paysage Docker existant et en pleine croissance, sans que de trop gros changements soient nécessaires dans ce paysage ; et je pense qu'en gardant l'isomorphisme mentionné, nous le faisons.

D'autres suggestions ici ont été d'avoir un Dockerfile multi-images, appelant potentiellement des sous-Dockerfiles. Cela ne fonctionnerait pas avec la façon dont la plupart des outils (Fig, etc.) utilisent actuellement Docker.

@davber

Les builds imbriqués ne résolvent pas les problèmes auxquels nous sommes confrontés, ce qui a déclenché ce fil, et le maintient.

Je propose cette solution que j'ai déjà signalée plus tôt :

$ docker-pre-processor [ --options ... ] . | docker build -

Alors que --options sont les règles, le contexte dans le (ici) répertoire courant doit être modifié et transmis à docker. Cela doit être fait à la volée en créant une archive tar temporaire contenant le contexte. De cette façon, le contexte source peut rester intact. Il est plus facile de modifier le préprocesseur que la syntaxe Dockerfile.

@itsafire

Qu'en est-il des outils qui attendent Dockerfiles aujourd'hui ? Ils sont de plus en plus nombreux, utilisant Amazon, Google ou autre. Et Fig et des cadres d'orchestration similaires.

Nous devrions alors proposer un outil standardisé de « préprocesseur docker » et l'utilisation d'un tel outil vers ces cadres, fournisseurs et outils.

Il serait certainement beaucoup plus facile d'avoir un support approprié de 'docker' au moins l'option déclenchant ce fil.

@itsafire tout le monde avec ce problème qui l'a résolu utilise déjà une sorte de préprocesseur ou de wrapper autour de la construction de docker pour atteindre cet objectif.

La fragmentation autour de cette situation est en conflit avec l'objectif déclaré de l'équipe @docker de « répétabilité ». Cette discussion et les autres visent à résoudre ce problème.

Plus d'un an et plus de 130 commentaires et comptant pour un problème simple affectant la plupart des utilisateurs... Je suis impressionné. Continuez votre bon travail, Docker!

+1

Les outils doivent aider les gens à suivre leur propre voie, mais pas à imposer la "bonne" voie. Un cas simple qui m'a amené à cette discussion :

`-- project
     |-- deploy
     |    |-- .dockerignore
     |    |-- Dockerfile
     |    ...
     `-- src

Ma façon est de garder la racine du projet propre. Mais ADD ../src et -f deploy/Dockerfile ne fonctionnent pas. Pour l'instant, j'ai Dockerfile et .dockerignore à la racine du projet, mais c'est pénible pour moi.

De mon côté, j'ai construit un script qui prépare un dossier avec les fichiers requis et exécute la ligne de commande standard docker build -t my/image . car j'ai rencontré le problème que le fichier .dockerignore est ignoré par le ADD ...

+1 aimerait bien pouvoir avoir plusieurs Dockerfiles dans un seul dépôt. Mon cas d'utilisation : une image est destinée à l'utilisation et au déploiement en production, une autre image est une instance de création de rapports conçue pour utiliser les mêmes outils backend et la même connectivité de base de données, mais ne nécessite aucun service frontal, Web, système ou supervision de processus...

+1 pour cela. J'ai besoin d'ajouter des fichiers à différentes images du même dossier, pour différents serveurs.

+1 J'apprécie Docker jusqu'à présent, mais en raison de la façon dont mon équipe a configuré, j'ai vraiment besoin d'un moyen de créer différents déployables qui partagent une bonne partie du code, à partir d'un seul dépôt. Pas particulièrement désireux de les intégrer tous dans un conteneur uberdocker, car leurs cycles de déploiement/libération sont alors inutilement liés. Quelle est la meilleure pratique pour contourner ce problème ?

@jfgreen : Mettez plusieurs Dockerfiles où vous voulez et nommez-les comme vous voulez. Ensuite, ayez un script bash qui les copie un par un à la racine du référentiel en tant que "./Dockerfile", exécute "docker build", puis les supprime. C'est ce que je fais pour plusieurs projets et cela fonctionne parfaitement. J'ai un dossier "dockerfiles" contenant des fichiers nommés comme base de données, base, tests, etc. qui sont tous des Dockerfiles.

@ShawnMilo Merci, cela semble être une solution de contournement très raisonnable.

+1

+1

+1 à un -f . Il y a une valeur par défaut sensée qui, si le drapeau est omis, Docker fera _la bonne chose._ Dans le cas où, pour une raison quelconque, la vue très spécifique de _la bonne chose_ est pour un utilisateur _la mauvaise chose_ il y a -f . Je pense que les comparaisons ci-dessus avec des outils comme make sont raisonnables. make est également un utilitaire très opiniâtre écrit à l'origine en 1976 et en tant que tel, il disposait d'un délai raisonnable pour stabiliser un ensemble de fonctionnalités. Je pense qu'il est instructif que dans man make le seul drapeau qui soit mentionné dans le très bref résumé est... -f .

       make [ -f makefile ] [ options ] ... [ targets ] ...

Il n'y a pas de problème dans les utilitaires opiniâtres centrés sur l'UX, mais certaines choses comme -f sont des clins d'œil pragmatiques au monde réel dans lequel vivent les utilisateurs. Un outil devrait vous rendre la vie plus facile et non plus difficile. Si je dois écrire un Makefile ou un script shell pour contourner un outil sans -f c'est un échec de l'outil. De toute évidence, d'après le nombre d'utilisateurs qui ont pris le temps de commenter et qui ont pesé +1, la fonctionnalité a une utilité significative même un an après sa proposition initiale.

+1

+1 (ou un article de blog officiel avec la solution de contournement recommandée)

+1

+1

@crosbymichael Je pense que cela peut être fermé maintenant en raison de la fusion de # 9707

LA VICTOIRE.

Si vous voulez tous essayer cette nouvelle fonctionnalité, vous pouvez télécharger les binaires pour master sur :

master.dockerproject.com

Merci @duglin !

:taper:

Merci @crosbymichael pour le binaire ! :+1:

Bien joué les gars! :taper:

Alors c'est docker build -f Dockerfile.dev . ? éditer : ouais

Cette page vous a été utile?
0 / 5 - 0 notes