Guia do Dockerfile: Criando e Gerenciando Imagens

Na nossa introdução ao Docker, exploramos os conceitos fundamentais de imagens, contêineres e Dockerfiles. O Dockerfile, em particular, é a ferramenta que usamos para definir o conteúdo de uma imagem. Como imagens são a base para a execução de contêineres, o Dockerfile se torna um componente crucial na arquitetura de software, especialmente em cenários de microsserviços. Este guia aprofundará o uso do Dockerfile.

A relação entre Dockerfile, imagem e contêiner pode ser visualizada da seguinte forma:

Relação Dockerfile, Imagem e ContêinerO Que é um Dockerfile?

Uma imagem Docker é um sistema de arquivos especial. Ela contém os programas, bibliotecas, recursos e configurações necessários para executar um contêiner, além de metadados como variáveis de ambiente e pontos de montagem de volume. As imagens são imutáveis; seu conteúdo não é alterado após a construção.

Personalizar uma imagem significa modificar ou adicionar camadas ao seu sistema de arquivos. Um Dockerfile atua como um script que automatiza esse processo. Ao encapsular as instruções de construção em um arquivo, resolvemos problemas de repetibilidade, transparência e tamanho das imagens. Qualquer necessidade de customização adicional se resume a editar o Dockerfile e reconsstruir a imagem, eliminando a necessidade de executar comandos manualmente repetidamente.

Estrutura de um Dockerfile

Um Dockerfile é um arquivo de texto contendo uma sequência de instruções. Cada instrução gera uma nova camada na imagem. A estrutura geral segue este padrão:


# Comentário: Este Dockerfile se baseia na imagem alpine
# VERSÃO 1.0
# Autor: Seu Nome

# 1. Instrução BASE: Define a imagem base
FROM alpine:latest

# 2. Metadados do Mantenedor
LABEL maintainer="Seu Nome <seu.email>"

# 3. Instruções de Construção
# Atualiza o índice de pacotes e instala o pacote 'curl'
RUN apk update && apk add --no-cache curl

# Copia um arquivo de configuração para o contêiner
COPY custom-config.conf /etc/app/config.conf

# 4. Instrução de Comando de Execução
# Define o comando a ser executado quando um contêiner for iniciado a partir desta imagem
CMD ["/bin/sh", "-c", "echo 'Aplicação iniciada!' && cat /etc/app/config.conf"]
 </seu.email>

Um Dockerfile é tipicamente composto por quatro seções principais: a imagem base (FROM), metadados (LABEL ou MAINTAINER), instruções de construção (RUN, COPY, ADD, etc.) e a instrução de comando de execução (CMD ou ENTRYPOINT).

Construindo Imagens com Docker

O comando docker build utiliza um Dockerfile e um "contexto de build" para criar novas imagens. O contexto de build é o conjunto de arquivos e diretórios localizados no caminho especificado ou em um URL (como um repositório Git). Este contexto é enviado ao daemon Docker para a construção.

Para construir uma imagem usando o Dockerfile no diretório atual como contexto:


docker build .
# Exemplo de saída:
# Sending build context to Docker daemon  3.072kB
# ...
 

É recomendável usar um diretório dedicado para o build, contendo apenas os arquivos necessários. O arquivo .dockerignore pode ser usado para excluir arquivos e diretórios do contexto de build, otimizando o envio para o daemon.

O Dockerfile geralmente reside na raiz do contexto de build. Caso contrário, sua localização pode ser especificada com a flag -f:


docker build -f ./caminho/para/Dockerfile .
 

As flags -t permitem nomear e marcar a imagem resultante:


docker build -t minha-app/webserver:v1.0 .
 

Para múltiplos nomes e tags:


docker build -t minha-app/webserver:v1.0 -t minha-app/webserver:latest .
 

Se houver erros de sintaxe no Dockerfile, o processo de build retornará um erro:


docker build -t minha-app/webserver:v1.0 .
# Exemplo de erro:
# Error response from daemon: Unknown instruction: RUNCMD
 

Cache de Build

