Quiero “activar” un virtualenv en un archivo de servicio systemd.
Me gustaría evitar tener un proceso de shell entre el proceso systemd y el intérprete de python.
Mi solución actual se ve así:
[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 }}
Pero estoy teniendo problemas. Obtengo ImportErrors ya que faltan algunas entidades en sys.path.
El virtualenv es “incorporado al intérprete de Python en el virtualenv”. Esto significa que puede iniciar python
o console_scripts
directamente en ese virtualenv y no necesita activar el virtualenv primero o administrar PATH
usted mismo:
ExecStart={{ venv_home }}/bin/fooservice --serve-in-foreground
o
ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foreground
y elimine la entrada de EnvironmentFile
.
Para verificar que es correcto, puede verificar sys.path
ejecutando
{{ venv_home }}/bin/python -m site
y comparando la salida a
python -m site
No estoy usando virtualenv pero pyenv: aquí está solo para usar la ruta real .pyenv en el shebang y asegurarme de que esté en el PATH
Ej: pyenv active flask-prod para el usuario mortenb que se ejecuta en prod.
/home/mortenb/.pyenv/versions/flask-prod/bin/python --version Python 3.6.2
Luego, a mis scripts de matraz que comienzan en systemd * .service agrego el siguiente shebang:
#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3