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


87

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 2016年

@PraveenYalagandula ImportError例外とその上のすべての行には、ここでは関係のないカスタムコードのみが含まれているため、トレースバックには有用な情報は含まれていません。
guettli 2016年

回答:


117

virtualenvは、「virtualenvのPythonインタープリターに組み込まれています」。つまり、そのvirtualenvで起動するpythonconsole_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
良い点ニルス。ところで、fooservice.pyはvenv_homeディレクトリ内にあるのは意味がありません。質問のタイプミスだと思います。
stelios 2017年

4
推奨される印刷コマンドはpython -m sitePython3と互換性がないことに注意してください。少なくともpython2.4を使用している場合は、代わりに:を使用して、追加情報とともにsys.path変数の適切にフォーマットされた出力を取得できます。
マークエディントン2017年

2
きちんとした、私はについて知りませんでしたpython -m site。答えを調整しました。
Nils Werner

1
@NilsWernerシェルをスポーンすることで解決しましたが、Ubuntu 17.10では他に何も機能しませんでした:github.com/umccr/pcgr-deploy/blob/master/ansible/files/… ... ansibleをテンプレートしているjinja2は無視してください、それデプロイすると正しく拡張されます。
ブレインストーミング

6
これは、ありません.... ninja2であれば疑問に思う方のために、二重カーリーブレースは、OPが発明しただけのプレースホルダは、次のとおりです。superuser.com/questions/1209919/...は
ankostis

12

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

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

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

私はこのサービスを構築するためにansibleを使用していることに注意してください、jinja2の中括弧をエルゴします。


1

私はvirtualenvではなくpyenvを使用しています。これは、shebangで実際の.pyenvパスを使用し、それがPATHにあることを確認するためだけのものです。

例:pyenvは、prodで実行されているユーザーmortenbのflask-prodをアクティブ化します

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

次に、systemd * .serviceで始まるフラスコスクリプトに、次のシバンを追加します。

#!/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.