Docker de aprendizagem, parte 3: arquivos do Dockerfile

Na tradução da terceira parte da série Docker, continuaremos a ser inspirados por doces, ou seja, bagels. Nosso principal tópico hoje estará trabalhando com Dockerfiles. Analisaremos as instruções usadas nesses arquivos.

Parte 1: o básico
Parte 2: termos e conceitos
Parte 3: arquivos Dockerfile
Parte 4: reduzindo o tamanho das imagens e acelerando sua montagem
Parte 5: equipes
Parte 6: trabalhando com dados


Bagels são instruções em um Dockerfile.

Imagens do Docker


Lembre-se de que um contêiner do Docker é uma imagem do Docker criada. Este é um sistema operacional independente no qual existe apenas o código de aplicativo e mais necessário.

Imagens do Docker são o resultado do processo de criação e os contêineres do Docker estão executando imagens. No coração do Docker estão os Dockerfiles. Arquivos como este informam ao Docker como montar as imagens a partir das quais os contêineres são criados.

Cada imagem do Docker possui um arquivo chamado Dockerfile. Seu nome está escrito assim - sem extensão. Quando você executa o docker build para criar uma nova imagem, supõe-se que o Dockerfile esteja no diretório de trabalho atual. Se esse arquivo estiver localizado em outro local, sua localização poderá ser especificada usando o sinalizador -f .

Os contêineres, como descobrimos no primeiro material desta série, consistem em camadas. Cada camada, exceto a última, localizada em cima de todas as outras, é somente leitura. O Dockerfile informa ao sistema Docker quais camadas e em que ordem adicionar à imagem.

Cada camada, de fato, é apenas um arquivo que descreve a alteração no estado da imagem em comparação com o estado em que estava após adicionar a camada anterior. No Unix, a propósito, quase tudo é um arquivo .

Uma imagem básica é o que é a camada de origem (ou camadas) da imagem que está sendo criada. A imagem base também é chamada de imagem pai.


A imagem básica é onde a imagem do Docker começa.

Quando uma imagem é baixada de um repositório remoto para um computador local, apenas as camadas que não estão disponíveis neste computador são baixadas fisicamente. O Docker visa economizar espaço e tempo reutilizando as camadas existentes.

Arquivos Dockerfile


Os arquivos de encaixe contêm instruções para criar uma imagem. Em letras maiúsculas, as linhas deste arquivo começam. Seguindo as instruções estão seus argumentos. As instruções, ao criar a imagem, são processadas de cima para baixo. Aqui está o que parece:

 FROM ubuntu:18.04 COPY . /app 

As camadas na imagem final são criadas apenas pelas instruções FROM , RUN , COPY e ADD . Outras instruções configuram algo, descrevem metadados ou informam ao Docker que você precisa fazer algo durante a execução do contêiner, por exemplo, abrir alguma porta ou executar algum comando.

Aqui partimos da suposição de que uma imagem do Docker baseada em um sistema operacional tipo Unix é usada. Obviamente, aqui você também pode usar uma imagem baseada no Windows, mas usar o Windows é uma prática menos comum, trabalhar com essas imagens é mais difícil. Como resultado, se você tiver a oportunidade, use o Unix.

Para começar, aqui está uma lista de instruções do Dockerfile com breves comentários.

Dúzia Dockerfile Instruções


  1. FROM - define a imagem base (principal).
  2. LABEL - descreve metadados. Por exemplo, informações sobre quem criou e mantém a imagem.
  3. ENV - define variáveis ​​de ambiente persistentes.
  4. RUN - executa um comando e cria uma camada de imagem. Usado para instalar pacotes em um contêiner.
  5. COPY - copia arquivos e pastas para o contêiner.
  6. ADD - copia arquivos e pastas para um contêiner, pode descompactar arquivos .tar locais.
  7. CMD - descreve um comando com argumentos que precisam ser executados quando o contêiner é iniciado. Os argumentos podem ser substituídos quando o contêiner é iniciado. Um arquivo pode conter apenas uma instrução CMD .
  8. WORKDIR - define o diretório de trabalho para a próxima instrução.
  9. ARG - define variáveis ​​para passar o Docker durante a criação da imagem.
  10. ENTRYPOINT - fornece um comando com argumentos para chamar durante a execução do contêiner. Argumentos não são substituídos.
  11. EXPOSE - indica a necessidade de abrir a porta.
  12. VOLUME - cria um ponto de montagem para trabalhar com armazenamento persistente.

