Crie imagem do Docker com cache no servidor de compilação?

7

Temos um servidor de CI Jenkins que obtém nosso código do Git, cria, faz uma imagem do Docker e envia-o para alguns servidores de produção.

Nosso projeto é escrito principalmente em Python, então "construir" envolve a execução

pip install -r requirements.txt

Isso funciona bem, exceto que é meio lento. Ele tem que buscar pacotes pela rede, além de ter que construir bibliotecas C para alguns deles (e 'lxml' não é pequeno!).

Em desenvolvimento, tive sucesso usando pip-accel para acelerar esse processo. Ele tem a mesma interface de pip , mas armazena em cache tanto os downloads em Python quanto o código em C, portanto

pip-accel install -r requirements.txt

é rápido.

Eu quero fazer isso para nossas construções de produção, mas estou encontrando alguns obstáculos.

Obviamente, pip-accel precisa de um diretório no qual armazenar o cache. Como o nosso servidor de CI é o que executa as construções, esse é o lugar lógico para colocá-lo. Mas o comando pip install é executado dentro de um novo contêiner do Docker, portanto, não pode simplesmente acessar um diretório comum nesse servidor.

Os "volumes" do Docker parecem ter sido projetados para compartilhar diretórios com contêineres, mas nossa compilação acontece (surpresa surpresa) dentro de docker build e apenas docker run permite anexar volumes. Você não pode anexar volumes com docker build .

Há algo que estou perdendo? Como posso executar um docker build e compartilhar uma pasta de cache com meu host, fora do contêiner em que estou?

    
por Tim 25.12.2015 / 01:49

1 resposta

0

Eu tenho poucas reputações para comentar sua pergunta, então minha resposta também tem algumas perguntas.

Eu tentei criar a mesma configuração que a sua, mas diminuí (com base na sua explicação acima) e parece haver melhorias com os próprios mecanismos de cache do Docker

Meu exemplo Dockerfile é assim:

FROM ubuntu:14.04   

RUN apt-get update \
  && apt-get install -y python-pip python-dev build-essential \
  && pip install pip-accel

COPY requirements.txt /requirements.txt

RUN pip-accel install -r /requirements.txt

CMD tail -f /dev/null

E requirements.txt ficou assim:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3

Depois de construir isso pela primeira vez (procure um tempo maior), adicionei uma nova biblioteca "chardet == 1.0.1" e agora meu requirements.txt parecia:

Flask==0.8
Jinja2==2.6
Werkzeug==0.8.3
chardet==1.0.1

Depois de executar a compilação do docker, ele usou o próprio cache do Docker que também tinha as antigas bibliotecas de pip.

anovil@anovil-Latitude-E6440:~/tmp/serverfault/docker$ time docker build --rm .
Sending build context to Docker daemon 3.072 kB
Step 1 : FROM ubuntu:14.04
 ---> 89d5d8e8bafb
...
...
Removing intermediate container 337c23340e7a
Step 5 : CMD tail -f /dev/null
 ---> Running in 5cb25bc75bbe
 ---> d3dfe184934b
Removing intermediate container 5cb25bc75bbe
Successfully built d3dfe184934b

real    0m6.325s
user    0m0.024s
sys 0m0.012s

Porque o docker build por padrão tem '--force-rm = false', '--no-cache = false'.
Pode ser uma história diferente se seu IC Jenkins executar essa construção como usuários diferentes ou em hosts diferentes. Caso contrário, é uma questão de ordenar os comandos no Dockerfile.
Se você ainda tiver dúvidas, você pode compartilhar seu Dockerfile de exemplo e também informar aqui quanto / frequentemente o seu requirements.txt muda cada compilação do jenkins.

    
por 31.12.2015 / 10:20