Dockerfile com Ubuntu: Um Guia Completo do Iniciante ao Avançado para Construir Imagens Docker

目次

1. Introdução

O que são Docker e Dockerfiles?

Nos últimos anos, o Docker ganhou popularidade rapidamente como uma forma eficiente de otimizar ambientes de desenvolvimento e implantação de aplicativos. O Docker empacota aplicativos e suas dependências em uma única unidade chamada de “contêiner”, permitindo que eles sejam executados de forma consistente em diferentes ambientes.

Para construir esses contêineres Docker, é necessário um blueprint chamado Dockerfile. Um Dockerfile é um arquivo de texto que define a imagem do sistema operacional base, o software instalado, variáveis de ambiente e outros detalhes de configuração. Os desenvolvedores podem usá-lo para construir ambientes personalizados automaticamente.

Por que Usar Ubuntu como Imagem Base?

Ao criar um Dockerfile, o primeiro passo é selecionar uma imagem de sistema operacional base. Entre as muitas opções disponíveis, o Ubuntu é uma das mais populares. O Ubuntu é uma distribuição Linux baseada em Debian, conhecida por sua facilidade de uso e configuração de ambiente flexível, suportada por um vasto ecossistema de pacotes.

Dockerfiles baseados em Ubuntu oferecem várias vantagens:

  • Documentação oficial e da comunidade extensa, resultando em uma curva de aprendizado baixa
  • Instalação fácil de pacotes e ferramentas usando APT
  • Imagens leves e mínimas fornecidas oficialmente (como ubuntu:20.04 e ubuntu:24.04 )

Propósito Desta Artigo e Público-Alvo

Este artigo foca na palavra-chave “Dockerfile Ubuntu” e explica como criar Dockerfiles baseados em Ubuntu de uma forma fácil de entender para iniciantes.

Ele abrange tudo, desde a estrutura básica de um Dockerfile até instruções passo a passo para construir um ambiente Ubuntu, exemplos de configuração de ambientes de aplicativos como Python, e erros comuns com suas soluções.

Este artigo é recomendado para:

  • Aqueles que querem construir ambientes usando Dockerfiles pela primeira vez
  • Desenvolvedores que querem criar ambientes de desenvolvimento reproduzíveis no Ubuntu
  • Qualquer pessoa que queira aprofundar seu entendimento, incluindo técnicas de solução de problemas

2. Estrutura Básica de um Dockerfile

O que é um Dockerfile e Qual é Seu Papel?

Um Dockerfile é como uma receita para criar imagens Docker. Ele define qual sistema operacional base usar, qual software instalar e como configurar o ambiente.

Ao executar o comando docker build com base neste arquivo, você pode criar facilmente ambientes de desenvolvimento e execução altamente reproduzíveis.

Benefícios de usar Dockerfiles:

  • Configuração de ambiente automatizada (sem necessidade de repetição manual)
  • Elimina inconsistências de ambiente no desenvolvimento em equipe
  • Integração fácil em pipelines CI/CD

Instruções Comumente Usadas em Dockerfiles

Um Dockerfile consiste em múltiplas instruções (diretivas). As seguintes são algumas das mais comumente usadas. Ao combiná-las adequadamente, você pode construir um Dockerfile baseado em Ubuntu.

InstructionDescription
FROMSpecifies the base Docker image (e.g., FROM ubuntu:24.04)
RUNExecutes shell commands, typically for installing packages
COPYCopies local files into the image
ADDSimilar to COPY, but also supports URLs and archive extraction
WORKDIRSets the working directory
ENVDefines environment variables
CMDDefines the default command executed at container startup (can be overridden)
ENTRYPOINTDefines a command that is always executed at container startup

Exemplo Mínimo de Dockerfile Baseado em Ubuntu

O seguinte é um exemplo muito básico de um Dockerfile usando Ubuntu como imagem base.

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    curl \
    vim

CMD ["/bin/bash"]

Este Dockerfile usa o Ubuntu 24.04 como imagem base, instala as utilidades curl e vim, e inicia um shell Bash quando o contêiner é iniciado.

Selecionando a Tag Apropriada do Ubuntu

As imagens Docker do Ubuntu são publicadas no repositório oficial do Docker Hub. Embora especificar ubuntu:latest use a versão mais recente, é recomendado fixar explicitamente uma versão.

Por exemplo:

  • ubuntu:22.04 (LTS: Long-Term Support, focado em estabilidade)
  • ubuntu:24.04 (Último LTS, focado em recursos mais novos)

Escolha a versão com base em se a estabilidade ou novos recursos são sua prioridade.

3. Prático: Criando um Dockerfile Baseado em Ubuntu

Instalando Pacotes Necessários em um Ambiente Ubuntu