Agora vamos falar sobre essas instruções.

Instruções e exemplos de uso


▍Dockerfile simples


O Dockerfile pode ser extremamente simples e curto. Por exemplo - assim:

 FROM ubuntu:18.04 

RomDe instruções


O Dockerfile deve começar com uma instrução FROM ou com uma instrução ARG seguida por uma instrução FROM .

A palavra-chave FROM diz ao Docker para usar uma imagem base que corresponda ao nome e à tag fornecidos ao criar a imagem. Além disso, a imagem básica também é chamada de imagem pai .

Neste exemplo, a imagem base é armazenada no repositório do ubuntu . Ubuntu é o nome do repositório oficial do Docker, que fornece a versão base da popular família de sistemas operacionais Linux chamada Ubuntu.

Observe que o Dockerfile em questão inclui uma marca 18.04 que especifica qual imagem base precisamos. É essa imagem que será carregada ao criar nossa imagem. Se a tag não estiver incluída na instrução, o Docker continuará assumindo que a imagem mais recente do repositório é necessária. Para expressar mais claramente suas intenções, é recomendável que o autor do Dockerfile indique qual imagem ele precisa.

Quando o Dockerfile acima é usado na máquina local para criar a imagem pela primeira vez, o Docker carrega as camadas definidas pela imagem do ubuntu . Eles podem ser imaginados sobrepostos um ao outro. Cada camada seguinte é um arquivo que descreve as diferenças da imagem em comparação com o estado em que estava após adicionar a camada anterior.

Quando você cria um contêiner, uma camada na qual você pode fazer alterações é adicionada sobre todas as outras camadas. Os dados nas camadas restantes só podem ser lidos.


Estrutura de contêiner (retirada da documentação )

O Docker, por uma questão de eficiência, usa uma estratégia de copiar na gravação. Se a camada da imagem existir no nível anterior e alguma camada precisar ler dados dela, o Docker usará o arquivo existente. Você não precisa baixar nada.

Quando a imagem é executada, se a camada precisar ser modificada por meio do contêiner, o arquivo correspondente será copiado para a camada superior mutável. Para saber mais sobre a estratégia de copiar na gravação, consulte este material na documentação do Docker.

Continuamos a discussão das instruções usadas no Dockerfile, fornecendo um exemplo de um arquivo com uma estrutura mais complexa.

Arquivo docker mais sofisticado


Embora o arquivo Docker que acabamos de revisar tenha sido limpo e compreensível, é muito simples, ele usa apenas uma instrução. Além disso, não há instruções chamadas durante a execução do contêiner. Dê uma olhada em outro arquivo que coleta uma imagem pequena. Possui mecanismos que determinam os comandos que são chamados durante a execução do contêiner.

 FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" ENV ADMIN="jeff" RUN apk update && apk upgrade && apk add bash COPY . ./app ADD https://raw.githubusercontent.com/discdiver/pachy-vid/master/sample_vids/vid1.mp4 \ /my_app_directory RUN ["mkdir", "/a_directory"] CMD ["python", "./my_script.py"] 

Talvez, à primeira vista, esse arquivo possa parecer bastante complicado. Portanto, vamos lidar com ele.

