J'ai une application de base Django rest dans mon serveur Digital Ocean (Ubuntu 16.04) avec un environnement virtuel local. Le wsgi.py de base est:
import os
os.environ.setdefault("Django_SETTINGS_MODULE", "workout_rest.settings")
# This application object is used by any WSGI server configured to use this
# file. This includes Django's development server, if the WSGI_APPLICATION
# setting points here.
from Django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
# Apply WSGI middleware here.
# from helloworld.wsgi import HelloWorldApplication
# application = HelloWorldApplication(application)
J'ai suivi étape par étape ce tutoriel: https://www.digitalocean.com/community/tutorials/how-to-set-up-Django-with-postgres-nginx-and-gunicorn-on-ubuntu -16-04
Lorsque je teste la capacité de Gunicorn à servir le projet avec cette commande: gunicorn --bind 0.0.0.0:8000 myproject.wsgi: application Tout fonctionne bien.
J'ai donc essayé de configurer Gunicorn pour utiliser le fichier de service systemd. Mon fichier /etc/systemd/system/gunicorn.service est:
[Unit]
Description=gunicorn daemon
After=network.target
[Service]
User=ben
Group=www-data
WorkingDirectory=/home/ben/myproject
ExecStart=/home/ben/myproject/myprojectenv/bin/gunicorn --workers 3 --bind unix:/home/ben/myproject/myproject.sock myproject.wsgi:application
[Install]
WantedBy=multi-user.target
Ma configuration Nginx est:
server {
listen 8000;
server_name server_domain_or_IP;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/ben/myproject;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/ben/myproject/myproject.sock;
}
}
J'ai changé le port d'écoute de 80 à 8000 car 80 me donne une erreur err_connection_refused. Après avoir démarré le serveur avec cette commande:
Sudo systemctl restart nginx
Lorsque j'essaie d'exécuter mon site Web, j'obtiens une erreur 502 Bad Gateway. J'ai essayé ces commandes (trouvées dans les commentaires du tutoriel):
Sudo systemctl daemon-reload
Sudo systemctl start gunicorn
Sudo systemctl enable gunicorn
Sudo systemctl restart nginx
mais rien ne change. Quand je regarde les journaux Nginix avec cette commande:
Sudo tail -f /var/log/nginx/error.log
Je peux lire que le fichier de chaussettes n'existe pas:
2016/10/07 09:00:18 [crit] 24974#24974: *1 connect() to unix:/home/ben/myproject/myproject.sock failed (2: No such file or directory) while connecting to upstream, client: 86.197.20.27, server: 139.59.150.116, request: "GET / HTTP/1.1", upstream: "http://unix:/home/ben/myproject/myproject.sock:/", Host: "server_ip_adress:8000"
Pourquoi ce fichier chaussette n'est pas créé? Comment puis-je configurer Django/gunicorn pour créer ce fichier? J'ai ajouté gunicorn dans mon INSTALLED_APP dans mon projet Django mais cela ne change rien.
MODIFIER:
Lorsque je teste le fichier de configuration nginx avec nginx -t
, J'obtiens une erreur: open() "/run/nginx.pid" failed (13: Permission denied)
. Mais si j'exécute la commande avec Sudo: Sudo nginx -t
, Le test réussit. Est-ce à dire que je dois autoriser l'utilisateur "ben" à exécuter Ngnix?
À propos du fichier journal gunicorn, je ne trouve pas de moyen de les lire. Où sont-ils stockés?
Lorsque je vérifie si gunicorn fonctionne en utilisant ps aux | grep gunicorn
:
ben 26543 0.0 0.2 14512 1016 pts/0 S+ 14:52 0:00 grep --color=auto gunicorn
Voici ce qui se passe lorsque vous exécutez les commandes systemctl enable et start pour gunicorn:
Sudo systemctl enable gunicorn
Synchronizing state of gunicorn.service with SysV init with /lib/systemd/systemd-sysv-install...
Executing /lib/systemd/systemd-sysv-install enable gunicorn
Sudo systemctl start gunicorn
I get no output with this command
Sudo systemctl is-active gunicorn
active
Sudo systemctl status gunicorn
● gunicorn.service - gunicorn daemon
Loaded: loaded (/etc/systemd/system/gunicorn.service; enabled; vendor preset: enabled)
Active: active (exited) since Thu 2016-10-06 15:40:29 UTC; 23h ago
Oct 06 15:40:29 DevUsine systemd[1]: Started gunicorn.service.
Oct 06 18:52:56 DevUsine systemd[1]: Started gunicorn.service.
Oct 06 20:55:05 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 20:55:17 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:07:36 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:16:42 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:21:38 DevUsine systemd[1]: Started gunicorn daemon.
Oct 06 21:25:28 DevUsine systemd[1]: Started gunicorn daemon.
Oct 07 08:58:43 DevUsine systemd[1]: Started gunicorn daemon.
Oct 07 15:01:22 DevUsine systemd[1]: Started gunicorn daemon.
J'ai dû changer les permissions de mon dossier chaussette:
Sudo chown ben:www-data /home/ben/myproject/
Une autre chose est que j'ai changé l'emplacement de la chaussette après avoir lu dans de nombreux articles que ce n'est pas une bonne pratique de conserver le fichier de la chaussette dans le projet Django. Mon nouvel emplacement est:
/home/ben/run/
N'oubliez pas de modifier les autorisations:
Sudo chown ben:www-data /home/ben/run/
Pour être sûr que gunicorn est actualisé, exécutez ces commandes:
pkill gunicorn
Sudo systemctl daemon-reload
Sudo systemctl start gunicorn
Cela tuera les processus gunicorn et en commencera de nouveaux.
Vous pouvez exécuter cette commande pour démarrer le processus au démarrage du serveur:
Sudo systemctl enable gunicorn
Tout fonctionne bien maintenant.
Bien que la réponse acceptée fonctionne, il y a un problème (imo majeur), à savoir que le serveur Web gunicorn fonctionne (probablement) en tant que root, ce qui n'est pas recommandé. La raison pour laquelle vous finissez par avoir besoin de chown le socket est parce qu'il appartient à root:root
, car il s'agit de l'utilisateur/groupe que votre tâche init suppose par défaut. Il existe plusieurs façons d'obtenir que votre travail assume un autre rôle. À partir de ce moment (avec gunicorn 19.9.0), à mon avis, la solution la plus simple est d'utiliser le --user
et --group
drapeaux fournis dans le cadre de la commande gunicorn
. Cela signifie que votre serveur peut démarrer avec l'utilisateur/groupe que vous spécifiez. Dans ton cas:
exec gunicorn --user ben --group www-data --bind unix:/home/ben/myproject/myproject.sock -m 007 wsgi
commencera gunicorn sous ben:www-data
utilisateur et créer un socket appartenant à ben:www-data
avec les autorisations 770
, ou privilège lecture/écriture/exécution pour l'utilisateur ben
et le groupe www-data
sur la prise, ce qui est exactement ce que vous avez fait dans ce cas.
J'ai donné le chemin vers le fichier chaussette en dehors de mon projet. Je devais simplement créer le répertoire afin que le gunicorn puisse créer le fichier à l'intérieur de ce répertoire comme j'avais mentionné ce chemin dans le fichier .services. Fondamentalement, je me suis assuré que tous les répertoires existaient selon le chemin dans le fichier .services. Pas besoin de changer les autorisations ou la propriété