image

Access unlimited bootcamps and 650+ courses

50
%OFF
Article image
Leonardo Augusto
Leonardo Augusto15/02/2025 23:51
Share

Reduzindo o Tamanho das Imagens no Python (Docker)

  • #Docker
  • #Python

Exemplo de configuração para uma aplicação web Python utilizando o framework FastAPI e o gerenciador de dependências Poetry:

FROM python:3.10-slim

ENV PYTHONUNBUFFERED=1
ENV PATH="/root/.local/bin:$PATH"
ENV PYTHONPATH="/"

RUN apt-get update && apt-get install -y curl gcc python3-dev libpq-dev && apt-get clean
RUN curl -sSL https://install.python-poetry.org | python3 - --yes
RUN poetry --version
RUN poetry config virtualenvs.create false

COPY pyproject.toml poetry.lock /

RUN poetry install --no-root
RUN poetry add gunicorn
RUN apt-get remove -y curl && apt-get autoremove -y && apt-get clean
RUN mkdir -p /app/migrations/versions && chmod -R 777 /app/migrations/versions

COPY . .

WORKDIR /app
EXPOSE 8000

CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000"]

imageEsse Dockerfile acima consome mais armazenamento por alguns motivos principais:

  1. Camadas Desnecessárias
  2. Cada RUN cria uma nova camada na imagem, aumentando o tamanho total.
  3. Dependências Excedentes
  4. Instalar gccpython3-dev e libpq-dev é necessário para compilar certas bibliotecas, mas esses pacotes não são mais usados depois da instalação do Poetry e das dependências. Eles ocupam bastante espaço e poderiam ser removidos após a instalação dos pacotes Python.
  5. Instalação do Gunicorn Separada
  6. gunicorn está sendo instalado separadamente com poetry add gunicorn. O ideal seria adicioná-lo diretamente no pyproject.toml para evitar mais uma camada extra.
  7. Arquivos do Poetry Mantidos
  8. Ao rodar poetry install --no-root, o Poetry pode baixar e armazenar pacotes temporários que permanecem na imagem. O cache de pacotes do Poetry não está sendo limpo, o que pode deixar arquivos desnecessários na imagem.
  9. Ordem Ineficiente de COPY
  10. O comando COPY . . copia tudo para a imagem, incluindo arquivos que podem não ser necessários. Como pyproject.toml e poetry.lock são copiados antes, se qualquer outro arquivo da aplicação mudar, o Docker invalidará o cache, forçando uma reinstalação completa dos pacotes Python.

Abordagens para Reduzir o Tamanho da Imagem

Dockerfile otimizado para reduzir o tamanho da imagem:

FROM python:3.10-slim

ENV PYTHONUNBUFFERED=1 \
  PATH="/root/.local/bin:$PATH" \
  PYTHONPATH="/"

WORKDIR /app

COPY pyproject.toml poetry.lock ./

RUN apt-get update && \
  apt-get install -y --no-install-recommends \
      curl \
      gcc \
      python3-dev \
      libpq-dev && \
  curl -sSL https://install.python-poetry.org | python3 - --yes && \
  poetry config virtualenvs.create false && \
  poetry install --no-root && \
  poetry add gunicorn && \
  apt-get remove -y curl gcc && \
  apt-get autoremove -y && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  mkdir -p migrations/versions && \
  chmod -R 777 migrations/versions

COPY . .

EXPOSE 8000

CMD ["gunicorn", "-k", "uvicorn.workers.UvicornWorker", "main:app", "--bind", "0.0.0.0:8000"]

image

Redução de 238MB!

  • Uso do --no-install-recommends no apt-get install
  • Objetivo: Reduzir o número de pacotes desnecessários instalados.
  • Como funciona: O parâmetro --no-install-recommends instrui o apt-get a não instalar pacotes recomendados por outros pacotes, evitando dependências que não são essenciais para o funcionamento da aplicação.
RUN apt-get update && \
  apt-get install -y --no-install-recommends \
      curl \
      gcc \
      python3-dev \
      libpq-dev
  • Combinação de Comandos em uma Única Camada (RUN)
  • Objetivo: Reduzir o número de camadas criadas na imagem, minimizando o tamanho final.
  • Como funciona: Comandos RUN são combinados para que arquivos temporários sejam removidos antes de criar a próxima camada.
RUN apt-get update && \
  apt-get install -y --no-install-recommends \
      curl \
      gcc \
      python3-dev \
      libpq-dev && \
  curl -sSL https://install.python-poetry.org | python3 - --yes && \
  poetry config virtualenvs.create false && \
  poetry install --no-root && \
  apt-get remove -y curl gcc && \
  apt-get autoremove -y && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/* && \
  mkdir -p migrations/versions && \
  chmod -R 777 migrations/versions
  • Remoção de Dependências Temporárias e Limpeza de Cache
  • Objetivo: Liberar espaço removendo pacotes e caches não necessários após a instalação.
  • Como funciona:
  • apt-get remove -y curl gcc: Remove pacotes usados apenas para instalação.
  • apt-get autoremove -y: Remove dependências que não são mais necessárias.
  • apt-get clean: Limpa os caches do apt-get.
  • rm -rf /var/lib/apt/lists/*: Remove arquivos temporários criados pelo apt-get.
  • Instalação Eficiente do Poetry e Dependências
curl -sSL https://install.python-poetry.org | python3 - --yes && \
poetry config virtualenvs.create false && \
poetry install --no-root && \
poetry add gunicorn
  • Criação de Diretório e Permissões
  • Objetivo: Criar o diretório de migrações e ajustar permissões sem impactar o tamanho da imagem.
mkdir -p migrations/versions && \
chmod -R 777 migrations/versions
  • Ordem dos Comandos COPY
  • Objetivo: Melhorar a eficiência do cache do Docker e reduzir o tempo de construção.
COPY pyproject.toml poetry.lock ./
COPY . .
  • Essa ordem evita reinstalar pacotes caso apenas o código-fonte mude, acelerando o build.

Com essas otimizações, conseguimos uma imagem menor e mais eficiente!

Share
Comments (1)
DIO Community
DIO Community - 17/02/2025 16:57

Ótimas otimizações, Leonardo! A redução do tamanho da imagem demonstra como pequenas mudanças no Dockerfile podem gerar um impacto significativo. A utilização do --no-install-recommends no apt-get install minimiza a instalação de pacotes desnecessários, enquanto a combinação de comandos RUN reduz a criação de camadas desnecessárias, otimizando o cache do Docker.

Além disso, a remoção de dependências temporárias e arquivos de cache contribui para uma imagem mais enxuta. Outra melhoria importante foi a reorganização do COPY, evitando reinstalações desnecessárias de dependências ao alterar o código-fonte. Para um refinamento adicional, um multi-stage build poderia ser implementado para eliminar qualquer resquício de dependências de compilação, reduzindo ainda mais o tamanho da imagem. Excelente trabalho na otimização e eficiência do Dockerfile!