A base desta imagem é a imagem oficial do Python com a tag 3.7.2-alpine3.8. Após analisar esse código, você pode ver que essa imagem básica inclui Linux, Python e, em geral, isso é limitado à sua composição. As imagens do sistema operacional Alpine são muito populares no mundo do Docker. O fato de serem pequenos em tamanho, alta velocidade e segurança. No entanto, as imagens alpinas não diferem nos amplos recursos típicos dos sistemas operacionais convencionais. Portanto, para coletar algo útil com base nessa imagem, o criador da imagem precisa instalar os pacotes de que precisa.

▍Instrução LABEL



Tags

A instrução LABEL (etiqueta) permite adicionar metadados à imagem. No caso do arquivo em consideração agora, ele inclui as informações de contato do criador da imagem. Declarar etiquetas não atrasa o processo de montagem da imagem nem aumenta seu tamanho. Eles contêm apenas informações úteis sobre a imagem do Docker, portanto, é recomendável que eles sejam incluídos no arquivo. Detalhes sobre como trabalhar com metadados no Dockerfile podem ser encontrados aqui .

InstructionInv instrução



Meio ambiente

A instrução ENV permite definir variáveis ​​de ambiente constantes que estarão disponíveis no contêiner durante sua execução. No exemplo anterior, depois de criar o contêiner, você pode usar a variável ADMIN .

A instrução ENV é adequada para definir constantes. Se você usar um determinado valor no Dockerfile várias vezes, por exemplo, ao descrever os comandos que são executados no contêiner, e suspeitar que algum dia precise alterá-lo para outro, faz sentido escrevê-lo em uma constante semelhante.

Note-se que nos arquivos do Dockerfile geralmente existem maneiras diferentes de resolver os mesmos problemas. O que exatamente usar é uma pergunta cuja decisão é influenciada pelo desejo de cumprir os métodos de trabalho adotados no ambiente do Docker, para garantir a transparência da solução e seu alto desempenho. Por exemplo, as ENTRYPOINT RUN , CMD e ENTRYPOINT servem a propósitos diferentes, mas todas são usadas para executar comandos.

Instrução UNRUN



Instrução RUN

A instrução RUN permite criar uma camada durante a criação da imagem. Após sua execução, uma nova camada é adicionada à imagem, seu estado é fixo. A instrução RUN é frequentemente usada para instalar pacotes adicionais em imagens. No exemplo anterior, a instrução RUN apk update && apk upgrade informa ao Docker que o sistema precisa atualizar pacotes a partir da imagem base. Após esses dois comandos, está o comando && apk add bash , indicando que o bash precisa ser instalado na imagem.

O que parece ser apk em equipes é uma abreviação de Alpine Linux package manager . Se você estiver usando a imagem base de outro sistema operacional da família Linux, por exemplo, ao usar o Ubuntu, pode ser necessário um comando no formato RUN apt-get para instalar pacotes. Mais tarde, falaremos sobre outras maneiras de instalar pacotes.

A instrução RUN e instruções semelhantes, como CMD e ENTRYPOINT , podem ser usadas no formato exec ou no formato shell. O formulário exec usa uma sintaxe semelhante à descrição de uma matriz JSON. Por exemplo, pode ser assim: RUN ["my_executable", "my_first_param1", "my_second_param2"] .

No exemplo anterior, usamos a forma de shell da instrução RUN da seguinte maneira: RUN apk update && apk upgrade && apk add bash .

Posteriormente em nosso Dockerfile, usamos a forma exec da instrução RUN , na forma de RUN ["mkdir", "/a_directory"] para criar um diretório. Ao mesmo tempo, usando as instruções neste formulário, é necessário lembrar a necessidade de formatar cadeias de caracteres com aspas duplas, como é habitual no formato JSON.

▍Instrução CÓPIA



Instrução COPY

A instrução COPY é apresentada em nosso arquivo assim: COPY . ./app COPY . ./app . Ela diz ao Docker que precisa pegar arquivos e pastas do contexto local da montagem e adicioná-los ao diretório de trabalho atual da imagem. Se o diretório de destino não existir, esta instrução o criará.

