Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Supervisor et variable d'environnement

+1 vote

Je déploie une application web (python 3 - flask - gunicorn - nginx) sur un serveur Debian 8, avec ansible (mais ce n'est vraisemblablement pas ansible le problème).

Tout fonctionne à merveille jusqu'à ce que je crée et utilise une variable d'environnement, que je "lie", dans mon application, à un fichier de config de cette manière:

app.config.from_object(os.environ['APP_SETTINGS'])

Là, le déploiement ne fonctionne plus alors que je n'ai pas modifié les configs nginx/gunicorn/supervisor.

J'identifie que le problème tourne autour de supervisor, qui n'a pas lancé gunicorn. Quand je lance moi-même la commande sudo supervisorctl (re)start {{ project_name }}, j'obtiens l'erreur "ERROR (abnormal termination)".

Un petit tour par les logs montre:

error: <class 'socket.error'>, [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 224

Pourtant, j'ai normalement bien les droits.

Le fichier /etc/supervisor/conf.d/{{ project_name }}.conf contient:

[program:{{ project_name }}]
command=/home/{{ user }}/venv/bin/gunicorn app:app -b localhost:8000
directory = /home/{{ user }}/{{ project_name }}
user = {{ user }}

Je ne comprends pas pourquoi supervisor plante parce que:

  • tout fonctionne bien en localhost (avec le serveur intégré à flask);

Coté serveur:

  • ma variable d'environnement est correctement déclarée et prise en compte (vérification avec ipython et print(app.config));
  • si je lance manuellement gunicorn en utilisant la commande de la ligne 2 de mon fichier de config de supervisor, ci-dessus, tout fonctionne également;
  • si je commente la ligne de config app.config.from_object(os.environ['APP_SETTINGS']) dans mon app, sans rien toucher au reste, supervisor (et donc le déploiement automatique) refonctionne...

D'où mes questions:

  1. Pourquoi supervisor bloque-t-il soudainement avec app.config.from_object(os.environ['APP_SETTINGS'])?
  2. Supervisor ne se contente-t-il pas de lancer gunicorn sans se soucier du reste?
  3. Est-ce lié au fait que supervisor tourne en python 2 et mon app en python 3 dans un virtualenv?
  4. Qu'est ce que j'ai loupé?

N'arrivant pas à déclarer ma variable d'environnement dans /etc/supervisor/conf.d/{{ project_name }}.conf (environment=APP_SETTINGS=Test n'a aucun effet), je l'ai déclarée dans mon environnement virtuel). Dernière question:

  • Pourquoi la variable d'environnement n'est-elle pas prise en compte si je la déclare dans mon fichier de config de supervisor?
demandé 21-Nov-2015 par meta (208 points)
edité 25-Nov-2015 par foxmask

2 Réponses

+3 votes
error: <class 'socket.error'>, [Errno 13] Permission denied: file: /usr/lib/python2.7/socket.py line: 224

On dirait que tu essaies d'ouvrir un port en dessous de 1024 (seul root peut le faire) : que contient ton fichier de config pointé par APP_SETTINGS?

je l'ai déclarée dans mon environnement virtuel

Si tu l'as déclarée dans le script bin/postactivate, je dirais que ce script est uniquement executé lorsquetu fais un workon, donc pas éxécuté par supervisor.

Est-ce lié au fait que supervisor tourne en python 2 et mon app en python 3 dans un virtualenv?

Aucun soucis de ce coté la.

Pourquoi la variable d'environnement n'est-elle pas prise en compte si je la déclare dans mon fichier de config de supervisor?

Pour en etre sur, tu peux tenter de logguer tout ton environement au démarage de ton app. Au pire remplaces l'appel a gunicorn par un script qui fait juste import os; print(os.environ), ca te permettra d'inspecter.

répondu 22-Nov-2015 par jc (2,674 points)

Ma variable d'environnement est déclarée dans le script bin/activate (puisque je n'arrivais pas à ce qu'elle soit prise en compte si déclarée dans le fichier de config de supervisor). Du coup, elle devrait être prise en compte en lançant gunicorn dans mon virtualenv, non?

Le fichier de config de mon app contient quelques classes basiques (Config <- DevConfig, ProdConfig...) qui, pour l'instant, se contentent de fournir une valeur à certaines variables prises en compte par Flask, telles que SECRET_KEY et DEBUG.

Je n'essaye pas (du moins, consciemment^^) d'ouvrir de port en dessous de 1024 et de toute façon, j'exécute supervisor avec sudo.

Et si j'exécute supervisor sans conf pour mon app, tout se passe bien. la méthode from_object est supportée (si je lui passe directement une valeur; donc est ce que le problème pourrait venir de os.environ[]?

+1 vote

selon la doc http://supervisord.org/configuration.html on décrit la config comme ceci

environment=APP_SETTINGS="Test"

dans mes fichiers de config supervisor je fais ca pour les locales

environment=LANG="fr_FR.UTF-8", LC_ALL="fr_FR.UTF-8", LC_LANG="fr_FR.UTF-8"

supervisor est très chatouilleux je trouve, une virgule de traviole et la conf part en sucette

par exemple mettre

user = foxmask

lancera le process avec le user root, alors que

user=foxmask

le lancera bien avec l'id foxmask

répondu 25-Nov-2015 par foxmask (2,830 points)
edité 14-Jan-2016 par foxmask
...