Je ne parviens pas à trouver beaucoup d'exemples de ce à quoi devrait ressembler un fichier .dockerignore.
Si vous utilisez marionnette pour installer quelques packages sur un conteneur Docker, l’image explose de 600 Mo à 3 Go. J'essaie d'utiliser un fichier .dockerignore
pour conserver une taille minimale.
$ cat Dockerfile
FROM centos:centos6
#Work around selinux problem on cent images
RUN yum install -y --enablerepo=centosplus libselinux-devel
RUN yum install -y wget git tar openssh-server; yum -y clean all
Add Puppetfile /
RUN librarian-puppet install
RUN puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}"
RUN librarian-puppet clean
Si je lance docker images --tree
, je peux voir que l'image augmente instantanément de plusieurs Go.
$ docker images --tree
├─e289570b5555 Virtual Size: 387.7 MB
│ └─a7646acf90d0 Virtual Size: 442.5 MB
│ └─d7bc6e1fbe43 Virtual Size: 442.5 MB
│ └─772e6b204e3b Virtual Size: 627.5 MB
│ └─599a7b5226f4 Virtual Size: 627.5 MB
│ └─9fbffccda8bd Virtual Size: 2.943 GB
│ └─ee46af013f6b Virtual Size: 2.943 GB
│ └─3e4fe065fd07 Virtual Size: 2.943 GB
│ └─de9ec3eba39e Virtual Size: 2.943 GB
│ └─31cba2716a12 Virtual Size: 2.943 GB
│ └─52cbc742d3c4 Virtual Size: 2.943 GB
│ └─9a857380258c Virtual Size: 2.943 GB
│ └─c6d87a343807 Virtual Size: 2.964 GB
│ └─f664124e0080 Virtual Size: 2.964 GB
│ └─e6cc212038b9 Virtual Size: 2.964 GB Tags: foo/jenkins-centos6-buildslave:latest
Je crois que la raison pour laquelle l'image grossit tellement, c'est parce que librarian-puppet
clone un module de marionnette en /modules
qui casse le cache de construction.
J'ai essayé les fichiers .dockerignore
suivants sans succès.
$ cat .dockerignore
/modules
/modules/
/modules/*
Est-ce la syntaxe correcte pour un fichier .dockerignore
?
Existe-t-il d'autres moyens d'empêcher ces conteneurs de devenir aussi volumineux?
Information additionnelle:
http://kartar.net/2013/12/building-puppet-apps-inside-docker/
http://danielmartins.ninja/posts/a-week-of-docker.html
.dockerignore
sert à empêcher l'ajout de fichiers au contexte de construction initial envoyé au démon docker lorsque vous effectuez docker build
. Il ne crée pas de règle globale permettant d'empêcher la création de fichiers dans toutes les images générées par un fichier Dockerfile.
Il est important de noter que chaque instruction RUN
générera une nouvelle image, le parent de cette image étant l'image générée par l'instruction Dockerfile située au-dessus d'elle. Essayez de réduire vos déclarations RUN
en une seule pour réduire la taille de l’image:
RUN librarian-puppet install &&\
puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}" &&\
librarian-puppet clean
Le format de .dockerignore
devrait être égal à celui de .gitignore
. Voir un exemple de fichier et le menu fixe documentation .
Le fichier doit être une liste de modèles d'exclusion (par rapport au chemin du fichier .dockerignore
) séparés par une nouvelle ligne.
Donc, vous devriez essayer le .dockerignore
suivant:
modules/*
L’erreur /
au début a peut-être été commise car elle ne sera valable que pour le répertoire racine du fichier (mais pas pour les sous-répertoires, la version récursive sans /
fera peut-être mieux son travail).
Ni:
modules/*
ni
modules
ne fonctionnerait pas pour moi, docker continuait à polluer l’image avec des fichiers inutiles jusqu’à ce que je l’ai réglée comme ceci:
**/modules
fonctionne également avec:
**/modules/*.py
Une autre façon de procéder, en créant une image plus petite, consiste à exécuter libellaire-marionnette dans l'hôte , pas dans Docker, afin d'éviter de vous retrouver avec le bibliothécaire, Ruby, gems, ... installé dans l'image .
J'ai terminé avec une image de 622 Mo pour jenkins esclave avec Puppet , et une image de 480 Mo sans Puppet .
http://docs.docker.com/articles/dockerfile_best-practices/
Il me semble que votre approche est rétrograde (conformément à @csanchez) et que vous devriez générer votre conteneur de docker à partir d'une marionnette, et non pas exécuter la marionnette dans le conteneur ...
De même, vous devriez &&
les lignes install/apply/clean ensemble ... chaque commande de docker crée une image incrémentielle ... S'il existe des fichiers temporaires/de ressources faisant partie des commandes centos yum
, vous devez également faire de même.
FROM centos:centos6
# Add your needed files first
# maybe you could use a baseimage and make this a volume mount point?
Add Puppetfile /
# combine multiple commands with cleanup of cache/temporary
# space in the same run sequence to reduce wasted diff image space.
#Work around selinux problem on cent images
RUN yum install -y --enablerepo=centosplus libselinux-devel && \
yum install -y wget git tar openssh-server; yum -y clean all && \
librarian-puppet install && \
puppet apply --modulepath=/modules -e "class { 'buildslave': jenkins_slave => true,}" && \
librarian-puppet clean
Je VRAIMENT suggérerais d'éviter SELINUX dans un conteneur, cela ne vous donnera rien à l'intérieur d'un conteneur. Sans compter que selon ce que vous essayez de créer, il existe des lieux de départ plus petits que centos6. Je crois que Ubuntu est plus petit, Debian: Wheezy encore plus petit, ou même Alpine pour un tout petit point de départ.
Il est à noter que votre taille de fichier, si vous utilisez un système de fichiers prenant en charge les montages virtuels, peut réutiliser la même image de base pour plusieurs instances, de sorte qu'elle ne grandira pas plus
L’optimisation de la taille de l’image du conteneur est l’objectif principal de .dockerignore, car elle a une fonction similaire à celle de votre .gitignore, car elle réduit le temps de latence et le temps de réponse lors de la fourniture de services. Cela est vrai pour l'automatisation de déploiement telle que Puppet, SaltStack ou Ansible. L'horodatage défini pour le déploiement de l'exécution du service peut échouer en raison de la taille plus grande de l'image et de la faible bande passante du réseau. Donc .dockerignore contribue à réduire au maximum la taille de l’image.
Vous pouvez le placer dans le répertoire de contexte build que nous spécifions à la fin d'une commande de génération de docker. Le fichier suit glob pattern pour les fichiers et les répertoires afin d'exclure ceux-ci de l'image de construction finale.
Supposons que j'ai un répertoire .img/ dans mon contexte de construction et que je veuille l'exclure lors de la création d'une image, je vais simplement ajouter la ligne suivante dans le fichier .dockerignore,
.img
Et, si je veux exclure tous les fichiers commence par. puis simplement, ajoutez la ligne,
.*
(Remarque: ne confondez pas le motif global Unix qui est différent des expressions régulières)
En outre, je vais exclure un peu plus de mes fichiers de mon contexte de construction,
.*
docs
my-stack.dab
docker-compose.overrride.yml
test*
*.md
!README.md
Ici, la ligne * .md exclut tous les fichiers de démarques (j'ai plusieurs fichiers de démarques dans mon projet). Mais, je veux inclure README.md et aucun autre fichier de démarques. En tant que dernière ligne ci-dessus, nous avons ajouté README.md avec ! ou l'exclure tout en excluant tous les autres fichiers de démarques.
Nous pouvons ainsi réduire les frais généraux de votre image de construction à l'aide de .dockerignore et tirer parti de la réduction de la taille de l'image.