Cómo actualizar código de Git a un contenedor Docker


Tengo un archivo Docker intentando implementar código Django en un contenedor

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

Y luego construyo mi código como docker build -t dockerhubaccount/demo:v1 ., y esto extrae mi código de Bitbucket al contenedor. Corro como docker run -p 8000:8080 -td felixcheruiyot/demo:v1 y las cosas parecen funcionar bien.

Ahora quiero actualizar el código, es decir, desde que usé git clone ..., tengo esta confusión:

  • ¿Cómo puedo actualizar mi código cuando tengo nuevas confirmaciones y cuando los contenedores de Docker lo construyen se envía con el nuevo código (nota: cuando corro build no lo obtiene debido a la caché).
  • ¿Cuál es el mejor flujo de trabajo para este tipo de enfoque?
Author: Peter Mortensen, 2014-12-17

5 answers

Hay un par de enfoques que puede utilizar.

  1. Puedes usar docker build --no-cache para evitar usar la caché del clon de Git.
  2. El comando de inicio llama a git pull. Así que en lugar de ejecutar python manage.py, tendrías algo como CMD cd /repo && git pull && python manage.py o usarías un script de inicio si las cosas son más complejas.

Tiendo a preferir 2. También puede ejecutar un trabajo cron para actualizar el código en su contenedor, pero eso es un poco más de trabajo y va en contra de la filosofía de Docker.

 20
Author: seanmcl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-29 22:40:42

Te recomiendo que descargues el código de tu host y COPY lo introduzcas en la imagen. De esa manera se actualizará cada vez que realice un cambio. Además, durante el desarrollo puede enlazar montar el directorio de origen sobre el directorio de código en el contenedor, lo que significa que cualquier cambio se refleja inmediatamente en el contenedor.

Un comando docker para repositorios git que comprueba la última actualización sería muy útil!

 10
Author: Adrian Mouat,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-18 13:44:30

Otra solución.

El comando Docker build usa caché siempre y cuando una cadena de instrucciones sea exactamente la misma que la de la imagen almacenada en caché. Entonces, si escribes

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

En la próxima actualización, cambia de la siguiente manera.

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

Esto puede evitar que docker use caché.

 5
Author: takaomag,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-12-18 01:25:48

Me gustaría ofrecer otra posible solución. Necesito advertir sin embargo que definitivamente no es la "forma de docker" de hacer las cosas y se basa en la existencia de volúmenes (que podría ser un bloqueador potencial en herramientas como Docker Swarm y Kubernetes)

El principio básico que vamos a aprovechar es el hecho de que el contenido de los directorios contenedores que se utilizan como volúmenes Docker, en realidad se almacenan en el sistema de archivos del host. Echa un vistazo esta parte de la documentación.

En su caso haría /opt/app un volumen Docker. No es necesario asignar el volumen explícitamente a una ubicación en el sistema de archivos del host, ya que, como describiré a continuación, la asignación se puede obtener dinámicamente.

Para empezar, deje su Dockerfile exactamente como está y cambie su comando de creación de contenedores a algo como:

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

El comando docker inspect -f {{index .Volumes "/opt/webapp"}} some-name imprimirá la ruta completa del sistema de archivos en el host donde se almacena su código (esto es donde recogí el truco de inspección).

Armado con ese conocimiento todo lo que tienes que hacer es reemplazar ese código y todo tu conjunto. Así que un script de implementación muy simple sería algo como:

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

Los beneficios que obtienes con un enfoque como este son:

  • No hay reconstrucciones de imágenes sin caché potencialmente costosas
  • No es necesario mover la información de ejecución específica de la aplicación al comando run. El Dockerfile es la única fuente necesaria para instrumentar la aplicación

UPDATE

Puede lograr los mismos resultados que he mencionado anteriormente utilizando docker cp (a partir de Docker 1.8). De esta manera, el contenedor no necesita tener volúmenes, y puede reemplazar el código en el contenedor como lo haría en el sistema de archivos host.

Por supuesto, como mencioné al principio de la respuesta, esta no es la "forma docker" de hacer las cosas, que aboga por que los contenedores sean inmutables y reproducibles.

 2
Author: geoand,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-17 07:43:09

Si usas GitHub puedes usar la API de GitHub para no almacenar en caché comandos de ejecución específicos.

Necesita tener instalado jq para analizar JSON: apt-get install -y jq

Ejemplo:

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

En Dockerfile (el comando ARG debe estar justo antes de EJECUTARSE):

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

O si no desea instalar jq:

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

Si un repositorio tiene nuevas confirmaciones, git clone se ejecutará.

 0
Author: Michal Z m u d a,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-29 22:42:08