Docker: mau conselho

Docker: mau conselho

Quando eu estava aprendendo a dirigir, logo na primeira aula o instrutor entrou no cruzamento em marcha ré e depois disse que você não deveria fazer isso - nunca. Lembrei-me dessa regra imediatamente e pelo resto da minha vida.

Você lê “Bad Advice”, de Grigory Oster para crianças, e vê como é fácil e natural que elas percebem que não deveriam fazer isso.

Muitos artigos foram escritos sobre como escrever um Dockerfile corretamente. Mas não encontrei instruções sobre como escrever Dockerfiles incorretos. Estou preenchendo essa lacuna. E talvez nos projetos que recebo apoio haja menos dockerfiles desse tipo.

Todos os personagens, situações e Dockerfile são fictícios. Se você se reconhece, desculpe.

Criando um Dockerfile, sinistro e terrível

Peter (desenvolvedor sênior de java/rubby/php): Colega Vasily, você já carregou um novo módulo no Docker?
Vasily (júnior): Não, não tive tempo, não consigo descobrir com esse Docker. Há tantos artigos sobre isso que é vertiginoso.

Peter: Tínhamos um prazo há um ano. Deixe-me ajudá-lo, descobriremos no processo. Diga-me o que não funciona para você.

Vasily: Não consigo escolher uma imagem básica para que seja mínima, mas tenha tudo que você precisa.
Peter: Pegue a imagem do Ubuntu, ela tem tudo que você precisa. E muitas coisas desnecessárias serão úteis mais tarde. E não esqueça de colocar a tag mais recente para que a versão seja sempre a mais recente.

E a primeira linha aparece no Dockerfile:

FROM ubuntu:latest

Peter: O que vem a seguir, o que usamos para escrever nosso módulo?
Vasily: Então, Ruby, existe um servidor web e alguns daemons de serviço devem ser iniciados.
Peter: Sim, do que precisamos: ruby, bundler, nodejs, imagemagick e o que mais... E ao mesmo tempo, fazer uma atualização para obter definitivamente novos pacotes.
Vasily: E não criaremos um usuário para não estarmos no root?
Peter: Foda-se, então você ainda terá que brincar com os direitos.
Vasily: Preciso de tempo, cerca de 15 minutos, para juntar tudo em um comando, eu li isso...
(Peter interrompe rudemente o júnior meticuloso e muito inteligente.)
Peter: Escreva em comandos separados, será mais fácil de ler.

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/*

Então Igor Ivanovich, DevOps (mas mais Ops do que Dev), irrompe no escritório gritando:

AI: Petya, seus desenvolvedores quebraram o banco de dados de alimentos novamente, quando isso vai acabar...

Depois de uma pequena escaramuça, Igor Ivanovich se acalma e começa a descobrir o que seus colegas estão fazendo aqui.

AI: O que você está fazendo?
Vasily: Peter está me ajudando a criar um Dockerfile para um novo módulo.
AI: Deixe-me dar uma olhada... O que você escreveu aqui, você limpa o repositório com um comando separado, esta é uma camada adicional... Mas como você instala dependências se você não copiou o Gemfile! E, em geral, isso não é bom.
Peter: Por favor, cuide da sua vida, vamos descobrir de alguma forma.

Igor Ivanovich suspira tristemente e sai para descobrir quem quebrou o banco de dados.

Peter: Sim, mas ele estava certo sobre o código, precisamos inseri-lo na imagem. E vamos instalar imediatamente o ssh e o supervisor, caso contrário iniciaremos os daemons.

Vasily: Então primeiro copiarei o Gemfile e o Gemfile.lock, depois instalarei tudo e depois copiarei o projeto inteiro. Se o Gemfile não mudar, a camada será retirada do cache.
Peter: Por que vocês estão todos com essas camadas, copiem tudo de uma vez. Copie imediatamente. A primeira linha.

O Dockerfile agora se parece com isto:

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/* 

Pedro: Então, o que vem a seguir? Você tem configurações para o supervisor?
Basílio: Não, não. Mas farei isso rapidamente.
Pedro: Então você fará isso. Vamos agora esboçar um script de inicialização que iniciará tudo. Ok, então você inicia o ssh, com nohup, para que possamos nos conectar ao contêiner e ver o que deu errado. Em seguida, execute o supervisor da mesma maneira. Bem, então você apenas dirige o passageiro.
P: Mas li que deveria haver um processo, para que o Docker saiba que algo deu errado e possa reiniciar o contêiner.
P: Não incomode sua cabeça com bobagens. E em geral, como? Como você executa tudo isso em um processo? Deixe Igor Ivanovich pensar em estabilidade, não é à toa que ele recebe um salário. Nosso trabalho é escrever código. E, em geral, deixe-o agradecer por termos escrito o Dockefile para ele.

10 minutos e dois vídeos sobre gatos depois.

P: Já fiz tudo. Adicionei mais comentários.
P: Mostre-me!

Versão mais recente do Dockerfile:

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

# Устанавливаем bundler
RUN gem install bundler

# Устанавливаем nodejs используется для сборки статики
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/* 

# Запускаем скрипт, при старте контейнера, который запустит все остальное.
CMD [“/app/init.sh”]

P: Ótimo, eu gosto. E os comentários estão em russo, convenientes e legíveis, todos trabalhariam assim. Eu te ensinei tudo, você pode fazer o resto sozinho. Vamos tomar um café...

Bem, agora temos um Dockerfile perfeitamente terrível, cuja visão fará com que Igor Ivanovich queira desistir e seus olhos doerão por mais uma semana. O Dockerfile, claro, poderia ser ainda pior, não há limite para a perfeição. Mas, para começar, isso servirá.

Gostaria de terminar com uma citação de Grigory Oster:

Se você ainda não tem certeza
Escolhemos o caminho da vida,
E você não sabe por que
Comece sua jornada laboral,
Quebre as lâmpadas dos corredores -
As pessoas dirão "obrigado" para você.
Você vai ajudar as pessoas
Economize eletricidade.

Fonte: habr.com

Adicionar um comentário