Làm cách nào để kích hoạt virtualenv trong đơn vị dịch vụ systemd?


85

Tôi muốn "kích hoạt" virtualenv trong tệp dịch vụ systemd.

Tôi muốn tránh có một quy trình trình bao giữa quy trình systemd và trình thông dịch python.

Giải pháp hiện tại của tôi trông như thế này:

[Unit]
Description=fooservice
After=syslog.target network.target

[Service]
Type=simple
User=fooservice
WorkingDirectory={{ venv_home }}
ExecStart={{ venv_home }}/fooservice --serve-in-foreground
Restart=on-abort
EnvironmentFile=/etc/sysconfig/fooservice.env

[Install]
WantedBy=multi-user.target

/etc/sysconfig/fooservice.env

PATH={{ venv_home }}/bin:/usr/local/bin:/usr/bin:/bin
PYTHONIOENCODING=utf-8
PYTHONPATH={{ venv_home }}/...
VIRTUAL_ENV={{ venv_home }}

Nhưng tôi đang gặp khó khăn. Tôi nhận được ImportErrors vì một số enties trong sys.path bị thiếu.


Bạn có thể vui lòng bao gồm các lỗi bạn đang nhận được?
Praveen Yalagandula

@PraveenYalagandula Truy nguyên không chứa bất kỳ thông tin hữu ích nào, vì Ngoại lệ ImportError và tất cả các dòng phía trên nó chỉ chứa mã tùy chỉnh không quan trọng ở đây.
guettli

Câu trả lời:


112

Virtualenv được "đưa vào trình thông dịch Python trong virtualenv". Điều này có nghĩa là bạn có thể khởi chạy pythonhoặc console_scriptstrực tiếp trong virtualenv đó và không cần phải kích hoạt virtualenv trước hoặc PATHtự quản lý :

ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground

hoặc là

ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground

và xóa EnvironmentFilemục nhập.

Để xác minh rằng nó thực sự đúng, bạn có thể kiểm tra sys.pathbằng cách chạy

{{ venv_home }}/bin/python -m site

và so sánh đầu ra với

python -m site

2
Nils điểm tốt. Btw, fooservice.py không có ý nghĩa gì khi nằm trong thư mục venv_home, tôi cho rằng đó là lỗi đánh máy trong câu hỏi.
stelios

4
Lưu ý rằng các lệnh in được đề xuất không tương thích với Python 3. Nếu bạn đang sử dụng ít nhất python 2.4, bạn có thể chỉ cần sử dụng: python -m siteđể có được đầu ra được định dạng độc đáo của biến sys.path cùng với thông tin bổ sung.
Mark Edington

2
Gọn gàng, tôi không biết về python -m site. Tôi đã điều chỉnh câu trả lời của mình.
Nils Werner

1
@NilsWerner Tôi đã kết thúc việc giải quyết nó bằng cách tạo ra một trình bao, không có gì khác hoạt động trên Ubuntu 17.10: github.com/umccr/pcgr-deploy/blob/master/ansible/files/… ... vui lòng bỏ qua khuôn mẫu jinja2 cho ansible, nó mở rộng chính xác khi được triển khai.
brainstorm

6
Đối với những người tự hỏi nếu điều này là ninja2 .... không, đôi xoăn-niềng răng chỉ là placeholders OP phát minh: superuser.com/questions/1209919/...
ankostis

11

Mặc dù đường dẫn cho các thư viện thực sự được đưa vào trình thông dịch python của virtualenv, nhưng tôi đã gặp sự cố với các công cụ python đang sử dụng các tệp nhị phân được cài đặt trong virtualenv đó. Ví dụ: dịch vụ luồng không khí apache của tôi sẽ không hoạt động vì nó không thể tìm thấy gunicorntệp nhị phân. Để giải quyết vấn đề này, đây là ExecStarthướng dẫn của tôi , với một Environmenthướng dẫn (đặt một biến môi trường cho riêng dịch vụ).

ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver
Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"

ExecStartsử dụng rõ ràng trình thông dịch python của virtualenv. Tôi cũng đang thêm một PATHbiến, thêm thư mục nhị phân của virtualenv trước hệ thống PATH. Bằng cách đó, tôi nhận được các thư viện python cũng như các tệp nhị phân mong muốn.

Lưu ý rằng tôi đang sử dụng ansible để xây dựng dịch vụ này, hãy bỏ qua các dấu ngoặc nhọn của jinja2.


1

Tôi không sử dụng virtualenv mà là pyenv: đây chỉ là sử dụng đường dẫn .pyenv thực trong shebang và đảm bảo rằng nó nằm trong PATH

Ví dụ: pyenv kích hoạt flask-prod cho người dùng mortenb đang chạy trong prod

/home/mortenb/.pyenv/versions/flask-prod/bin/python --version
Python 3.6.2

Sau đó, đến các tập lệnh bình của tôi bắt đầu trong systemd * .service, tôi thêm shebang sau:

#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3

0

Trong trường hợp của tôi, tôi chỉ cố gắng thêm các biến môi trường cần thiết cho Flask, chẳng hạn

[Service]
Environment="PATH=/xx/yy/zz/venv/bin"
Environment="FLASK_ENV=development"
Environment="APP_SETTINGS=config.DevelopmentConfig"

Tôi đã sử dụng virtualenv vì vậy /xx/yy/zz/venv/binđường dẫn của thư mục virtualenv cũng vậy.

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.