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 [email protected]/{user}/{repo}
RUN pip install -r website/requirements.txt
#EXPOSE = ["8000"]
CMD python website/manage.py runserver 0.0.0.0:8000
Et puis je construis mon code en tant que docker build -t dockerhubaccount/demo:v1 .
, et cela extrait mon code de Bitbucket vers le 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:
Il existe plusieurs approches que vous pouvez utiliser.
docker build --no-cache
pour éviter d'utiliser le cache du clone Git.git pull
. Ainsi, au lieu d'exécuter python manage.py
, vous utiliseriez quelque chose comme CMD cd /repo && git pull && python manage.py
ou utilisez 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 de votre conteneur, mais cela demande un peu plus de travail et va un peu à l'encontre de la philosophie Docker.
Je vous recommande de vérifier le code sur votre hôte et le COPY
dans l'image De cette façon, il sera mis à jour chaque fois que vous apporterez un changement. En outre, pendant le développement, vous pouvez lier le répertoire source par-dessus le répertoire de code du conteneur, ce qui signifie que toutes les modifications sont immédiatement reflétées dans le conteneur.
Une commande docker pour les dépôts git qui vérifie la dernière mise à jour serait très utile cependant!
Une autre solution.
La commande de construction Docker utilise le cache tant qu'une chaîne d'instruction est identique à celle de l'image mise en cache. Donc, si vous écrivez
RUN echo '2014122400' >/dev/null && git pull ...
Lors de la prochaine mise à jour, vous changez comme suit.
RUN echo '2014122501' >/dev/null && git pull ...
Cela peut empêcher le menu fixe d'utiliser le cache.
Je voudrais proposer une autre solution possible. Je dois toutefois avertir que ce n’est certainement pas la "manière de 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 tirer parti est le fait que le contenu des répertoires de conteneur utilisés en tant que volumes Docker est en réalité stocké dans le système de fichiers de l'hôte. Découvrez this une partie de la documentation.
Dans votre cas, vous feriez /opt/app
un volume Docker. Vous n'avez pas besoin de mapper explicitement le volume sur un emplacement du système de fichiers de l'hôte car, comme je le décrirai ci-dessous, le mappage peut être obtenu de manière dynamique.
Donc, pour commencer, laissez votre fichier Dockerfile exactement tel qu’il est et passez votre commande de création de conteneur à 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
imprimera le chemin d'accès complet au système de fichiers sur l'hôte où votre code est stocké ( this est l'endroit où j'ai pris l'astuce d'inspecter).
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 [email protected]/{user}/{repo}
Les avantages que vous obtenez avec une telle approche sont les suivants:
METTRE À JOUR
Vous pouvez obtenir les mêmes résultats que ceux mentionnés ci-dessus avec docker cp (à partir de 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 la réponse, ce n’est pas la "manière docker" de faire les choses, qui préconise que les conteneurs soient immuables et reproductibles.
Si vous utilisez GitHub, vous pouvez utiliser l'API GitHub pour ne pas mettre en cache des commandes RUN spécifiques.
Vous devez avoir installé jq pour pouvoir analyser 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 (la commande ARG devrait être juste avant RUN):
ARG SHA=LATEST
RUN SHA=${SHA} \
git clone https://github.com/Tencent/mars.git
Ou si vous ne voulez pas installer jq:
SHA=$(curl -s 'https://api.github.com/repos/Tencent/mars/commits' | grep sha | head -1)
Si un référentiel a de nouveaux commits, git clone
sera exécuté.