Comment mettre à jour le code de Git vers un conteneur Docker

j'ai un fichier Docker essayant de déployer du code Django dans un conteneur

FROM ubuntu:latest
MAINTAINER { myname }

#RUN echo "deb http://archive.ubuntu.com/ubuntu/ $(lsb_release -sc) main universe" >> /etc/apt/sou$

RUN apt-get update

RUN DEBIAN_FRONTEND=noninteractive apt-get install -y tar git curl dialog wget net-tools nano buil$
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y python python-dev python-distribute python-p$

RUN mkdir /opt/app
WORKDIR /opt/app

#Pull Code
RUN git clone git@bitbucket.org/{user}/{repo}

RUN pip install -r website/requirements.txt

#EXPOSE = ["8000"]
CMD python website/manage.py runserver 0.0.0.0:8000

puis-je construire mon code docker build -t dockerhubaccount/demo:v1 ., et ceci tire mon code de Bitbucket au conteneur. Je le lance en tant que docker run -p 8000:8080 -td felixcheruiyot/demo:v1 et les choses semblent bien fonctionner.

maintenant je veux mettre à jour le code I. e depuis que j'ai utilisé git clone ..., j'ai cette confusion:

  • Comment puis-je mettre à jour mon code quand j'ai de nouveaux commits et que les conteneurs Docker le construisent avec le nouveau code (note: quand je exécuter le construire ne pas chercher à cause du cache).
  • Quel est le meilleur workflow pour ce type d'approche?
28
demandé sur Peter Mortensen 2014-12-17 18:35:43

5 réponses

il y a quelques approches que vous pouvez utiliser.

  1. Vous pouvez utiliser docker build --no-cache pour éviter d'utiliser le cache du clone Git.
  2. la commande de démarrage appelle git pull. Donc, au lieu de courir python manage.py, vous auriez quelque chose comme CMD cd /repo && git pull && python manage.py ou utiliser un script de démarrage si les choses sont plus complexes.

j'ai tendance à préférer 2. Vous pouvez également exécuter un travail cron pour mettre à jour le code dans votre conteneur, mais c'est un peu plus de travail et va quelque peu à l'encontre du Docker Philosophie.

20
répondu seanmcl 2017-11-29 22:40:42

je vous recommande la caisse le code sur votre hôte et COPY dans l'image. De cette façon, il sera mis à jour à chaque fois que vous faites un changement. En outre, pendant le développement, vous pouvez lier le montage du répertoire source sur le répertoire de code dans le conteneur, ce qui signifie que tout changement se reflète immédiatement dans le conteneur.

une commande docker pour les dépôts git qui vérifie la dernière mise à jour serait cependant très utile!

10
répondu Adrian Mouat 2014-12-18 13:44:30

une Autre solution.

la commande docker build utilise le cache à condition qu'une chaîne d'instructions soit exactement la même que celle de l'image mise en cache. Ainsi, si vous écrivez

RUN echo '2014122400' >/dev/null && git pull ...

sur la prochaine mise à jour, vous changez comme suit.

RUN echo '2014122501' >/dev/null && git pull ...

cette boîte empêche docker d'utiliser le cache.

5
répondu takaomag 2014-12-18 01:25:48

je voudrais proposer une autre solution possible. Je dois toutefois vous prévenir que ce n'est certainement pas la "manière docker" de faire les choses et repose sur l'existence de volumes (qui pourrait être un bloqueur potentiel dans des outils comme Docker Swarm et Kubernetes)

le principe de base dont nous allons profiter est le fait que le contenu des répertoires de conteneurs qui sont utilisés comme Volumes Docker, sont en fait stockés dans le système de fichiers de l'hôte. Découvrez partie de la documentation.

Dans votre cas, vous feriez /opt/app un menu fixe en Volume. Vous n'avez pas besoin de mapper le Volume explicitement à un emplacement sur le système de fichiers de l'hôte puisque comme je le décrirai ci-dessous, le mappage peut être obtenu dynamiquement.

alors, pour commencer, quittez votre fichier Dockerfile tel quel et changez votre commande de création de conteneur en quelque chose comme:

docker run -p 8000:8080 -v /opt/app --name some-name -td felixcheruiyot/demo:v1

La commande docker inspect -f {{index .Volumes "/opt/webapp"}} some-name affichera le chemin complet du système de fichiers sur l'hôte où votre code est stocké ( est l'endroit où j'ai trouvé le tour d'inspection).

armé de cette connaissance, tout ce que vous avez à faire est de remplacer ce code et votre ensemble. Donc un script de déploiement très simple serait quelque chose comme:

code_path=$(docker inspect -f {{index .Volumes "/opt/webapp"}} some-name)
rm -rfv $code_path/*
cd $code_path
git clone git@bitbucket.org/{user}/{repo}

Les avantages que vous obtenez avec une approche de ce genre sont:

  • il n'y a pas de reconstruction d'image sans cachette potentiellement coûteuse
  • Il n'est pas nécessaire de déplacer l'application spécifique informations sur la commande exécuter. Le fichier Dockerfile est la seule source nécessaire pour instrumenter l'application

UPDATE

vous pouvez obtenir les mêmes résultats que ceux que j'ai mentionnés ci-dessus en utilisant panneau de cp (démarrage Docker 1.8). De cette façon, le conteneur n'a pas besoin de volumes, et vous pouvez remplacer le code dans le conteneur comme vous le feriez sur le système de fichiers hôte.

bien sûr, comme je l'ai mentionné au début de réponse, ce n'est pas la "manière docker" de faire les choses, qui préconise des conteneurs immuables et reproductibles.

2
répondu geoand 2016-02-17 07:43:09

si vous utilisez GitHub, vous pouvez utiliser L'API GitHub pour ne pas mettre en cache des commandes D'exécution spécifiques.

Vous devez avoir jq installé pour parser JSON: apt-get install -y jq

Exemple:

docker build --build-arg SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | jq -r '.[0].sha') -t imageName .

Dans Dockerfile (ARG commande doit être droite avant l'EXÉCUTION):

ARG SHA=LATEST
RUN SHA=${SHA} \
    git clone https://github.com/Tencent/mars.git

Ou si vous ne souhaitez pas installer jq:

SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)

Si un dépôt a les nouveaux commits, git clone sera exécuté.

0
répondu Michal Z m u d a 2017-11-29 22:42:08