Ich möchte eine virtuelle Umgebung in einer systemd-Dienstdatei "aktivieren".
Ich möchte vermeiden, einen Shell-Prozess zwischen dem systemd-Prozess und dem Python-Interpreter zu haben.
Meine aktuelle Lösung sieht folgendermaßen aus:
[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 }}
Aber ich habe Probleme. Ich erhalte ImportErrors, da einige Enties in sys.path fehlen.
python
environment-variables
virtualenv
guettli
quelle
quelle
Antworten:
Die virtuelle Umgebung wird "in die Python-Interpretation in der virtuellen Umgebung eingebrannt". Dies bedeutet, dass Sie diese virtuelle Umgebung starten
python
oderconsole_scripts
direkt in dieser virtuellen Umgebung starten können und die virtuelle Umgebung nicht zuerst aktivieren oderPATH
selbst verwalten müssen :ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground
oder
ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground
und entfernen Sie den
EnvironmentFile
Eintrag.Um zu überprüfen, ob es tatsächlich korrekt ist, können Sie dies
sys.path
durch Ausführen überprüfenund Vergleichen der Ausgabe mit
quelle
python -m site
Folgendes verwenden , um eine gut formatierte Ausgabe der Variablen sys.path zusammen mit zusätzlichen Informationen zu erhalten.python -m site
. Ich habe meine Antwort angepasst.Während der Pfad für Bibliotheken tatsächlich in den Python-Interpreter der virtuellen Umgebung eingebettet ist, hatte ich Probleme mit Python-Tools, die in dieser virtuellen Umgebung installierte Binärdateien verwendeten. Zum Beispiel würde mein Apache-Luftstromdienst nicht funktionieren, weil er die
gunicorn
Binärdatei nicht finden konnte . Um dies zu umgehen, ist hier meineExecStart
Anweisung mit einerEnvironment
Anweisung (die eine Umgebungsvariable nur für den Dienst festlegt).ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"
ExecStart
Verwendet explizit den Python-Interpreter der virtuellen Umgebung. IchPATH
füge auch eine Variable hinzu, die den Binärordner der virtuellen Umgebung vor dem System hinzufügtPATH
. Auf diese Weise erhalte ich die gewünschten Python-Bibliotheken sowie Binärdateien.Beachten Sie, dass ich ansible verwende, um diesen Service zu erstellen, also die geschweiften Klammern von jinja2.
quelle
Ich verwende nicht virtualenv, sondern pyenv: Hier ist es nur, um den realen .pyenv-Pfad im Shebang zu verwenden und sicherzustellen, dass er im PATH ist
Beispiel: pyenv aktiviert flask-prod für den Benutzer mortenb, der in prod ausgeführt wird
/home/mortenb/.pyenv/versions/flask-prod/bin/python --version Python 3.6.2
Dann füge ich meinen Kolbenskripten, die in systemd * .service beginnen, den folgenden Shebang hinzu:
#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3
quelle
In meinem Fall habe ich nur versucht, beispielsweise Umgebungsvariablen hinzuzufügen, die für Flask erforderlich sind
[Service] Environment="PATH=/xx/yy/zz/venv/bin" Environment="FLASK_ENV=development" Environment="APP_SETTINGS=config.DevelopmentConfig"
Ich habe virtualenv verwendet, also
/xx/yy/zz/venv/bin
ist der Pfad des virtualenv-Ordners.quelle