thiết lập một biến môi trường trong virtualenv


160

Tôi có một dự án Heroku sử dụng các biến môi trường để có được cấu hình của nó, nhưng trước tiên tôi sử dụng virtualenv để kiểm tra ứng dụng của mình.

Có cách nào để đặt các biến môi trường được xác định trên máy từ xa bên trong virtualenv không?

Câu trả lời:


106

Cập nhật

Kể từ ngày 17 tháng 5 năm 2017, README của autoenv nói rằng direnv có lẽ là lựa chọn tốt hơn và ngụ ý autoenv không còn được duy trì.

Câu trả lời cũ

Tôi đã viết autoenv để làm chính xác điều này:

https://github.com/kennethreitz/autoenv


12
Gif rất hài hước: D
chachan 04/11 '

3
Chỉ cần FYI có vẻ như .envcác tập tin bork Heroku xây dựng, ít nhất là theo kinh nghiệm của tôi. Vì vậy, không bao gồm nó trong repo của bạn. Người dùng lâu năm / fan hâm mộ lớn của autoenv btw. Chào Kenneth, bạn da man!
galarant

Là câu trả lời này vẫn còn có liên quan sau khi chỉnh sửa? Ý kiến ​​của bạn về giải pháp được đề xuất bởi Nagasaki45 & TheLetterN
đóng băng

288

Trong trường hợp bạn đang sử dụng virtualenvwrapper (tôi rất khuyên bạn nên làm như vậy), bạn có thể xác định các hook khác nhau (vô hiệu hóa, postactivate, preeaceacate, postdeacate) bằng cách sử dụng các tập lệnh có cùng tên $VIRTUAL_ENV/bin/. Bạn cần móc postactivate.

$ workon myvenv

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
export DJANGO_DEBUG=True
export S3_KEY=mykey
export S3_SECRET=mysecret

$ echo $DJANGO_DEBUG
True

Nếu bạn muốn giữ cấu hình này trong thư mục dự án của bạn, chỉ cần tạo một liên kết tượng trưng từ thư mục dự án của bạn $VIRTUAL_ENV/bin/postactivate.

$ rm $VIRTUAL_ENV/bin/postactivate
$ ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivate

Bạn thậm chí có thể tự động hóa việc tạo các liên kết tượng trưng mỗi khi bạn sử dụng mkvirtualenv .

Dọn dẹp hủy kích hoạt

Hãy nhớ rằng điều này sẽ không làm sạch sau khi chính nó. Khi bạn hủy kích hoạt virtualenv, biến môi trường sẽ tồn tại. Để làm sạch đối xứng, bạn có thể thêm vào $VIRTUAL_ENV/bin/predeactivate.

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
unset DJANGO_DEBUG

$ deactivate

$ echo $DJANGO_DEBUG

Hãy nhớ rằng nếu sử dụng điều này cho các biến môi trường có thể đã được đặt trong môi trường của bạn thì việc bỏ đặt sẽ dẫn đến việc chúng hoàn toàn không được đặt khi rời virtualenv. Vì vậy, nếu đó là tất cả có thể xảy ra, bạn có thể ghi lại giá trị trước đó ở đâu đó tạm thời sau đó đọc lại khi tắt.

Thiết lập:

$ cat $VIRTUAL_ENV/bin/postactivate
#!/bin/bash
# This hook is run after this virtualenv is activated.
if [[ -n $SOME_VAR ]]
then
    export SOME_VAR_BACKUP=$SOME_VAR
fi
export SOME_VAR=apple

$ cat $VIRTUAL_ENV/bin/predeactivate
#!/bin/bash
# This hook is run before this virtualenv is deactivated.
if [[ -n $SOME_VAR_BACKUP ]]
then
    export SOME_VAR=$SOME_VAR_BACKUP
    unset SOME_VAR_BACKUP
else
    unset SOME_VAR
fi

Kiểm tra:

$ echo $SOME_VAR
banana

$ workon myenv

$ echo $SOME_VAR
apple

$ deactivate

$ echo $SOME_VAR
banana

Chỉ cần một độ chính xác: làm ln -s .env/postactivate $VIRTUAL_ENV/bin/postactivatekhông làm việc cho tôi. lnmuốn có một con đường đầy đủ, vì vậy tôi phải làmln -s `pwd`/.env/postactivate $VIRTUAL_ENV/bin/postactivate
Khu vực

@Zoneur Bạn đang dùng hệ điều hành nào? Theo Linux đường dẫn tương đối làm việc cho ln.
Danilo Bargen

@DaniloBargen Tôi sử dụng LinuxMint 3.2.0. Câu trả lời này nói rằng lnthích các đường dẫn đầy đủ vì vậy tôi đã thử nó và nó đã hoạt động. Khi tôi cố gắng catliên kết với đường dẫn tương đối, nó nói No such file or directory.
Khu vực

@dpwrussel, gần như không làm cho nó thông qua đánh giá, đây là một bổ sung tốt, nhưng nó rất quan trọng nên nó có thể được thực hiện như một bài đăng của riêng nó (sẽ nhận được một số đại diện cho bạn). Rất nhiều câu trả lời hay là tốt :)
Kent Fredric

2
Và kiểm soát nguồn? Làm thế nào điều này dịch cho người khác nhân bản và thiết lập một dự án cần env. var.s?
CpILL

44

Bạn có thể thử:

export ENVVAR=value

trong virtualenv_root / bin / kích hoạt. Về cơ bản, tập lệnh kích hoạt là những gì được thực thi khi bạn bắt đầu sử dụng virtualenv để bạn có thể đặt tất cả các tùy chỉnh của mình vào đó.


2
Không chắc chắn nếu điều đó đủ sạch nhưng chắc chắn hoạt động!
chachan

