Có phải là xấu khi có thư mục virtualenv của tôi trong kho git của tôi?


284

Tôi đang suy nghĩ về việc đặt virtualenv cho một ứng dụng web Django mà tôi đang tạo trong kho git của mình cho ứng dụng. Nó có vẻ như là một cách dễ dàng để giữ cho việc triển khai đơn giản và dễ dàng. Có bất kỳ lý do tại sao tôi không nên làm điều này?

Câu trả lời:


301

Tôi sử dụng pip freezeđể có được các gói tôi cần vào một requirements.txttập tin và thêm nó vào kho lưu trữ của tôi. Tôi đã cố gắng nghĩ về một lý do tại sao bạn muốn lưu trữ toàn bộ virtualenv, nhưng tôi không thể.


81
Bạn có thể tiết kiệm không gian không cần thiết trong repo của mình và vẫn triển khai đến một máy chủ mới trong một lệnh duy nhất: virtualenv --no-site-gói --distribution .env && source .env / bin / activ && pip install -r tests.txt
RyanBrady

2
Tôi sẽ cho bạn câu trả lời cho câu hỏi này, vì đây có lẽ là "cách thực hành tốt nhất" và bạn đã đưa ra câu hỏi đầu tiên. Tôi chắc chắn đã gặp phải một số vấn đề mà mọi người đã đề cập. Tôi đang ước tính tôi sẽ tự làm phiền mình thêm một ngày trước khi tôi làm những gì mà các bạn đã gợi ý và sử dụng pip và một tệp yêu cầu. Cảm ơn bạn đã giúp đỡ!
Lyle Pratt

11
Nếu bạn nói pip install mysql-python, trên máy 64 bit, và sau đó ai đó có máy 32 bit cố gắng sử dụng thì nó sẽ không hoạt động. Nó sử dụng một mô-đun C, giống như nhiều mô-đun Python làm, để tăng hiệu suất. Tôi tưởng tượng Windows-> Linux cũng sẽ không hoạt động.
Matt Williamson

7
chỉ là một nhận xét: chúng tôi đã có một chút trong quá khứ bởi vì bằng cách nào đó các thư viện đang trở nên không có sẵn từ pip (phiên bản quá cũ), buộc phải nâng cấp trong khi trang web bị sập. vì vậy ... bây giờ tôi sẽ không bao giờ dựa vào pip freezemột lần nữa để làm điều này. vấn đề là trong quá trình triển khai nâng cấp bắt buộc của bạn, không ai trả tiền cho nó và đối với các nâng cấp trung gian (bảo trì "thực hành tốt nhất") thì không ai làm cả.
HỢP ĐỒNG SAYS TÔI QUYỀN

5
Lưu ý về nhận xét @RayanBrady: Các tùy chọn --distribute--setuptoolshiện không còn hoạt động. (phân phối, đó là một nhánh của setuptools đã được hợp nhất trở lại từ lâu). --no-site-packagesbị ĐỔI, giờ đây là hành vi mặc định
JackNova

48

Lưu trữ thư mục virtualenv bên trong git, như bạn đã lưu ý, cho phép bạn triển khai toàn bộ ứng dụng chỉ bằng cách thực hiện một bản sao git (cộng với cài đặt và định cấu hình Apache / mod_wsgi). Một vấn đề tiềm năng quan trọng với cách tiếp cận này là trên Linux, đường dẫn đầy đủ được mã hóa cứng trong kích hoạt của venv, django-admin.py, easy_install và các tập lệnh pip. Điều này có nghĩa là virtualenv của bạn sẽ không hoạt động hoàn toàn nếu bạn muốn sử dụng một đường dẫn khác, có lẽ để chạy nhiều máy chủ ảo trên cùng một máy chủ. Tôi nghĩ rằng trang web thực sự có thể hoạt động với các đường dẫn sai trong các tệp đó, nhưng bạn sẽ gặp vấn đề trong lần tiếp theo bạn cố chạy pip.

Giải pháp, đã được đưa ra, là lưu trữ đủ thông tin trong git để trong quá trình triển khai, bạn có thể tạo virtualenv và thực hiện các cài đặt pip cần thiết. Thông thường mọi người chạy pip freezeđể lấy danh sách sau đó lưu trữ nó trong một tệp có tên là tests.txt. Nó có thể được tải với pip install -r requirements.txt. RyanBrady đã chỉ ra cách bạn có thể xâu chuỗi các câu lệnh triển khai trong một dòng duy nhất:

# 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

Cá nhân, tôi chỉ đặt những thứ này trong một kịch bản shell mà tôi chạy sau khi thực hiện git clone hoặc git pull.

Việc lưu trữ thư mục virtualenv cũng giúp việc xử lý nâng cấp pip trở nên khó khăn hơn một chút, vì bạn sẽ phải thêm / xóa thủ công và cam kết các tệp do nâng cấp. Với tệp tests.txt, bạn chỉ cần thay đổi các dòng thích hợp trong tests.txt và chạy lại pip install -r requirements.txt. Như đã lưu ý, điều này cũng làm giảm "thư rác".


