É ruim ter meu diretório virtualenv dentro do meu repositório git?


284

Estou pensando em colocar o virtualenv para um aplicativo da web Django que estou criando dentro do meu repositório git para o aplicativo. Parece uma maneira fácil de manter a implantação simples e fácil. Existe alguma razão para eu não fazer isso?

Respostas:


301

Eu uso pip freezepara obter os pacotes necessários em um requirements.txtarquivo e adicioná-lo ao meu repositório. Tentei pensar em uma maneira de você querer armazenar o virtualenv inteiro, mas não consegui.


81
Você pode economizar espaço desnecessário no seu repositório e ainda implantar em um novo servidor em um único comando: virtualenv --no-site-packages --distribute .env && source .env / bin / ativar && pip install -r requirements.txt
RyanBrady

2
Eu estou lhe dando a resposta para esta pergunta, pois provavelmente é a "melhor prática" e você a ofereceu primeiro. Eu definitivamente encontrei alguns dos problemas que todos mencionaram. Estou estimando que me dou outro dia brincando com ele antes de fazer o que vocês sempre sugeriram e usar pip e um arquivo de requisitos. Obrigado pela ajuda!
Lyle Pratt

11
Se você, digamos pip install mysql-python, em uma máquina de 64 bits e alguém com uma máquina de 32 bits tentar usá-la, isso não funcionará. Ele usa um módulo C, como muitos módulos Python, para aumentar o desempenho. Eu imagino que o Windows-> Linux também não funcionaria.
Matt Williamson

7
apenas uma observação: recebemos pouco no passado porque, de alguma forma, as bibliotecas estão ficando indisponíveis no pip (versão muito antiga), forçando uma atualização enquanto o site estava inativo. então ... agora nunca mais vou confiar pip freezenisso para fazer isso. o problema é que, durante a atualização forçada da reimplantação, ninguém paga por isso e pelas atualizações intermediárias (manutenção de "práticas recomendadas") também não.
CONTRATO DIZ QUE ESTOU CERTO

5
Nota sobre o comentário @RayanBrady: As opções --distributee --setuptoolsagora não estão disponíveis. (distribuir, que era um fork de setuptools foi mesclado há muito tempo). --no-site-packagesé obsoleto, agora é o comportamento padrão
JackNova

48

Armazenar o diretório virtualenv dentro do git permitirá, como você observou, implantar o aplicativo inteiro executando apenas um clone do git (além de instalar e configurar o Apache / mod_wsgi). Um problema potencialmente significativo com essa abordagem é que, no Linux, o caminho completo é codificado nos scripts de ativação, django-admin.py, easy_install e pip do venv. Isso significa que seu virtualenv não funcionará inteiramente se você desejar usar um caminho diferente, talvez para executar vários hosts virtuais no mesmo servidor. Acho que o site pode realmente funcionar com os caminhos errados nesses arquivos, mas você terá problemas na próxima vez que tentar executar o pip.

A solução, já fornecida, é armazenar informações suficientes no git para que, durante a implementação, você possa criar a virtualenv e fazer as instalações necessárias do pip. Normalmente, as pessoas correm pip freezepara obter a lista e a armazenam em um arquivo chamado requirements.txt. Pode ser carregado com pip install -r requirements.txt. RyanBrady já mostrou como você pode encadear as instruções de implantação em uma única linha:

# before 15.1.0
virtualenv --no-site-packages --distribute .env &&\
    source .env/bin/activate &&\
    pip install -r requirements.txt

# after deprecation of some arguments in 15.1.0
virtualenv .env && source .env/bin/activate && pip install -r requirements.txt

Pessoalmente, eu apenas os coloquei em um script de shell que executei após executar o clone git ou o git pull.

Armazenar o diretório virtualenv também torna um pouco mais complicado lidar com atualizações de pip, pois você terá que adicionar / remover manualmente e confirmar os arquivos resultantes da atualização. Com um arquivo requirements.txt, basta alterar as linhas apropriadas em requirements.txt e executar novamente pip install -r requirements.txt. Como já observado, isso também reduz o "envio de spam".