2
Vâng, nó rẻ và khó chịu, nhưng đôi khi đó là những gì bạn cần.
Michael Scheper

1
Tôi không khuyến nghị điều này, tôi đã làm nó và đôi khi tất cả các tập lệnh kích hoạt (activ, activ.csh, activ.fish) đã được ghi đè tự động nên tôi đã mất thay đổi. Sử dụng postactivate và kích hoạt trước.
wil93

không sử dụng khoảng trắng xung quanh =
Rik Schoonbeek

Cũng có thể thêm 'hủy đặt ENVVAR' trong deactivatechức năng được xác định virtualenv_root / bin / kích hoạt để cân bằng cài đặt và bỏ cài đặt
Lou Zell

42

Chỉ sử dụng virtualenv (không có virtualenvwrapper ), việc thiết lập các biến môi trường rất dễ dàng thông qua activatetập lệnh bạn tìm nguồn để kích hoạt virtualenv.

Chạy:

nano YOUR_ENV/bin/activate

Thêm các biến môi trường vào cuối tệp như thế này:

export KEY=VALUE

Bạn cũng có thể đặt một móc tương tự để bỏ đặt biến môi trường theo đề xuất của Danilo Bargen trong câu trả lời tuyệt vời của anh ấy ở trên nếu bạn cần.


9
một cách tiếp cận lành mạnh hơn nhiều IMO. ghi đè cdchỉ để có biến môi trường? rùng mình
Michel Müller

Làm thế nào về việc dọn dẹp sau khi ngừng hoạt động?
buncis

36

Mặc dù có rất nhiều câu trả lời hay ở đây, tôi đã không thấy một giải pháp được đăng tải, cả hai đều bao gồm việc không đặt các biến môi trường khi hủy kích hoạt và không yêu cầu các thư viện bổ sung virtualenv, vì vậy đây là giải pháp của tôi chỉ liên quan đến chỉnh sửa / bin / kích hoạt, sử dụng các biến MY_SERVER_NAMEMY_DATABASE_URLnhư ví dụ:

Cần có một định nghĩa để hủy kích hoạt trong tập lệnh kích hoạt và bạn muốn hủy đặt các biến của mình ở cuối của nó:

deactivate () {
    ...

    # Unset My Server's variables
    unset MY_SERVER_NAME
    unset MY_DATABASE_URL
}

Sau đó, ở cuối tập lệnh kích hoạt, đặt các biến:

# Set My Server's variables
export MY_SERVER_NAME="<domain for My Server>"
export MY_DATABASE_URL="<url for database>"

Bằng cách này, bạn không phải cài đặt bất cứ thứ gì khác để nó hoạt động và bạn không kết thúc với các biến còn sót lại khi bạn deactivatesử dụng virtualenv.


3
Tôi thích cách tiếp cận này vì tôi không muốn các ứng dụng hoặc ứng dụng bên ngoài nhưng vấn đề với điều này là nếu bạn xây dựng lại môi trường, bạn sẽ mất tất cả các cài đặt của mình.
VStoykov

2
Ưu điểm của phương pháp này là tốc độ thiết lập và thiếu phép thuật. Giữ các biến môi trường ngoài tầm kiểm soát nguồn sẽ luôn đưa bạn trở lại vấn đề có khả năng phá hủy các bí mật / cài đặt của bạn khi xây dựng lại môi trường.
Anthony Manning-Franklin

Có phải thư mục virtualenv cuối cùng đã được kiểm tra vào kho lưu trữ để làm việc này không? Điều gì xảy ra nếu các biến giữ bí mật mà bạn không muốn trong repo? Làm thế nào bạn kiểm soát nó?
fraxture

2
Tôi thực sự không hiểu tại sao nên đưa virtualenv vào kho lưu trữ của bạn, vì chúng không dễ mang theo, nhưng tôi tưởng tượng bạn có thể đặt bản xuất của mình vào một tệp riêng thay vì tập lệnh kích hoạt và lấy nguồn tệp nếu nó hiện diện và không thêm tệp đó vào kho lưu trữ của bạn.
TheLetterN

18

Tại địa phương trong một virtualenv, có hai phương pháp bạn có thể sử dụng để kiểm tra điều này. Đầu tiên là một công cụ được cài đặt thông qua công cụ Heroku (https://toolbelt.heroku.com/). Công cụ này là đốc công. Nó sẽ xuất tất cả các biến môi trường của bạn được lưu trữ trong tệp .env cục bộ và sau đó chạy các quy trình ứng dụng trong Procfile của bạn.

Cách thứ hai nếu bạn đang tìm kiếm một cách tiếp cận nhẹ hơn là có tệp .env cục bộ rồi chạy:

export $(cat .env)

6

Cài đặt autoenv bằng cách

$ pip install autoenv

(hoặc là)

$ brew install autoenv

Và sau đó tạo .envtập tin trong thư mục dự án virtualenv của bạn

$ echo "source bin/activate" > .env

Bây giờ mọi thứ hoạt động tốt.


3

Nếu bạn đã sử dụng Heroku, hãy xem xét việc chạy máy chủ của bạn thông qua Foreman . Nó hỗ trợ một .envtệp chỉ đơn giản là một danh sách các dòng KEY=VALsẽ được xuất sang ứng dụng của bạn trước khi nó chạy.


3

Một cách khác để làm điều đó được thiết kế cho django, nhưng nên hoạt động trong hầu hết các cài đặt, là sử dụng django-dotenv.


1

Để kích hoạt virtualenv trong envthư mục và xuất các biến envinroment được lưu trữ trong .envsử dụng:

source env/bin/activate && set -a; source .env; set +a

lưu vào bí danh vớiecho 'alias e=". env/bin/activate && set -a; source .env; set +a"' >> ~/.bash_aliases
Daniil Mashkin
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.