จะเปิดใช้งาน Virtualenv ในหน่วยบริการ systemd ได้อย่างไร?


87

ฉันต้องการ "เปิดใช้งาน" Virtualenv ในไฟล์บริการ systemd

ฉันต้องการหลีกเลี่ยงที่จะมีกระบวนการเชลล์ระหว่างกระบวนการ systemd และตัวแปล python

โซลูชันปัจจุบันของฉันมีลักษณะดังนี้:

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

แต่ฉันกำลังมีปัญหา ฉันได้รับ ImportErrors เนื่องจากบางรายการใน sys.path หายไป


คุณสามารถระบุข้อผิดพลาดที่คุณได้รับได้หรือไม่?
Praveen Yalagandula

@PraveenYalagandula การย้อนกลับไม่มีข้อมูลที่เป็นประโยชน์ใด ๆ เนื่องจากข้อยกเว้น ImportError และทุกบรรทัดด้านบนมีเฉพาะโค้ดที่กำหนดเองซึ่งไม่สำคัญที่นี่
guettli

คำตอบ:


117

Virtualenv คือ "รวมเข้ากับล่าม Python ใน Virtualenv" ซึ่งหมายความว่าคุณสามารถเปิดใช้งานpythonหรือconsole_scriptsใน Virtualenv ได้โดยตรงและไม่จำเป็นต้องเปิดใช้งาน Virtualenv ก่อนหรือจัดการPATHตัวเอง:

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

หรือ

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

และลบEnvironmentFileรายการ

เพื่อตรวจสอบว่าถูกต้องจริงๆคุณสามารถตรวจสอบได้sys.pathโดยการรัน

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

และเปรียบเทียบผลลัพธ์กับ

python -m site

2
จุดที่ดี Nils Btw, fooservice.py ไม่สมเหตุสมผลที่จะอยู่ในไดเรกทอรี venv_home ฉันคิดว่ามันพิมพ์ผิดในคำถาม
stelios

4
โปรดทราบว่าคำสั่งพิมพ์ที่แนะนำใช้ไม่ได้กับ Python 3 หากคุณใช้ python 2.4 เป็นอย่างน้อยคุณสามารถใช้: python -m siteเพื่อรับเอาต์พุตที่จัดรูปแบบไว้อย่างสวยงามของตัวแปร sys.path พร้อมกับข้อมูลเพิ่มเติม
Mark Edington

2
python -m siteเรียบร้อยผมไม่ทราบเกี่ยวกับ ฉันได้ปรับคำตอบของฉันแล้ว
Nils Werner

1
@NilsWerner ฉันลงเอยด้วยการแก้ปัญหาโดยการวางไข่เปลือกไม่มีอะไรทำงานบน Ubuntu 17.10: github.com/umccr/pcgr-deploy/blob/master/ansible/files/… ... โปรดละเว้น jinja2 templating สำหรับ ansible มัน ขยายได้อย่างถูกต้องเมื่อปรับใช้
ระดมความคิด

6
สำหรับผู้ที่สงสัยว่านี่คือ ninja2 .... ไม่วงเล็บปีกกาสองชั้นเป็นเพียงตัวยึดตำแหน่งที่ OP คิดค้น: superuser.com/questions/1209919/…
ankostis

12

ในขณะที่เส้นทางสำหรับไลบรารีถูกรวมเข้ากับตัวแปล python ของ Virtualenv แต่ฉันมีปัญหากับเครื่องมือ python ที่ใช้ไบนารีที่ติดตั้งใน Virtualenv ตัวอย่างเช่นบริการ apache airflow ของฉันไม่ทำงานเพราะไม่พบgunicornไบนารี ในการแก้ไขปัญหานี้นี่คือExecStartคำสั่งของฉันพร้อมด้วยEnvironmentคำสั่ง (ซึ่งตั้งค่าตัวแปรสภาพแวดล้อมสำหรับบริการเพียงอย่างเดียว)

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

ExecStartใช้ล่ามหลามของ Virtualenv อย่างชัดเจน ฉันยังเพิ่มPATHตัวแปรซึ่งจะเพิ่มโฟลเดอร์ไบนารีของ Virtualenv ก่อนระบบPATHก่อนระบบ ด้วยวิธีนี้ฉันจะได้รับไลบรารี python และไบนารีที่ต้องการ

โปรดทราบว่าฉันใช้ ansible เพื่อสร้างบริการนี้โดยใช้เครื่องหมายปีกกาของ jinja2


1

ฉันไม่ได้ใช้ Virtualenv แต่ pyenv: นี่เป็นเพียงการใช้เส้นทาง. pyenv จริงใน shebang และตรวจสอบให้แน่ใจว่าอยู่ใน PATH

เช่น pyenv เปิดใช้งาน flask-prod สำหรับ user mortenb ที่กำลังทำงานใน prod

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

จากนั้นในสคริปต์ขวดของฉันเริ่มต้นใน systemd * .service ฉันเพิ่ม shebang ต่อไปนี้:

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

0

ในกรณีของฉันฉันแค่พยายามเพิ่มตัวแปรสภาพแวดล้อมที่จำเป็นสำหรับ Flask เป็นต้น

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

ฉันใช้ Virtualenv ดังนั้น/xx/yy/zz/venv/binเส้นทางของโฟลเดอร์ Virtualenv

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.