web-dev-qa-db-ja.com

systemdサービスユニットでvirtualenvを有効にする方法は?

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が発生します。

59
guettli

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
82
Nils Werner

ライブラリのパスは実際にvirtualenvのpythonインタープリターに組み込まれていますが、そのvirtualenvにインストールされたバイナリを使用していたpythonツールに問題がありました。たとえば、Apacheエアフローサービスは、gunicornバイナリが見つからなかったため機能しません。これを回避するために、ここにExecStart命令とEnvironment命令(サービスのみの環境変数を設定する)があります。

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

ExecStartexplicitlyは、virtualenvのpythonインタープリターを使用します。システムPATHの前にvirtualenvのバイナリフォルダーを追加するPATH変数も追加しています。そうすれば、目的のpythonライブラリとバイナリを取得できます。

このサービスを構築するためにansibleを使用していることに注意してください。jinja2の中括弧を忘れないでください。

3
Alexis Lessard