▍Instrução ADICIONAR


A instrução ADD permite resolver os mesmos problemas que COPY , mas mais alguns COPY uso estão associados a ela. Portanto, usando esta instrução, você pode adicionar arquivos baixados de fontes remotas ao contêiner, além de descompactar arquivos .tar locais.

Neste exemplo, a instrução ADD foi usada para copiar um arquivo acessível por URL para o my_app_directory contêiner my_app_directory . Note-se, no entanto, que a documentação do Docker não recomenda o uso desses arquivos obtidos pela URL, pois eles não podem ser excluídos e aumentam o tamanho da imagem.

Além disso, a documentação sugere, sempre que possível, que você use a instrução COPY vez da instrução ADD para facilitar a compreensão do Dockerfile. Acredito que a equipe de desenvolvimento do Docker deve combinar ADD e COPY em uma instrução para que aqueles que criam as imagens não precisem se lembrar de muitas instruções.

Observe que a instrução ADD contém o caractere de quebra de linha - \ . Esses caracteres são usados ​​para melhorar a legibilidade de comandos longos, dividindo-os em várias linhas.

Instruction instrução CMD



Instrução CMD

A instrução CMD fornece ao Docker um comando para executar quando o contêiner for iniciado. Os resultados deste comando não são adicionados à imagem durante sua montagem. Em nosso exemplo, este comando inicia o script my_script.py em tempo de execução.

Aqui está outra coisa que você precisa saber sobre a instrução CMD :

  • Somente uma instrução CMD pode estar presente em um Dockerfile. Se houver várias instruções no arquivo, o sistema ignorará tudo, exceto a última.
  • Uma instrução CMD pode ter um formulário exec. Se a instrução não incluir a referência ao arquivo executável, a instrução ENTRYPOINT deverá estar presente no arquivo. Nesse caso, essas duas instruções devem estar no JSON .
  • Os argumentos da linha de comando transmitidos para a docker run substituem os argumentos fornecidos pela instrução CMD no Dockerfile.

DUm Dockerfile ainda mais complexo


Considere outro Dockerfile, no qual alguns novos comandos serão usados.

 FROM python:3.7.2-alpine3.8 LABEL maintainer="jeffmshale@gmail.com" #   RUN apk add --update git #     WORKDIR /usr/src/my_app_directory #          COPY . . #       ARG my_var=my_default_value #  ,           ENTRYPOINT ["python", "./app/my_script.py", "my_var"] #   EXPOSE 8000 #      VOLUME /my_volume 

Neste exemplo, entre outras coisas, você pode ver comentários que começam com o caractere # .
Uma das principais coisas que o Dockerfile faz é instalar pacotes. Como já mencionado, existem várias maneiras de instalar pacotes usando a instrução RUN .

Os pacotes na imagem do Alpine Docker podem ser instalados usando o apk . Para isso, como já dissemos, RUN apk update && apk upgrade && apk add bash um comando do formulário RUN apk update && apk upgrade && apk add bash .

Além disso, os pacotes Python na imagem podem ser instalados usando pip , wheel e conda . Se não estamos falando sobre Python, mas sobre outras linguagens de programação, outros gerenciadores de pacotes podem ser usados ​​para preparar as imagens correspondentes.

Ao mesmo tempo, para que a instalação seja possível, a camada subjacente deve fornecer ao gerenciador de pacotes um gerenciador de pacotes adequado. Portanto, se você encontrar problemas para instalar pacotes, verifique se o gerenciador de pacotes está instalado antes de tentar usá-lo.

Por exemplo, você pode usar a instrução RUN em um Dockerfile para instalar uma lista de pacotes usando o pip . Se você fizer isso, combine todos os comandos em uma instrução e separe-os com caracteres de quebra de linha usando o caractere \ . Graças a essa abordagem, os arquivos ficarão bem arrumados e isso levará à adição de menos camadas à imagem do que seria adicionado usando várias instruções RUN .

