0

J'ai une application Django qui fonctionne sur Gunicorn, et est géré par SupervisorD qui est géré par Ansible.Comment passer la variable d'environnement shell au programme Supervisor?

Je veux que Django lise la variable DJANGO_SECRET_KEY de l'environnement, puisque je ne veux pas stocker ma clé secrète dans un fichier de configuration ou VCS. Pour que je lis la clé de l'environnement dans mon settings.py:

SECRET_KEY = os.environ['DJANGO_SECRET_KEY'] 

En regardant Supervisor docs il dit:

Remarque que le sous-processus héritera des variables d'environnement du shell utilisé pour démarrer « superviseur "sauf pour ceux qui sont remplacés ici. Voir Environnement de sous-processus.

Voici mon supervisor.conf:

[program:gunicorn] 
command=/.../.virtualenvs/homepage/bin/gunicorn homepage.wsgi -w 1 --bind localhost:8001 --pid /tmp/gunicorn.pid 
directory=/.../http/homepage 

Quand je mets la variable et exécutez la commande gunicorn à partir du shell, il démarre très bien:

$ DJANGO_SECRET_KEY=XXX /.../.virtualenvs/homepage/bin/gunicorn homepage.wsgi -w 1 --bind localhost:8001 --pid /tmp/gunicorn.pid 

Cependant quand je mets la variable le shell et redémarrez le service de superviseur mon application ne démarre pas avec l'erreur sur la variable non trouvée:

$ DJANGO_SECRET_KEY=XXX supervisorctl restart gunicorn 
gunicorn: ERROR (not running) 
gunicorn: ERROR (spawn error) 

Regarder erreur Superviseur journal:

File "/.../http/homepage/homepage/settings.py", line 21, in <module> 
    SECRET_KEY = os.environ['DJANGO_SECRET_KEY'] 
    File "/.../.virtualenvs/homepage/lib/python2.7/UserDict.py", line 40, in __getitem__ 
    raise KeyError(key) 
KeyError: 'DJANGO_SECRET_KEY' 
[2017-08-27 08:22:09 +0000] [19353] [INFO] Worker exiting (pid: 19353) 
[2017-08-27 08:22:09 +0000] [19349] [INFO] Shutting down: Master 
[2017-08-27 08:22:09 +0000] [19349] [INFO] Reason: Worker failed to boot. 

J'ai aussi essayé de redémarrer le service superviseur, mais même erreur se produit:

$ DJANGO_SECRET_KEY=XXX systemctl restart supervisor 
... 
INFO exited: gunicorn (exit status 3; not expected) 

Ma question est de savoir comment puis-je faire superviseur à « pass » variables d'environnement à ses processus de l'enfant?

+1

C'est complètement à l'envers. Le superviseur ne fonctionne pas sous votre ID utilisateur. Vous devriez définir la variable dans la configuration du superviseur, et non l'inverse. –

+0

@DanielRoseman J'ai mon superviseur config dans VCS, donc je ne peux pas mettre ma clé secrète dedans. –

+1

La lecture de la variable d'environnement 'DJANGO_SECRET_KEY' n'est pas liée au superviseur conf. Vous ne savez pas comment vous le faites, mais vous pouvez utiliser 'os.environ.get ('DJANGO_SECRET_KEY')' pour attribuer une valeur dans notre fichier de paramètres django. vous pouvez également utiliser un paquet comme 'django-environ' pour ça. – demonno

Répondre

0

Créez un fichier exécutable similaire à celui-ci et essayez de le démarrer manuellement. i.e. créer fichier et copie script ci-dessous /home/user/start_django.sh

Vous devez remplir DJANGODIR et effectuer d'autres ajustements en fonction de votre cas. De plus, vous devrez peut-être ajuster les autorisations en conséquence. Si elle démarre manuellement, utilisez simplement ce fichier dans votre fichier. Conf.

[program:django_project] 
command = /home/user/start_django.sh 
user = {your user} 
stdout_logfile = /var/log/django.log 
redirect_stderr = true 
# you can also try to define enviroment variables in this conf 
environment=LANG=en_US.UTF-8,LC_ALL=en_US.UTF-8,DJANGO_SECRET_KEY=XXX 

références qui pourraient être utiles,

+0

Hmm, alors comment gérer 'start_django.sh'? Je ne peux pas le mettre en contrôle de version car il contient une clé secrète. J'aurais pu tout aussi bien mettre ma clé secrète dans 'settings.py' ou' supervor.conf', mais le problème est que ces fichiers sont aussi sous contrôle de version. –

+0

Je pense qu'il est possible d'ajouter une ligne dans le script bash proposé qui exporte les variables env à partir d'un fichier externe (non suivi par le contrôle de version). Mais personnellement, je préférerais utiliser 'django-environ' qui peut être configuré pour lire toutes les variables du fichier' .env'. – demonno

0

OK figured it moi-même. Il s'avère qu'Ableible a une fonctionnalité appelée Vault, qui est utilisée pour exactement ce genre de travaux - cryptage des clés.

Maintenant, j'ajouté la clé secrète voûte aux host_vars de Ansible, voir: Vault: single encrypted variable et Inventory: Splitting out host and group specific data.

J'ai ajouté une tâche à mon ansible PlayBook pour copier le fichier clé de voûte ansible au serveur:

- name: copy django secret key to server 
    copy: content="{{ django_secret_key }}" dest=/.../http/homepage/deploy/django_secret_key.txt mode=0600 

Et fait Django lire le secret de ce fichier:

with open(os.path.join(BASE_DIR, 'deploy', 'django_secret_key.txt')) as secret_key_file: 
    SECRET_KEY = secret_key_file.read().strip() 

Si quelqu'un a une solution plus simple/meilleure, veuillez la poster et je l'accepterai comme réponse.