Começamos a migrar nossos contêineres docker para a versão 24.04 e recebemos a seguinte recomendação do sistema operacional durante a instalação das dependências do python:
root@76ea3b9e695a:/# pip install numpy
error: externally-managed-environment
× This environment is externally managed
╰─> To install Python packages system-wide, try apt install
python3-xyz, where xyz is the package you are trying to
install.
If you wish to install a non-Debian-packaged Python package,
create a virtual environment using python3 -m venv path/to/venv.
Then use path/to/venv/bin/python and path/to/venv/bin/pip. Make
sure you have python3-full installed.
If you wish to install a non-Debian packaged Python application,
it may be easiest to use pipx install xyz, which will manage a
virtual environment for you. Make sure you have pipx installed.
See /usr/share/doc/python3.12/README.venv for more information.
note: If you believe this is a mistake, please contact your Python installation or OS
distribution provider. You can override this, at the risk of breaking your Python
installation or OS, by passing --break-system-packages.
hint: See PEP 668 for the detailed specification.
Questões:
- Supondo que o python-* não cubra todas as nossas dependências, a abordagem venv é de fato a maneira recomendada para instalar dependências do python em contêineres 24.04 para expor um único ponto de entrada do aplicativo, por exemplo
__main__.py
? - Quais são os benefícios de usar python-* como dependências? Elas são oferecidas com suporte a vulnerabilidades pelo Ubuntu?
TLDR; use venv para projetos (e use uma ferramenta para controlar e resolver suas dependências)
Tenho certeza de que há várias maneiras de fazer as coisas, mas aqui está meu argumento:
Sim, instalar em um venv é realmente preferível e aqui está o porquê:
python-*
pacotes apt corretos (que podem ser modificados pelo pip).Os pacotes apt
python-*
são principalmente para sistemas operacionais que dependem deles. Os sistemas operacionais são projetados e testados com dependências fornecidas e funcionam bem juntos. Contanto que você se mova apenas para dentro dessas dependências, elas provavelmente funcionarão bem umas com as outras. Esses pacotes são atualizados às vezes, mas provavelmente não conterão todas as novas versões, pois isso exigiria muitos testes para garantir que todos os sistemas operacionais continuem funcionando. Claro, correções de segurança para esses pacotes provavelmente são fornecidas pelos mantenedores do pacote apt, mas, novamente, as atualizações podem ser menos frequentes ou não tão rápidas.Exemplo
Um exemplo de como construir uma compilação determinística do Docker com a ferramenta uv pode ser encontrado aqui . Eu gosto especialmente dessa compilação multiestágio do Docker porque no contêiner em execução, o uv não é necessário, pois apenas o venv é copiado para lá. (Observe que o exemplo aqui na verdade usa o interpretador do sistema em ambas as imagens, então ainda há uma dependência do sistema.)
Opinião
Em geral, gerenciar dependências se torna muito mais fácil com uma boa ferramenta. Uv é o mais novo na comunidade Python e eu o uso para praticamente todos os meus novos projetos. Como ele é opinativo e só funciona em venvs, o fluxo de trabalho acima se torna um requisito ao trabalhar com ele.
Se você tem apenas alguns requisitos para um script simples , então provavelmente é bom instalá-los diretamente sem um venv, é só que esses projetos tendem a crescer e se tornar mais complicados com o tempo. Então sim, faça corretamente da primeira vez ;)