web-dev-qa-db-fra.com

Docker et liens symboliques

J'ai un repo mis en place comme ceci:

/config
   config.json
/worker-a
   Dockerfile
   <symlink to config.json>
   /code
/worker-b
   Dockerfile
   <symlink to config.json>
   /code

Cependant, la construction des images échoue car Docker ne peut pas gérer les liens symboliques. Je devrais mentionner que mon projet est beaucoup plus compliqué que cela, alors la restructuration des répertoires n’est pas une bonne option. Comment puis-je gérer cette situation?

21
Chris B.

Docker ne prend pas en charge les liens symboliques en dehors du contexte de construction .

Quelques méthodes différentes pour utiliser un fichier partagé dans un conteneur. 

Partager une image de base

Créez une Dockerfile pour l'image de base worker-config qui inclut la configuration/les fichiers partagés. 

COPY config.json /config.json

Construire et étiqueter l'image en tant que worker-config

docker build -t worker-config:latest .

Sourcez l'image worker-config de base pour tous vos employés Dockerfiles

FROM worker-config:latest

Construire le script

Utilisez un script pour transmettre la configuration commune à chacun de vos conteneurs de travail.

./build worker-n

#!/bin/sh
set -uex 
rundir=$(readlink -f "${0%/*}")
container=$(shift)
cd "$rundir/$container"
cp ../config/config.json ./config-docker.json
docker build "$@" .

Construire à partir d'une URL

Extrayez la configuration d'une URL commune pour toutes les générations worker-n

ADD http://somehost/config.json /

Augmenter la portée du contexte de construction de l'image

Incluez les fichiers cibles des liens symboliques dans le contexte de construction en créant à partir d'un répertoire parent qui inclut à la fois les fichiers partagés et des fichiers de conteneur spécifiques.

cd ..
docker build -f worker-a/Dockerfile .

Tous les chemins source que vous référencez dans une Dockerfile doivent également être modifiés pour correspondre au nouveau contexte de construction:

COPY workerathing /app

devient

COPY worker-a/workerathing /app

L'utilisation de cette méthode peut rendre all des contextes de construction volumineux si vous avez un seul contexte de construction volumineux, car ils deviennent tous partagés. Cela peut ralentir les générations, en particulier pour les serveurs de compilation Docker distants. 

Monter un répertoire de configuration à partir d'un volume nommé

De tels volumes ne fonctionnent que comme des répertoires, vous ne pouvez donc pas spécifier un fichier comme vous le feriez lors du montage d'un fichier de l'hôte au conteneur.

docker volume create --name=worker-cfg-vol
docker run -v worker-cfg-vol:/config worker-config cp config.json /config

docker run -v worker-cfg-vol:/config:/config worker-a

Monter le répertoire de configuration à partir du conteneur de données

Encore une fois, les répertoires seulement, car c’est fondamentalement le même que ci-dessus. Cela copiera automatiquement les fichiers du répertoire de destination dans le volume partagé nouvellement créé. 

docker create --name wcc -v /config worker-config /bin/true
docker run --volumes-from wcc worker-a

Monter le fichier de configuration à partir de l'hôte

docker run -v /app/config/config.json:/config.json worker-a
34
Matt

La commande CLI docker build envoie le répertoire spécifié (généralement .) en tant que "contexte de construction" au moteur Docker (démon). Au lieu de spécifier le contexte de construction en tant que /worker-a, spécifiez le contexte de construction en tant que répertoire racine et utilisez l'argument -f pour spécifier le chemin d'accès à la variable Dockerfile dans l'un des répertoires enfants.

docker build -f worker-a/Dockerfile .
docker build -f worker-b/Dockerfile .

Vous devrez retravailler légèrement vos fichiers Dockerfile pour les diriger vers ../config/config.json, mais c'est assez simple à corriger.

Consultez également cette question/réponse, qui, je pense, répond exactement au même problème que vous rencontrez.

Comment inclure des fichiers en dehors du contexte de construction de Docker?

J'espère que cela t'aides! À votre santé

1
Trevor Sullivan

Une solution alternative consiste à mettre à niveau tous vos liens symboliques en liens physiques.

1
Benjamin Pastel