4
Lưu ý rằng - phân phối hiện không được chấp nhận (ít nhất là trong 15.1.0): --distribute DEPRECATED. Retained only for backward compatibility. This option has no effect.
AnthonyC

1
--no-site-packagescũng không được chấp nhận trong 15.1.0, vì bây giờ nó là mặc định.
cjs

35

Tôi đã từng làm như vậy cho đến khi tôi bắt đầu sử dụng các thư viện được biên dịch khác nhau tùy thuộc vào môi trường như PyCrypto. Mac PyCrypto của tôi sẽ không hoạt động trên Cygwin sẽ không hoạt động trên Ubuntu.

Nó trở thành một cơn ác mộng hoàn toàn để quản lý kho lưu trữ.

Dù bằng cách nào tôi cũng thấy việc quản lý pip đóng băng & tệp yêu cầu dễ dàng hơn so với việc có tất cả trong git. Nó cũng sạch hơn vì bạn có thể tránh được thư rác cam kết cho hàng ngàn tệp khi các thư viện đó được cập nhật ...


Hừm. Tôi chắc chắn sẽ không gặp vấn đề với những thứ được biên dịch khác nhau trong các môi trường khác nhau. Tôi đoán có lẽ không nên làm điều đó chỉ để tránh thư rác.
Lyle Pratt

@LylePratt: Tôi nghĩ ngược lại: tốt hơn không bao gồm toàn bộ virtualenv trong kho lưu trữ chỉ để tránh các vấn đề với việc có các công cụ tuyệt vời như PyCrypto hoặc PIL.
Tadeck

17

Tôi nghĩ một trong những vấn đề chính xảy ra là virtualenv có thể không được người khác sử dụng được. Lý do là nó luôn sử dụng các đường dẫn tuyệt đối. Vì vậy, nếu bạn virtualenv chẳng hạn, /home/lyle/myenv/nó sẽ giả sử giống nhau cho tất cả những người khác sử dụng kho lưu trữ này (nó phải chính xác là cùng một đường dẫn tuyệt đối). Bạn không thể đoán người sử dụng cấu trúc thư mục giống như bạn.

Thực hành tốt hơn là mọi người đều thiết lập môi trường của riêng họ (có thể có hoặc không có virtualenv) và cài đặt các thư viện ở đó. Điều đó cũng làm cho bạn viết mã dễ sử dụng hơn trên các nền tảng khác nhau (Linux / Windows / Mac), cũng bởi vì virtualenv được cài đặt khác nhau trong mỗi nền tảng.


Điều này đúng cho lý do tại sao việc giữ một virtualenv trong SCM là một ý tưởng tồi, nhưng đáng để xem xét một cái gì đó như đề xuất của @ RJBrady hoặc sự kiện một kịch bản bootstrap.py , vì có một số phương tiện tái tạo cùng một môi trường trên các máy là một nhu cầu nghiêm túc khi làm việc với người khác.
ig0774

Tôi không thực sự chắc chắn rằng vấn đề bạn đề cập sẽ là một vấn đề chính xác trong tình huống của tôi. Ứng dụng Django của tôi chứa tệp .wsgi xác định vị trí của virtualenv so với vị trí của nó (2 thư mục trở lên '../../env'). Vì vậy, trong kịch bản của tôi, vấn đề đường dẫn tuyệt đối không ảnh hưởng tiêu cực đến tôi ... phải không?
Lyle Pratt

Nếu bạn chạy ứng dụng của mình luôn với WSGI thì bạn có thể thoát khỏi nó. Nếu bạn sử dụng máy chủ phát triển (thông qua manage.py), bạn sẽ gặp vấn đề chắc chắn.
Torsten Engelbrecht

3

Tôi sử dụng những gì về cơ bản là câu trả lời của David Sickmiller với sự tự động hóa hơn một chút. Tôi tạo một tệp (không thể thực thi) ở cấp cao nhất của dự án của tôi có tên activatevới các nội dung sau:

[ -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"

(Theo câu trả lời của David, điều này giả định rằng bạn đang làm pip freeze > requirements.txtđể giữ cho danh sách các yêu cầu của bạn được cập nhật.)

Trên đây cho ý tưởng chung; tập lệnh kích hoạt thực tế ( tài liệu ) mà tôi thường sử dụng phức tạp hơn một chút, cung cấp -qtùy chọn (yên tĩnh), sử dụng pythonkhi python3không khả dụng, v.v.

Điều này sau đó có thể có nguồn gốc từ bất kỳ thư mục làm việc hiện tại và sẽ kích hoạt đúng cách, đầu tiên thiết lập môi trường ảo nếu cần thiết. Tập lệnh kiểm tra cấp cao nhất của tôi thường có mã dọc theo các dòng này để có thể chạy được mà không cần nhà phát triển phải kích hoạt trước:

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

Tìm nguồn cung ứng ./activate, không activatequan trọng ở đây bởi vì cái sau sẽ tìm thấy bất kỳ thứ gì khác activatetrong đường dẫn của bạn trước khi nó tìm thấy cái trong thư mục hiện tại.


Yêu cách tiếp cận này! Âm thanh rất hợp lý, cảm ơn bạn đã chia sẻ.
Esolitos

Tôi đã phải thay đổi dòng đầu tiên [[ $_ != $0 ]] || { echo 1>&2 "source (.) this script with Bash."; exit 2; }để phát hiện xem kịch bản có được thực thi trái ngược với nguồn gốc hay không
Chris Snow

3

Có lẽ không nên bao gồm bất kỳ thành phần phụ thuộc môi trường nào hoặc cài đặt trong repos của bạn như một trong những khía cạnh quan trọng của việc sử dụng repo, có lẽ là, chia sẻ nó với các nhà phát triển khác. Đây là cách tôi sẽ thiết lập môi trường phát triển của mình trên PC Windows (giả sử Win10).

  1. Mở Pycharm và trên trang đầu tiên, chọn kiểm tra dự án từ Hệ thống kiểm soát nguồn của bạn (trong trường hợp của tôi, tôi đang sử dụng github)

  2. Trong Pycharm, điều hướng đến cài đặt và chọn "Trình thông dịch dự án" và chọn tùy chọn để thêm môi trường ảo mới, bạn có thể gọi nó là "venv".

  3. Chọn trình thông dịch python cơ sở được đặt tại C: \ Users {user} \ AppData \ Local \ Programs \ Python \ Python36 (đảm bảo bạn chọn phiên bản Python phù hợp dựa trên những gì bạn đã cài đặt)

  4. Lưu ý rằng Pycharm sẽ tạo môi trường ảo mới và sao chép các tệp nhị phân python và các thư viện cần thiết trong thư mục venv của bạn trong thư mục dự án của bạn.

  5. Hãy để Pycharm hoàn thành quá trình quét vì nó cần xây dựng lại / làm mới bộ xương dự án của bạn

  6. loại trừ thư mục venv khỏi các tương tác git của bạn (thêm tệp venv \ vào .gitignore trong thư mục dự án của bạn)

Phần thưởng: Nếu bạn muốn mọi người dễ dàng (tốt, gần như dễ dàng) cài đặt tất cả các thư viện mà phần mềm của bạn cần, bạn có thể sử dụng

pip freeze > requirements.txt

và đặt hướng dẫn trên git của bạn để mọi người có thể sử dụng lệnh sau để tải xuống tất cả các thư viện cần thiết cùng một lúc.

pip install -r requirements.txt 

2

Nếu bạn biết ứng dụng nào mà ứng dụng của bạn sẽ chạy, tôi sẽ tạo một virtualenv cho mỗi hệ thống và đưa nó vào kho lưu trữ của tôi. Sau đó, tôi sẽ làm cho ứng dụng của mình phát hiện hệ thống nào đang chạy và sử dụng virtualenv tương ứng.

Hệ thống có thể được xác định bằng cách sử dụng mô-đun nền tảng .

Trên thực tế, đây là những gì tôi làm với một ứng dụng nội bộ mà tôi đã viết và tôi có thể nhanh chóng thêm virtualenv của một hệ thống mới trong trường hợp cần thiết. Bằng cách này, tôi không phải dựa vào pip đó để có thể tải xuống thành công phần mềm mà ứng dụng của tôi yêu cầu. Tôi cũng sẽ không phải lo lắng về việc biên dịch ví dụ psycopg2 mà tôi sử dụng.

Nếu bạn không biết ứng dụng nào có thể chạy trên hệ điều hành nào, có lẽ bạn nên sử dụng pip freezenhư được đề xuất trong các câu trả lời khác ở đây.


0

Tôi nghĩ rằng tốt nhất là cài đặt môi trường ảo trong một đường dẫn bên trong thư mục kho lưu trữ, có thể bao gồm tốt hơn để sử dụng thư mục con dành riêng cho môi trường (Tôi đã vô tình xóa toàn bộ dự án của mình khi buộc cài đặt môi trường ảo trong kho lưu trữ gốc thư mục, tốt là tôi đã lưu dự án trong phiên bản mới nhất của nó trong Github).

Trình cài đặt tự động hoặc tài liệu sẽ chỉ ra đường dẫn virtualenv là đường dẫn tương đối, theo cách này bạn sẽ không gặp phải vấn đề khi chia sẻ dự án với người khác. Về các gói, các gói được sử dụng nên được lưu bởi pip freeze -r requirements.txt.


-1

Nếu bạn chỉ thiết lập env phát triển, sau đó sử dụng tệp đóng băng pip, caz làm cho git repo sạch sẽ.

Sau đó, nếu thực hiện triển khai sản xuất, sau đó kiểm tra toàn bộ thư mục venv. Điều đó sẽ làm cho việc triển khai của bạn có thể tái tạo nhiều hơn, không cần các gói libxxx-dev đó và tránh các sự cố internet.

Vì vậy, có hai repos. Một cho mã nguồn chính của bạn, bao gồm một tệp.txt.txt. Và một repo env, chứa toàn bộ thư mục venv.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.