
Quando eu aprendi a dirigir, na primeira aula, o instrutor entrou na intersection de marcha ré e depois disse que fazer isso nunca é permitido. Essa regra eu memorize imediatamente e para a vida toda.
Você lê para as crianças "Conselhos Nocivos" de Grigori Oster e vê como é fácil e natural para elas entenderem que não se deve fazer isso.
Sobre como escrever um Dockerfile corretamente, foram escritas muitas matérias. Mas não encontrei instruções sobre como escrever Dockerfiles incorretos. Estou preenchendo essa lacuna. E, talvez, nos projetos que recebo para suporte, esse tipo de Dockerfile talvez diminua.
Todos os heróis, situações e Dockerfiles são fictícios. Se você se reconheceu, desculpe.
Criando um Dockerfile, sinistro e aterrorizante
Petr (Desenvolvedor sênior java/ruby/php): Colega Vasily, você já carregou o novo módulo no Docker?
Vasily (junior): Não, não consegui, não consigo entender esse Docker. Tantas matérias sobre ele, meus olhos ficam confusos.
Petr: O nosso prazo expirou há um ano. Vamos, eu ajudo, vamos entender durante o processo. Fala o que você não conseguiu.
Vasily: Não consigo escolher a imagem base, que seja mínima, mas tenha tudo o que preciso.
Petr: Pegue a imagem ubuntu, nela tem tudo o que você precisa. E o que for demais, depois ainda vai ser útil. E não se esqueça de colocar a tag latest para ter sempre a versão mais atual.
E no Dockerfile aparece a primeira linha:
FROM ubuntu:latestPetr: O que vem depois, em que nós escrevemos nosso módulo?
Vasily: Então é ruby, deve haver um servidor web e alguns demons de serviço rodando.
Petr: Certo, o que nós precisamos: ruby, bundler, nodejs, imagemagick, e o que mais ... E aproveita, faz o upgrade para ter certeza de que vai obter os novos pacotes.
Vasily: E não vamos criar um usuário para não rodar sob root?
Petr: Ah, deixa pra lá, depois vamos ter que lidar com permissões.
Vasily: Eu preciso de tempo, uns 15 minutos, para juntar tudo isso em um único comando, eu li que ...
(Petr interrompe bruscamente o detalhista e super inteligente júnior.)
Petr: Escreva em comandos separados, assim vai ser mais fácil de ler.
O Dockerfile cresce:
FROM ubuntu:latest
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full
RUN gem install bundler
RUN curl -sL https://deb.nodesource.com/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
RUN bundle install --without development test --path vendor/bundle
RUN rm -rf /usr/local/bundle/cache/*.gem
RUN apt-get clean
RUN rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*Nesse momento, Igor Ivanovich, DevOps (mas mais Ops do que Dev), entra na sala gritando:
II: Petya, seus desenvolvedores quebraram o banco de dados de produção novamente, quando isso vai acabar….
Após uma leve discussão, Igor Ivanovich se acalma e começa a perguntar o que os colegas estão fazendo.
IA: O que vocês estão fazendo?
Vasiliy: Petr está me ajudando a criar um Dockerfile para um novo módulo.
IA: Deixe-me ver... O que vocês escreveram aqui? Vocês estão limpando o repositório com um comando separado, isso é uma camada adicional... Como vocês estão instalando as dependências se não copiaram o Gemfile! E, no geral, isso não vale nada.
Petr: Por favor, você pode ir cuidar dos seus assuntos? Nós vamos nos entender aqui.
Igor Ivanovich suspira melancolicamente e sai para descobrir quem quebrou o banco de dados.
Petr: Sim, mas ele está certo sobre o código, precisamos incluí-lo na imagem. E vamos instalar ssh e supervisor logo, ou como vamos executar os demons?
Vasiliy: Vou primeiro copiar o Gemfile e o Gemfile.lock, depois vou instalar tudo e, em seguida, copiar todo o projeto. Se o Gemfile não mudar, a camada será retirada do cache.
Petr: O que vocês têm com essas camadas? Copie tudo de uma vez. Copie tudo. Na primeira linha.
O Dockerfile agora está assim:
FROM ubuntu:latest
COPY .\/ \/app
WORKDIR \/app
RUN apt-get update
RUN apt-get upgrade
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
RUN gem install bundler
RUN curl -sL https:\/\/deb.nodesource.com\/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
RUN bundle install --without development test --path vendor\/bundle
RUN rm -rf \/usr\/local\/bundle\/cache\/*.gem
RUN apt-get clean
RUN rm -rf \/var\/lib\/apt\/lists\/* \/tmp\/* \/var\/tmp\/* Petr: Então, o que vem a seguir? Você tem as configurações para o supervisor?
Vasiliy: Não, não tenho. Mas eu farei rapidamente.
Petr: Faça isso depois. Vamos agora rascunhar um script init que vai iniciar tudo. Então, você inicia o ssh com nohup, para que possamos nos conectar ao contêiner e ver o que deu errado. Depois, inicie o supervisor da mesma forma. E então, você apenas iniciará o passenger.
V: Mas eu li que deve haver um processo só, assim o Docker saberá que algo deu errado e poderá reiniciar o contêiner.
P: Não se preocupe com bobagens. E como? Como você vai executar tudo isso em um processo só? Deixe a estabilidade para Igor Ivanovich pensar, ele ganha o salário por isso. Nossa tarefa é escrever o código. E, no geral, que ele agradeça que escrevemos o Dockerfile por ele.
Depois de 10 minutos e dois vídeos de gatinhos.
V: Eu terminei tudo. Adicionei mais alguns comentários.
P: Mostre!
A nova versão do Dockerfile:
DE FROM ubuntu:latest
# Copiando o código fonte
COPY .\/ \/app
WORKDIR \/app
# Atualizando a lista de pacotes
RUN apt-get update
# Atualizando pacotes
RUN apt-get upgrade
# Instalando pacotes necessários
RUN apt-get -y install libpq-dev imagemagick gsfonts ruby-full ssh supervisor
# Instalando o bundler
RUN gem install bundler
# Instalando nodejs usado para construir o front-end
RUN curl -sL https:\/\/deb.nodesource.com\/setup_9.x | sudo bash -
RUN apt-get install -y nodejs
# Instalando dependências
RUN bundle install --without development test --path vendor\/bundle
# Limpando caches
RUN rm -rf \/usr\/local\/bundle\/cache\/*.gem
RUN apt-get clean
RUN rm -rf \/var\/lib\/apt\/lists\/* \/tmp\/* \/var\/tmp\/*
# Executando o script na inicialização do contêiner que iniciará tudo o mais.
CMD [“\/app\/init.sh”]P: Ótimo, eu gostei. E os comentários em russo, práticos e legíveis, todos deveriam trabalhar assim. Eu te ensinei tudo, a partir daqui você consegue sozinho. Vamos tomar um café…
Então, aqui está o Dockerfile horrivelmente perfeito, ao qual Igor Ivanovich vai querer pedir demissão e que vai deixar seus olhos doendo por uma semana. O Dockerfile, claro, poderia ser ainda pior, não há limites para a perfeição. Mas por enquanto, assim está bom.
Gostaria de terminar com uma citação de Grigory Oster:
Se você ainda não decidiu
O caminho a seguir na vida,
E não sabe por onde
Começar seu caminho de trabalho,
Quebre lâmpadas nos corredores —
As pessoas dirão 'Obrigado' a você.
Você ajudará o povo
A economizar eletricidade.
Fonte: habr.com
