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. Recibo ImportErrors ya que faltan algunas entradas en sys.path.
python
environment-variables
virtualenv
guettli
fuente
fuente

Respuestas:
El virtualenv está "integrado en el intérprete de Python en el virtualenv". Esto significa que puede iniciar
pythonoconsole_scriptsdirectamente en ese virtualenv y no necesita activar primero el virtualenv o administrarsePATHusted mismo:ExecStart={{ venv_home }}/bin/fooservice --serve-in-foregroundo
ExecStart={{ venv_home }}/bin/python {{ venv_home }}/fooservice.py --serve-in-foregroundy elimine la
EnvironmentFileentrada.Para verificar que sea correcto, puede verificar
sys.pathejecutandoy comparando la salida con
fuente
python -m sitepara obtener una salida con un formato agradable de la variable sys.path junto con información adicional.python -m site. He ajustado mi respuesta.Si bien la ruta de las bibliotecas está integrada en el intérprete de Python del virtualenv, he tenido problemas con las herramientas de Python que usaban binarios instalados en ese virtualenv. Por ejemplo, mi servicio de flujo de aire apache no funcionaría porque no pudo encontrar el
gunicornbinario. Para solucionar esto, aquí está miExecStartinstrucción, con unaEnvironmentinstrucción (que establece una variable de entorno solo para el servicio).ExecStart={{ virtualenv }}/bin/python {{ virtualenv }}/bin/airflow webserver Environment="PATH={{ virtualenv }}/bin:{{ ansible_env.PATH }}"ExecStartutiliza explícitamente el intérprete de Python del virtualenv. También estoy agregando unaPATHvariable, que agrega la carpeta binaria del virtualenv antes del sistemaPATH. De esa manera, obtengo las bibliotecas de Python deseadas, así como los binarios.Tenga en cuenta que estoy usando ansible para construir este servicio, ergo las llaves de jinja2.
fuente
No estoy usando virtualenv sino pyenv: aquí está solo para usar la ruta .pyenv real en el shebang y asegurarse de que esté en la RUTA
Ejemplo: pyenv activa flask-prod para el usuario mortenb que se ejecuta en prod
/home/mortenb/.pyenv/versions/flask-prod/bin/python --version Python 3.6.2Luego, a mis scripts de matraces que comienzan en systemd * .service, agrego el siguiente shebang:
#!/home/mortenb/.pyenv/versions/flask-prod/bin/python3fuente
En mi caso, solo intenté agregar variables de entorno requeridas para Flask, por ejemplo
[Service] Environment="PATH=/xx/yy/zz/venv/bin" Environment="FLASK_ENV=development" Environment="APP_SETTINGS=config.DevelopmentConfig"Estaba usando virtualenv, así que
/xx/yy/zz/venv/bines la ruta de la carpeta virtualenv.fuente