systemd 서비스 유닛에서 virtualenv를 활성화하는 방법은 무엇입니까?


85

systemd 서비스 파일에서 virtualenv를 "활성화"하고 싶습니다.

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

하지만 문제가 있습니다. sys.path의 일부 항목이 없기 때문에 ImportErrors가 발생합니다.


발생한 오류를 포함 해 주시겠습니까?
Praveen Yalagandula

@PraveenYalagandula 트레이스 백에는 유용한 정보가 포함되어 있지 않습니다. ImportError Exception과 그 위의 모든 줄에는 여기서 중요하지 않은 사용자 지정 코드 만 포함되어 있기 때문입니다.
guettli

답변:


112

virtualenv는 "virtualenv의 Python 인터프리터로 구워집니다". 즉 , 해당 virtualenv에서 직접 실행 python하거나 console_scripts직접 실행할 수 있으며 먼저 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 2017 년

2
깔끔한, 나는에 대해 몰랐다 python -m site. 내 대답을 조정했습니다.
닐스 베르너

1
@NilsWerner 셸을 생성하여 문제를 해결했으며 Ubuntu 17.10에서 다른 작업은 없었습니다. github.com/umccr/pcgr-deploy/blob/master/ansible/files/… ... ansible에 대한 jinja2 템플릿을 무시하십시오. 배포시 올바르게 확장됩니다.
브레인 스토밍

6
이, 아니 .... ninja2 경우 궁금 사람들을 위해 이중 곱슬 중괄호는 영업 이익은 발명 단지 자리는 다음과 같습니다 superuser.com/questions/1209919/...이
ankostis

11

라이브러리 경로는 실제로 virtualenv의 파이썬 인터프리터에 구워졌지만 해당 virtualenv에 설치된 바이너리를 사용하는 파이썬 도구에 문제가있었습니다. 예를 들어, 내 아파치 기류 서비스는 gunicorn바이너리를 찾을 수 없기 때문에 작동하지 않습니다 . 이 문제를 해결하기 위해 여기 ExecStartEnvironment지침 (서비스에 대한 환경 변수 만 설정) 과 함께 지침이 있습니다.

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

ExecStartvirtualenv의 파이썬 인터프리터를 명시 적으로 사용합니다. 또한 PATH시스템 앞에 virtualenv의 바이너리 폴더를 추가하는 변수를 추가하고 있습니다 PATH. 그렇게하면 원하는 파이썬 라이브러리와 바이너리를 얻을 수 있습니다.

이 서비스를 구축하기 위해 ansible을 사용하고 있습니다. jinja2의 중괄호를 사용하십시오.


1

나는 virtualenv가 아니라 pyenv를 사용하고 있습니다. 여기에 shebang에서 실제 .pyenv 경로를 사용하고 PATH에 있는지 확인하십시오.

예 : prod에서 실행중인 사용자 mortenb에 대한 pyenv activate flask-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/binvirtualenv 폴더의 경로입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.