Algumas notas sobre docker
Ok, não consegui manter o ritmo de uma semana (meta inicial). Mas voltando…
Docker
A algum tempo venho planejando falar algo sobre esse cara (o docker), mas ao mesmo tempo vejo que já tem zilhões de vídeos/artigos falando sobre docker. E ainda tem pessoas q tem dúvidas sobre ele, então acho que ainda tem margem para falar mais um pouco :-)
Não sei nada de docker, por onde começo?
Um dos vídeos mais ditáticos é o do Linux tips:
…e tem também o vídeo do Gomex:
Ok, e o que mais?
Bom, aqui eu tento transmitir os conhecimentos de um grande professor / arquiteto, Diogo Lucas:
1) O container docker é imutável. Toda vez que você parar ele e rodar denovo, ele terá o mesmo estado da primeira execução. Ele não guarda estado. Você pode ter volumes mapeados para guardar dados (ex: banco de dados), mas logs ou outros dados não devem ser salvos dentro de um container. Levantar container e fazer uma configuração tbm não é uma boa prática (ex: rodar jboss com config especial feita em runtime). Configs devem ficar fora do container também… talvez variáveis de ambiente? (ver 12 factors - config).
Outro ditado sobre o docker que chama a atenção a primeira vista: containers docker devem ser tratados como gado, e não como animais de estimação. Você não dá nome para gado. E não deve ter medo de matar um container e recriar. Se você dá nome para as instancias de containers (instancias, não imagens), tem algo errado aí…
2) Uma imagem docker usa camadas (layers). Logo, ao criar uma imagem tem que ser pensado o que será reusado. Logo, incluir dependencias antes do código.
Um exemplo:
FROM node:latest
RUN mkdir /app
WORKDIR /app
# Adiciona descritor de dependencias na imagem
ADD package.json /app
#baixa as dependencias na imagem
RUN npm install
#Adiciona o resto do código
ADD . /app
EXPOSE 80
Supondo um desenvolvimento "normal" nesse projeto node, mudanças de código serão rápidas pois o docker fará cache da imagem node e das dependencias (descritas no package.json). A imagem só vai baixar as dependencias novamente se o package.json for alterado.
3) Containers são leves. Ok, esse imagem deve estar batida, mas vamos denovo:
Não são as libs do OS são reusadas, mas as imagens base também: instancias diferentes de containers que usam as mesmas imagens base / layers no mesmo server compartilham essa memória. Dois containers em execução não são duas vezes o uso da memória.
4) Containes são reproduzíveis. Sim, aquela história de "funciona na minha máquina" acabou. Não importa se o host é windows/linux/osx, a execução do container deve ser igual.
Imagine o cenário: você tem uma aplicação node / java que acessa banco mongo, um cache redis, filas usando rabbitmq… tudo isso pode ser simulado usando docker-compose, e se o CI for bem feito ele vai chamar só uma linha de execução (algo como docker-compose run app meuComandoDeTeste
). Só configurar para rodar a cada commit, e em caso de erro é só reproduzir na máquina de dev local.
Minha experiência
Tinhamos dois modulos em um projeto, um em node usando mongo / redis / rabbitmq para API e persistência de dados, um módulo java usando Apache Camel para rotas e integrações (ex: ftp, tcp, rest, etc)
Pontos importantes:
-
Usavamos gitflow como modelo de branch, com configuração no bamboo para efetuar CI a cada commit;
-
Os testes era focado em end to end, isto é, usando docker-compose rodavamos a API "live" (conectando em instancias geradas das dependencias - mongo, redis, etc) e rodava os testes;
-
Builds simultaneos não geravam problema;
-
Testes não eram demorados. Devido ao cache do docker, testes do módulo node demoravam 7 segundos… e tinham vários testes
-
Como nosso environment de prod era misto de cloud e on premise usando heroku e dokku, nunca tivemos surpresas em prod já que nosso CI rodava exatamente o que era executado em prod
Quer saber mais sobre o projeto? Eu falo um pouco sobre ele aqui:
…e um pouco sobre a parte event sourcing aqui:
Próximos Passos / relacionados
Feedbacks
Comentários? Feedbacks? Dicas? Dúvidas? Faltou algo? Algo ficou confuso? Coloca um comentário aí ou manda um email