O daemon Docker executa as instruções do Dockerfile sequencialmente, criando uma nova camada (e um novo ID de imagem intermediária) para cada instrução bem-sucedida. O Docker utiliza um cache para acelerar builds subsequentes. Se uma instrução e seus argumentos não mudaram desde o último build, o Docker reutilizará a camada de imagem existente em vez de reexecutar a instrução.


# Exemplo de build utilizando cache:
$ docker build -t meu-app .
Sending build context to Docker daemon  20.48kB
Step 1/4 : FROM alpine:latest
---> abc123def456
Step 2/4 : RUN apk update && apk add --no-cache curl
---> Using cache
---> fedcba987654
Step 3/4 : COPY custom-config.conf /etc/app/config.conf
---> Using cache
---> 1a2b3c4d5e6f
Step 4/4 : CMD ["/bin/sh", "-c", "echo 'Aplicação iniciada!' && cat /etc/app/config.conf"]
---> Using cache
---> 6f5e4d3c2b1a
Successfully built 6f5e4d3c2b1a
 

O cache de build é local. Para usar um cache de um repositório remoto, pode-se usar a flag --cache-from.

Lógica de Busca de Cache

O Docker busca cache perocrrendo a estrutura de instruções do Dockerfile. A maioria das instruções (como RUN, FROM) são verificadas pelo seu conteúdo ou comando. No entanto, instruções como ADD e COPY consideram não apenas o nome do arquivo, mas também o checksum do conteúdo do arquivo. Se o conteúdo de um arquivo copiado ou adicionado mudar, o cache para essa instrução e as subsequentes será invalidado.

Instruções como RUN apt-get update podem usar cache mesmo que o conteúdo dos repositórios tenha mudado, pois o Docker compara apenas o comando em si. Se o cache para uma instrução não for ancontrado, uma nova imagem será construída, e as instruções seguintes não tentarão usar cache.

Exemplo Simples: Criando uma Imagem Nginx Customizada

Vamos criar uma imagem Nginx que serve uma página HTML personalizada.

  1. Crie um diretório para o projeto e entre nele: ```

    mkdir meu-nginx cd meu-nginx

  2. Crie um arquivo chamado Dockerfile com o seguinte conteúdo: ```

    Usa a imagem oficial do Nginx como base

    FROM nginx:alpine

    Cria um arquivo HTML simples personalizado

    RUN echo 'Bem-vindo ao meu Nginx customizado!' > /usr/share/nginx/html/index.html

    Expõe a porta padrão do Nginx

    EXPOSE 80

  3. Construa a imagem: ```

    docker build -t meu-nginx-custom:v1 .

  4. Verifique se a imagem foi criada: ```

    docker images

    Espera-se ver algo como:

    REPOSITORY TAG IMAGE ID CREATED SIZE

    meu-nginx-custom v1 abcdef123456 2 minutes ago 123MB

  5. Inicie um contêiner a partir da imagem: ```

    docker run --name webserver-custom -d -p 8080:80 meu-nginx-custom:v1

    
    Agora, acesse `http://localhost:8080` no seu navegador. Você deverá ver a mensagem "Bem-vindo ao meu Nginx customizado!".
    
    

Modificando Conteúdo de um Contêiner em Execução

É possível entrar em um contêiner em execução para fazer modificações manuais. Use docker exec para isso.


# Entra no contêiner em execução e abre um shell bash
docker exec -it webserver-custom bash

# Dentro do contêiner, modifique o arquivo HTML
root@abcdef123456:/# echo '<h1>Atualização na página!</h1>' > /usr/share/nginx/html/index.html
root@abcdef123456:/# exit
exit
 

Após sair do contêiner e recarregar a página no navegador, a alteração será visível. Para ver as modificações feitas no sistema de arquivos do contêiner, utilize docker diff:


docker diff webserver-custom
# Isso listará os arquivos modificados, adicionados ou excluídos.
 

Este guia cobriu os fundamentos do Dockerfile. Instruções mais avançadas e opções de configuração serão abordadas em futuras discussões.

Tags: Docker Dockerfile Imagens Docker construção de imagens cache docker

Publicado em 9-15 06:36