Ao criar um ambiente Ubuntu usando um Dockerfile, costuma ser necessário instalar pacotes adicionais. Por exemplo, as seguintes utilidades são comumente usadas ao configurar um ambiente de desenvolvimento:

  • curl : Para baixar arquivos e testar APIs
  • vim : Um editor de texto leve
  • git : Sistema de controle de versão
  • build-essential : Ferramentas essenciais para compilar programas C/C++

Para instalar esses pacotes em um Dockerfile, use a instrução RUN.

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    curl \
    vim \
    git \
    build-essential

Ao executar apt-get update primeiro, você garante que as listas de pacotes mais recentes sejam obtidas antes da instalação.

Configurando Instalação Não Interativa

No Ubuntu, apt-get install pode às vezes exigir entrada do usuário. Contudo, operações interativas não são possíveis durante builds de Docker. Para evitar isso, recomenda‑se definir uma variável de ambiente e habilitar o modo não interativo.

ENV DEBIAN_FRONTEND=noninteractive

Isso suprime prompts como seleção de locale ou fuso horário e permite que as instalações prossigam sem interrupções.

Reduzindo o Tamanho da Imagem Removendo o Cache Desnecessário

Ao usar o APT, arquivos temporários baixados (cache) podem permanecer na imagem, aumentando seu tamanho final. Você pode reduzir o tamanho da imagem removendo o cache conforme mostrado abaixo:

RUN apt-get update && apt-get install -y \
    curl \
    vim \
    && rm -rf /var/lib/apt/lists/*

Combinar múltiplos comandos em uma única instrução RUN também ajuda a evitar aumentos desnecessários nas camadas da imagem.

Melhores Práticas para Escrever Dockerfiles

Em ambientes de desenvolvimento reais, as seguintes melhores práticas para Dockerfiles são amplamente recomendadas:

  • Combine instruções RUN sempre que possível para reduzir o número de camadas
  • Defina explicitamente versões e configurações usando ENV
  • Use comentários para descrever claramente o propósito de cada passo
  • Evite deixar arquivos desnecessários usando rm e --no-install-recommends

Exemplo:

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    git \
    && rm -rf /var/lib/apt/lists/*

Essa abordagem resulta em um Dockerfile mais leve e mais fácil de manter.

4. Construindo e Verificando Imagens Docker

Construindo uma Imagem Docker a partir de um Dockerfile

Depois que seu Dockerfile estiver pronto, o próximo passo é construir uma imagem Docker. Isso é feito usando o comando docker build. Execute o comando a seguir no diretório que contém seu Dockerfile:

docker build -t my-ubuntu-image .
  • A opção -t atribui um nome (tag) à imagem. Neste exemplo, a imagem recebe o nome my-ubuntu-image.
  • O ponto (.) refere‑se ao diretório atual que contém o Dockerfile.

O Docker lerá as instruções no Dockerfile sequencialmente e construirá a imagem de acordo.

Verificando a Imagem Docker Construída

Após a imagem ter sido construída com sucesso, você pode verificá‑la usando o comando a seguir:

docker images

Isso exibe uma lista de imagens Docker armazenadas localmente, incluindo as seguintes informações:

  • REPOSITORY (nome da imagem)
  • TAG
  • IMAGE ID (identificador único)
  • CREATED (data de criação)
  • SIZE

Exemplo:

REPOSITORY        TAG       IMAGE ID       CREATED          SIZE
my-ubuntu-image   latest    abcd1234abcd   5 minutes ago    189MB

Isso confirma que a imagem foi registrada corretamente.

Executando um Contêiner Docker para Verificação

Para confirmar que a imagem criada funciona como esperado, inicie um contêiner Docker usando o comando a seguir:

docker run -it my-ubuntu-image
  • A opção -it inicia uma sessão de terminal interativa.
  • Se tudo correr bem, aparecerá um prompt Bash, indicando que você está dentro do contêiner Ubuntu.

Dentro do contêiner, você pode verificar as ferramentas instaladas com comandos como:

curl --version
vim --version

Se esses comandos funcionarem corretamente, seu Dockerfile está configurado corretamente.

Limpeza de Imagens e Contêineres Não Utilizados

Compilações e experimentos repetidos podem deixar imagens e contêineres Docker não utilizados no seu sistema. Recomenda-se limpá‑los periodicamente usando os seguintes comandos:

  • Remover contêineres parados:
    docker container prune
    
  • Remover imagens não utilizadas:
    docker image prune
    
  • Remover todos os dados não utilizados (use com cautela):
    docker system prune
    

Essas operações ajudam a economizar espaço em disco e prevenir possíveis problemas.

5. Avançado: Construindo um Ambiente Python

Habilitando Python em um Dockerfile Baseado em Ubuntu

Ao construir um ambiente Ubuntu usando um Dockerfile, adicionar um ambiente de runtime Python permite uma ampla gama de casos de uso, incluindo desenvolvimento, testes e aprendizado de máquina. Embora o Python já possa estar instalado no Ubuntu por padrão, é prática comum configurá‑lo explicitamente para melhor gerenciamento de versões e pacotes.

Instalando Python Usando APT

A abordagem mais simples é instalar o Python usando pacotes APT. Abaixo está um exemplo:

FROM ubuntu:24.04

RUN apt-get update && apt-get install -y \
    python3 \
    python3-pip \
    && rm -rf /var/lib/apt/lists/*

Esse método fornece uma versão estável do Python do sistema (como Python 3.10 ou 3.12, dependendo da versão do Ubuntu). Você também pode instalar pacotes Python adicionais usando o comando pip.

Gerenciando Versões do Python com pyenv

Se você precisar de uma versão específica do Python ou quiser alternar entre várias versões, usar pyenv é altamente recomendado.

O exemplo a seguir mostra como instalar o Python 3.11.6 usando pyenv em um Dockerfile:

FROM ubuntu:24.04

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
    git \
    curl \
    make \
    build-essential \
    libssl-dev \
    zlib1g-dev \
    libbz2-dev \
    libreadline-dev \
    libsqlite3-dev \
    wget \
    llvm \
    libncurses5-dev \
    libncursesw5-dev \
    xz-utils \
    tk-dev \
    libffi-dev \
    liblzma-dev \
    && rm -rf /var/lib/apt/lists/*

# Install pyenv
RUN git clone https://github.com/pyenv/pyenv.git ~/.pyenv

ENV PYENV_ROOT="$HOME/.pyenv"
ENV PATH="$PYENV_ROOT/bin:$PATH"

RUN echo 'eval "$(pyenv init --path)"' >> ~/.bashrc

# Install a specific Python version
RUN pyenv install 3.11.6 && pyenv global 3.11.6

Essa configuração fornece um ambiente Python flexível e bem controlado.

Gerenciando Pacotes com requirements.txt

A maioria dos projetos reais requer múltiplas bibliotecas Python. Essas dependências são comumente gerenciadas usando um arquivo requirements.txt.

Primeiro, crie um arquivo requirements.txt na raiz do seu projeto:

flask==2.3.2
requests>=2.25.1
pandas

Em seguida, faça referência a ele no seu Dockerfile da seguinte forma:

COPY requirements.txt /app/requirements.txt
WORKDIR /app

RUN pip install --no-cache-dir -r requirements.txt

Isso permite que todas as bibliotecas necessárias sejam instaladas de uma vez e melhora significativamente a reproducibilidade do ambiente.

Boas Práticas

  • Ao usar Python, criar um ambiente virtual com virtualenv ou venv ajuda a prevenir conflitos de dependências.
  • Usar opções de supressão de cache como --no-cache-dir reduz o tamanho da imagem Docker.
  • Executar pip install --upgrade pip antes de instalar pacotes pode ajudar a evitar erros de instalação.

6. Problemas Comuns e Solução de Problemas

Erros de Permissão

Exemplo:

Permission denied

Esse erro ocorre quando os arquivos copiados não têm permissões de execução ou quando a propriedade dos arquivos e os usuários de execução estão configurados incorretamente.

Solução:

  • Torne o arquivo executável:
    RUN chmod +x script.sh
    
  • Altere a propriedade do arquivo se necessário:
    RUN chown root:root /path/to/file
    

Pacote Não Encontrado ou Falha na Instalação

Exemplo:

E: Unable to locate package xxx

Este erro geralmente ocorre quando o apt-get update não foi executado ou quando o nome do pacote está incorreto.

Solução:

  • Sempre execute apt-get update antes de instalar pacotes:
    RUN apt-get update && apt-get install -y curl
    
  • Verifique os nomes dos pacotes e procure por erros de digitação

Erros Relacionados à Rede

Exemplo:

Temporary failure resolving 'deb.debian.org'

Este erro indica um problema de resolução de DNS durante o processo de build.

Solução:

  • Reiniciar o daemon do Docker pode resolver o problema:
    sudo systemctl restart docker
    
  • Revise as configurações de DNS do Docker adicionando servidores DNS em /etc/docker/daemon.json :
    {
      "dns": ["8.8.8.8", "8.8.4.4"]
    }
    

Build Usando Cache Desatualizado

O Docker usa cache baseado em camadas para acelerar builds. Como resultado, alterações em um Dockerfile podem não ser refletidas imediatamente.

Solução:

  • Reconstruir sem cache:
    docker build --no-cache -t my-image .
    

O Contêiner Sai Imediatamente ou o Comando de Inicialização Não É Executado

Causas:

  • O comando especificado em CMD ou ENTRYPOINT contém um erro
  • Usar CMD ["/bin/bash"] sem modo interativo causa saída imediata

Solução:

  • Inicie o contêiner em modo de depuração:
    docker run -it my-image /bin/bash
    
  • Entenda as diferenças entre CMD e ENTRYPOINT e use-as adequadamente

Ao encontrar e resolver esses problemas, suas habilidades de design de Dockerfile melhorarão gradualmente. Quando erros ocorrerem, leia atentamente as mensagens de erro e identifique qual instrução e camada causaram o problema.

7. Resumo

Principais Pontos para Criar Dockerfiles Baseados em Ubuntu

Este artigo forneceu uma explicação passo a passo de como construir ambientes Ubuntu usando Dockerfiles, abordando tanto tópicos fundamentais quanto avançados. Vamos revisar os pontos principais:

  • Entender os fundamentos do Dockerfile é o primeiro passo – Instruções como FROM, RUN, CMD e ENV permitem a criação automatizada de ambientes.
  • Ubuntu é uma imagem base estável e flexível – Seu extenso ecossistema de pacotes, grande base de usuários e lançamentos LTS a tornam ideal para ambientes de desenvolvimento.
  • Gerenciamento prático de pacotes permite a instalação das ferramentas e bibliotecas necessárias – O uso correto de apt-get, limpeza de cache e instalação não interativa são essenciais.
  • Construir ambientes práticos, como Python, é totalmente suportado por Dockerfiles – Ferramentas como pyenv, pip e requirements.txt garantem configurações reproduzíveis.
  • Habilidades de solução de problemas impactam diretamente a estabilidade – Compreender permissões, rede e comportamento do cache de build melhora significativamente a produtividade.

Próximos Passos no Aprendizado de Dockerfiles

Depois de se sentir confortável usando Dockerfiles, você pode expandir suas habilidades além do desenvolvimento, para testes e implantações em produção. Considere explorar os seguintes tópicos:

  • Gerenciamento de ambientes multi‑contêiner com Docker Compose
  • Integração com ferramentas de CI/CD como GitHub Actions e GitLab CI
  • Trabalho com plataformas de orquestração de contêineres como Kubernetes

Documentação Oficial e Links de Referência

8. FAQ (Perguntas Frequentes)

Q1. Qual versão do Ubuntu devo escolher em um Dockerfile?

A1. Na maioria dos casos, escolher um lançamento LTS (Long Term Support) é recomendado para estabilidade e manutenção a longo prazo. Versões como ubuntu:22.04 e ubuntu:20.04 são amplamente usadas e suportadas por cinco anos.

Se você precisar dos pacotes mais recentes ou de versões mais novas de linguagens, pode optar por um lançamento mais recente, como ubuntu:24.04, mas testes rigorosos são recomendados.

Q2. Por que o apt-get install relata “pacote não encontrado”?

A2. A razão mais comum é não executar apt-get update antes. Sem atualizar a lista de pacotes, o APT não consegue localizar os pacotes solicitados.

Exemplo correto:

RUN apt-get update && apt-get install -y curl

Também certifique‑se de que os nomes dos pacotes estejam corretos e não estejam obsoletos (por exemplo, use python3 em vez de python).

Q3. Como definir variáveis de ambiente em um Dockerfile?

A3. Use a instrução ENV para definir variáveis de ambiente que ficam disponíveis tanto durante o tempo de construção quanto na execução do contêiner.

Exemplo:

ENV DEBIAN_FRONTEND=noninteractive

Isso é comumente usado para suprimir prompts interativos durante instalações do APT. Variáveis de ambiente também são úteis para configuração de aplicativos e chaves de API.

Q4. Qual é a diferença entre CMD e ENTRYPOINT?

A4. Ambos especificam comandos executados quando um contêiner inicia, mas seu comportamento difere.

ItemCMDENTRYPOINT
OverridableCan be overridden by docker runGenerally not overridden (treated as fixed command)
Use CaseDefine a default commandDefine a command that must always run

Exemplo:

CMD ["python3", "app.py"]
# vs
ENTRYPOINT ["python3"]
CMD ["app.py"]

No último caso, você pode passar argumentos usando docker run my-image another_script.py.

Q5. Por que as alterações no meu Dockerfile não são refletidas?

A5. O Docker usa cache de construção, o que pode fazer com que camadas não alteradas sejam reutilizadas mesmo após editar o Dockerfile.

Solução:

docker build --no-cache -t my-image .

Isso força uma reconstrução completa e garante que todas as alterações sejam aplicadas.