4
Observe que --distribute agora está obsoleto (pelo menos em 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC

1
--no-site-packagestambém foi preterido na 15.1.0, pois agora é o padrão.
CJS

35

Eu fazia o mesmo até começar a usar bibliotecas compiladas de maneira diferente, dependendo do ambiente, como PyCrypto. Meu Mac PyCrypto não funcionaria no Cygwin não funcionaria no Ubuntu.

Torna-se um pesadelo absoluto para gerenciar o repositório.

De qualquer maneira, achei mais fácil gerenciar o congelamento do pip e um arquivo de requisitos do que ter tudo no git. Também é mais limpo, pois você evita o envio de spam para milhares de arquivos à medida que essas bibliotecas são atualizadas ...


Hmm. Definitivamente, não terei problemas com coisas sendo compiladas de maneira diferente em ambientes diferentes. Eu acho que provavelmente não vale a pena fazê-lo apenas para evitar o spam de confirmação.
Lyle Pratt

@LylePratt: Penso o contrário: é melhor não incluir virtualenv inteiro no repositório apenas para evitar problemas com ferramentas excelentes como PyCrypto ou PIL.
Tadeck 18/12/12

17

Eu acho que um dos principais problemas que ocorrem é que o virtualenv pode não ser utilizável por outras pessoas. A razão é que ele sempre usa caminhos absolutos. Portanto, se você tiver virtualenv, por exemplo, /home/lyle/myenv/ele assumirá o mesmo para todas as outras pessoas que usam este repositório (ele deve ser exatamente o mesmo caminho absoluto). Você não pode presumir pessoas usando a mesma estrutura de diretórios que você.

A melhor prática é que todos estejam configurando seu próprio ambiente (com ou sem virtualenv) e instalando bibliotecas nele. Isso também torna o código mais utilizável em diferentes plataformas (Linux / Windows / Mac), também porque o virtualenv é instalado diferente em cada uma delas.


Isso está certo porque é uma má ideia manter uma virtualenv no SCM, mas vale a pena considerar algo como a sugestão do @ RJBrady ou o evento de um script bootstrap.py , pois ter alguns meios de recriar o mesmo ambiente nas máquinas é um necessidade séria ao trabalhar com outras pessoas.
ig0774

Não tenho certeza se o problema que você mencionou seria exatamente um problema na minha situação. Meu aplicativo Django contém um arquivo .wsgi que define onde o virtualenv é relativo à sua localização (2 diretórios acima '../../env'). Então, no meu cenário, o problema do caminho absoluto não deve me afetar negativamente ... certo?
Lyle Pratt

Se você executar seu aplicativo sempre com o WSGI, poderá se safar. Se você usar o servidor de desenvolvimento (via manage.py), terá problemas com certeza.
Torsten Engelbrecht

3

Eu uso o que é basicamente a resposta de David Sickmiller com um pouco mais de automação. Crio um arquivo (não executável) no nível superior do meu projeto, nomeado activatecom o seguinte conteúdo:

[ -n "$BASH_SOURCE" ] \
    || { echo 1>&2 "source (.) this with Bash."; exit 2; }
(
    cd "$(dirname "$BASH_SOURCE")"
    [ -d .build/virtualenv ] || {
        virtualenv .build/virtualenv
        . .build/virtualenv/bin/activate
        pip install -r requirements.txt
    }
)
. "$(dirname "$BASH_SOURCE")/.build/virtualenv/bin/activate"

(Conforme a resposta de David, isso pressupõe que você esteja fazendo um pip freeze > requirements.txtpara manter sua lista de requisitos atualizada.)

O exposto acima dá a ideia geral; o script de ativação real ( documentação ) que eu normalmente uso é um pouco mais sofisticado, oferecendo uma -qopção (silenciosa), usando pythonquando python3não está disponível etc.

Isso pode ser originado de qualquer diretório de trabalho atual e será ativado corretamente, primeiro configurando o ambiente virtual, se necessário. Meu script de teste de nível superior geralmente possui código nessas linhas para que possa ser executado sem que o desenvolvedor precise ativar primeiro:

cd "$(dirname "$0")"
[[ $VIRTUAL_ENV = $(pwd -P) ]] || . ./activate

O fornecimento ./activate, não activate, é importante aqui, porque o último encontrará outro activateno seu caminho antes de encontrar o outro no diretório atual.


Amando essa abordagem! Parece muito razoável, obrigado por compartilhar.
Esolitos 20/02/19

Eu tive que mudar a primeira linha para [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }detectar se o roteiro foi sendo executado em oposição a origem
Chris Neve

3

Não é uma boa ideia incluir qualquer componente ou configuração dependente do ambiente em seus repositórios, pois um dos principais aspectos do uso de um repositório é, talvez, compartilhá-lo com outros desenvolvedores. Aqui está como eu configuraria meu ambiente de desenvolvimento em um PC com Windows (por exemplo, Win10).

  1. Abra Pycharm e, na primeira página, escolha o projeto no seu Source Control System (no meu caso, estou usando o github)

  2. No Pycharm, navegue até as configurações e escolha "Project Interpreter" e escolha a opção para adicionar um novo ambiente virtual, você pode chamá-lo de "venv".

  3. Escolha o interpretador python base localizado em C: \ Usuários {usuário} \ AppData \ Local \ Programas \ Python \ Python36 (certifique-se de escolher a versão apropriada do Python com base no que você instalou)

  4. Observe que o Pycharm criará o novo ambiente virtual e copiará binários python e bibliotecas necessárias na sua pasta venv dentro da pasta do projeto.

  5. Deixe o Pycharm concluir sua varredura, pois precisa reconstruir / atualizar o esqueleto do seu projeto

  6. excluir a pasta venv de suas interações git (adicione venv \ ao arquivo .gitignore na pasta do seu projeto)

Bônus: se você deseja que as pessoas instalem facilmente (bem, quase facilmente) todas as bibliotecas de que seu software precisa, você pode usar

pip freeze > requirements.txt

e coloque as instruções no seu git para que as pessoas possam usar o seguinte comando para baixar todas as bibliotecas necessárias de uma só vez.

pip install -r requirements.txt 

2

Se você souber em quais sistemas operacionais seu aplicativo estará executando, eu criaria uma virtualenv para cada sistema e a incluiria no meu repositório. Então eu faria meu aplicativo detectar em qual sistema ele está sendo executado e usar o virtualenv correspondente.

O sistema pode, por exemplo, ser identificado usando o módulo da plataforma .

De fato, é isso que faço com um aplicativo interno que escrevi e ao qual posso adicionar rapidamente um novo virtualv do sistema, caso seja necessário. Dessa forma, não preciso confiar que o pip será capaz de baixar com êxito o software que meu aplicativo exige. Também não precisarei me preocupar com a compilação de, por exemplo, psycopg2, que eu uso.

Se você não souber em qual sistema operacional seu aplicativo pode ser executado, provavelmente será melhor usar o pip freezeque é sugerido em outras respostas aqui.


0

Acho que o melhor é instalar o ambiente virtual em um caminho dentro da pasta do repositório, talvez seja melhor incluir um subdiretório dedicado ao ambiente (excluí acidentalmente todo o meu projeto ao forçar a instalação de um ambiente virtual na raiz do repositório pasta, bom que eu tenha o projeto salvo em sua versão mais recente no Github).

O instalador automatizado ou a documentação devem indicar o caminho virtualenv como um caminho relativo, desta forma você não terá problemas ao compartilhar o projeto com outras pessoas. Sobre os pacotes, os pacotes usados ​​devem ser salvos por pip freeze -r requirements.txt.


-1

Se você acabou de configurar o ambiente de desenvolvimento, use o arquivo pip freeze, caz que limpa o repositório git.

Então, se estiver implementando a produção, verifique a pasta venv inteira. Isso tornará sua implantação mais reproduzível, não precisará desses pacotes libxxx-dev e evitará problemas de Internet.

Portanto, existem dois repositórios. Um para o seu código-fonte principal, que inclui um requirements.txt. E um repositório env, que contém toda a pasta venv.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.