Além disso, você pode fazer coisas diferentes para instalar vários pacotes. Você pode listá-los em um arquivo e transferi-lo para o gerenciador de pacotes usando RUN . Normalmente, esses arquivos são chamados requirements.txt .

▍ Instrução WORDDIR



Diretórios de trabalho

A instrução WORKDIR permite alterar o diretório de trabalho do contêiner. As ENTRYPOINT COPY , ADD , RUN , CMD e ENTRYPOINT que seguem WORKDIR funcionam com este diretório. Aqui estão alguns recursos relacionados a esta instrução:

  • É melhor definir caminhos absolutos para pastas com WORKDIR vez de navegar no sistema de arquivos usando os comandos cd no Dockerfile.
  • A instrução WORKDIR cria automaticamente um diretório se ele não existir.
  • Você pode usar várias instruções do WORKDIR . Se forem fornecidas instruções relativas a essas instruções, cada uma delas mudará o diretório de trabalho atual.

▍Guia ARG


A instrução ARG permite definir uma variável cujo valor pode ser passado da linha de comando para a imagem durante sua montagem. O valor da variável padrão pode ser representado no Dockerfile. Por exemplo: ARG my_var=my_default_value .

Diferente das variáveis ENV , as variáveis ARG não estão disponíveis no tempo de execução. No entanto, as variáveis ARG podem ser usadas para definir valores padrão para variáveis ENV na linha de comando durante a criação da imagem. E as variáveis ENV já estarão disponíveis no contêiner durante sua execução. Detalhes sobre essa técnica de trabalhar com variáveis ​​podem ser encontrados aqui .

▍Instrução ENTRYPOINT



Ponto de transição para algum lugar

A instrução ENTRYPOINT permite especificar um comando com argumentos que devem ser executados quando o contêiner for iniciado. É semelhante ao comando CMD , mas os parâmetros especificados em ENTRYPOINT não serão substituídos se o contêiner for iniciado com parâmetros de linha de comando.

Em vez disso, os argumentos da linha de comando passados ​​nas construções da docker run my_image_name formulário docker run my_image_name são adicionados aos argumentos especificados pela ENTRYPOINT . Por exemplo, depois de executar um comando da docker run my_image bash formulários e docker run my_image bash argumento docker run my_image bash será adicionado ao final da lista de argumentos especificados por ENTRYPOINT . Ao preparar o Dockerfile, não esqueça as ENTRYPOINT CMD ou ENTRYPOINT .

Existem várias recomendações na documentação do Docker sobre quais instruções, CMD ou ENTRYPOINT , devem ser escolhidas como uma ferramenta para executar comandos quando o contêiner é iniciado:

  • Se você precisar executar o mesmo comando sempre que iniciar o contêiner, use ENTRYPOINT .
  • Se o contêiner for usado como um aplicativo, use ENTRYPOINT .
  • Se você souber que, ao iniciar o contêiner, precisará passar argumentos que possam substituir os argumentos especificados no Dockerfile, use o CMD .

Em nosso exemplo, o uso da instrução ENTRYPOINT ["python", "my_script.py", "my_var"] faz com que o contêiner, quando iniciado, execute o script Python my_script.py com o argumento my_var . O valor representado por my_var pode ser usado no script usando argparse . , Dockerfile my_var , , ARG . , , .

Docker exec- ENTRYPOINT : ENTRYPOINT ["executable", "param1", "param2"] .

▍ EXPOSE



EXPOSE

EXPOSE , , . . , , , , , , .

( ) , docker run -p . -P ( P ), , EXPOSE .

▍ VOLUME



VOLUME

VOLUME , . .

Sumário


, Dockerfile. . , , USER , ONBUILD , STOPSIGNAL , SHELL HEALTHCHECK . Dockerfile.

, Dockerfile — Docker, , . , .

Caros leitores! Docker , , Docker-.

Source: https://habr.com/ru/post/pt439980/


All Articles