Bonjour!
Je viens poster ici un peu en guise de joker car je suis encore débutant en développement web, et que j'aurais besoin d'un peu d'aide, j'espère avoir choisi le bon endroit pour poster.
Je me suis beaucoup appuyé sur un livre pour découvrir Django, dont le chapitre sur la mise en production .
J'ai voulu m'exercer au passage en prod avec un petit projet de test réalisé avec django (permettant l'affichage d'une bête page de test).
Ce projet ("blog") contient juste une application ("news") avec un fichier de vues, contenant une unique vue qui renvoie du code html écrit directement dans le code en python pour le test de la mise en prod.
J'arrive à faire fonctionner ce petit projet avec runserver, il m'affiche correctement la page que DEBUG soit à False ou à True.
Je suis passé par plusieurs bugs avec la mise en prod, et j'avoue être un peu perdu quant à la cause de celui sur lequel je bloque actuellement, j'ai du mal à établir un diagnostique et localiser le soucis, et je parviens encore moins à le comprendre.
Le problème :
Lorsque j'essaie d'accéder à mon projet avec un navigateur j'obtiens une erreur 400 (bad request).
Je vais décrire ma config et ce qui marche, tout cela de manière exhaustive (je m'excuse d'ailleurs par avance pour la longueur) :
Général :
J'utilise un Raspberry Pi avec Arch ARM (Dérivée d'Archlinux).
J'ai installé dessus :
-Python 3.4
-Apache 2.4
-Django 1.6.5
-uwsgi 2.0
Tout le travail que je fait est en local, à titre expérimental.
Ce qui fonctionne :
-J'arrive à faire fonctionner plusieurs vhosts avec des pages statiques en html, en local.
-J'arrive à faire fonctionner mon projet Django avec runserver.
Voici à présent les fichiers de config :
- /etc/hosts que j'ai modifié pour utiliser les différents vhosts sans changer de port.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 # # /etc/hosts: static lookup table for host names # #<ip-address> <hostname.domain.org> <hostname> 127.0.0.1 localhost.localdomain localhost ::1 localhost.localdomain localhost 127.0.0.1 test.localhost.localdomain test.localhost 127.0.0.1 test.fr localhost 127.0.0.1 test.test.fr localhost 127.0.0.1 default.test.fr localhost 127.0.0.1 test_django.test.fr localhost # End of file
- /etc/httpd/conf/httpd.conf contient un include vers /etc/httpd/conf/extra/httpd-vhosts.conf et un LoadModule wsgi_module modules/mod_wsgi.so (pour WSGI).
- /etc/httpd/conf/extra/httpd-vhosts.conf
Le vhost concerné est test_django.test.fr.
- /var/www/test_django/conf/httpd-app.conf contient la conf du projet fait avec Django, il est inclus dans le fichier précédent (/etc/httpd/conf/extra/httpd-vhosts.conf).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 <Virtualhost test.test.fr:80> DocumentRoot "/var/www/test/htdocs" ServerName test.test.fr Include "/var/www/test/conf/httpd-app.conf" </VirtualHost> <VirtualHost default.test.fr:80> DocumentRoot "/var/www/default/htdocs" ServerName default.test.fr Include "/var/www/default/conf/httpd-app.conf" </VirtualHost> <VirtualHost test_django.test.fr:80> Include "/var/www/test_django/conf/httpd-app.conf" </VirtualHost> <VirtualHost test.fr:80> DocumentRoot "/srv/http" ServerName test.fr </VirtualHost>
Les lignes de configuration viennent de l'exemple.
Seulement la ligne avec WSGIPythonPath provoque une erreur dans un virtualhost au redémarrage d'Apache, j'ai donc du l'enlever mais je ne lui connais pas de substitut.
- /var/www/test_django/htdocs/blog/blog/settings.py, le fichier de configuration du projet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 WSGIScriptAlias / /var/www/test_django/htdocs/blog/blog/wsgi.py #WSGIPythonPath /var/www/test_django/htdocs/blog/blog DocumentRoot "/var/www/test_django/htdocs/blog/" ServerName test_django.test.fr <Directory /var/www/test_django/htdocs/blog/blog/ > #<Files wsgi.py> <IfVersion < 2.3 > Order allow,deny Allow from all </IfVersion> <IfVersion >= 2.3> Require all granted </IfVersion> #</Files> </Directory> <Directory /var/www/test_django/htdocs/blog/ > <IfVersion < 2.3 > Order allow,deny Allow from all </IfVersion> <IfVersion >= 2.3> Require all granted </IfVersion> </Directory>
-le fichier /var/www/test_django/htdocs/blog/blog/wsgi.py qui contient le script permettant de faire le lien entre Apache et Django du moins si j'ai bien compris.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 """ Django settings for blog project. For more information on this file, see https://docs.djangoproject.com/en/1.6/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/1.6/ref/settings/ """ # Build paths inside the project like this: os.path.join(BASE_DIR, ...) import os BASE_DIR = os.path.dirname(os.path.dirname(__file__)) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/1.6/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' # SECURITY WARNING: don't run with debug turned on in production! DEBUG = True TEMPLATE_DEBUG = True ADMINS = ( ('myName', 'myname@mail.fr'), ) #ALLOWED_HOSTS = ['test_django.test.fr', '127.0.0.1', 'localhost'] ALLOWED_HOSTS = '*' # Application definition INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'news', ) MIDDLEWARE_CLASSES = ( 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ) ROOT_URLCONF = 'blog.urls' WSGI_APPLICATION = 'blog.wsgi.application' TEMPLATE_DIRS = ( os.path.join(BASE_DIR, 'templates') ) # Database # https://docs.djangoproject.com/en/1.6/ref/settings/#databases DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': os.path.join(BASE_DIR, 'database.sql'), } } # Internationalization # https://docs.djangoproject.com/en/1.6/topics/i18n/ LANGUAGE_CODE = 'en-us' TIME_ZONE = 'Europe/Paris' USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/1.6/howto/static-files/ STATIC_URL = '/static/' APPEND_SLASH = True
Il a été un peu modifié par un ami pour résoudre une erreur 500, et je ne comprends pas forcément ce qui s'y trouve.
- le résultat d'un ls -lRa /var/www/test_django/htdocs/blog (pour l'arborescence de mon projet)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 """ WSGI config for blog project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/1.6/howto/deployment/wsgi/ """ #import os #os.environ.setdefault("DJANGO_SETTINGS_MODULE", "blog.settings") #from django.core.wsgi import get_wsgi_application #application = get_wsgi_application() import os, sys import django.conf.global_settings as DEFAULT_SETTINGS SETTINGS_DIR = os.path.dirname(__file__) PROJECT_PATH = os.path.join(SETTINGS_DIR, os.pardir) PROJECT_PATH = os.path.abspath(PROJECT_PATH) sys.path.append(PROJECT_PATH) os.environ['DJANGO_SETTINGS_MODULE'] = 'blog.settings' #### Security os.environ['HTTPS']= "on" import django.core.handlers.wsgi _application = django.core.handlers.wsgi.WSGIHandler() def application(environ, start_response): #environ['SCRIPT_NAME'] = '/' environ['PATH_INFO'] = environ['SCRIPT_NAME'] + environ['PATH_INFO'] return _application(environ, start_response)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48 /var/www/test_django/htdocs/blog: total 20 drwxr-xr-x 4 vmonteco users 4096 Jan 1 21:31 . drwxr-xr-x 4 vmonteco root 4096 Dec 31 22:10 .. drwxr-xr-x 3 vmonteco users 4096 Jan 1 21:54 blog -rwxr-xr-x 1 vmonteco users 248 Jan 20 1970 manage.py drwxr-xr-x 3 vmonteco root 4096 Jan 1 21:54 news /var/www/test_django/htdocs/blog/blog: total 24 drwxr-xr-x 3 vmonteco users 4096 Jan 1 21:54 . drwxr-xr-x 4 vmonteco users 4096 Jan 1 21:31 .. -rwxr-xr-x 1 vmonteco users 0 Jan 20 1970 __init__.py drwxr-xr-x 2 vmonteco users 4096 Jan 1 18:54 __pycache__ -rwxr-xr-x 1 vmonteco users 2209 Jan 1 18:49 settings.py -rwxr-xr-x 1 vmonteco users 333 Jan 1 18:38 urls.py -rwxr-xr-x 1 vmonteco users 1015 Jan 1 18:32 wsgi.py /var/www/test_django/htdocs/blog/blog/__pycache__: total 24 drwxr-xr-x 2 vmonteco users 4096 Jan 1 18:54 . drwxr-xr-x 3 vmonteco users 4096 Jan 1 21:54 .. -rwxr-xr-x 1 vmonteco users 132 Jan 20 1970 __init__.cpython-34.pyc -rw-r--r-- 1 root root 1728 Jan 1 18:53 settings.cpython-34.pyc -rw-r--r-- 1 root root 402 Jan 1 18:54 urls.cpython-34.pyc -rw-r--r-- 1 root root 1045 Jan 1 18:54 wsgi.cpython-34.pyc /var/www/test_django/htdocs/blog/news: total 32 drwxr-xr-x 3 vmonteco root 4096 Jan 1 21:54 . drwxr-xr-x 4 vmonteco users 4096 Jan 1 21:31 .. -rwxr-xr-x 1 vmonteco root 0 Dec 31 21:51 __init__.py drwxr-xr-x 2 vmonteco root 4096 Jan 1 18:54 __pycache__ -rwxr-xr-x 1 vmonteco root 63 Dec 31 21:51 admin.py -rwxr-xr-x 1 vmonteco root 57 Dec 31 21:51 models.py -rwxr-xr-x 1 vmonteco root 60 Dec 31 21:51 tests.py -rw-r--r-- 1 vmonteco users 135 Dec 31 22:24 urls.py -rwxr-xr-x 1 vmonteco root 308 Jan 1 18:52 views.py /var/www/test_django/htdocs/blog/news/__pycache__: total 28 drwxr-xr-x 2 vmonteco root 4096 Jan 1 18:54 . drwxr-xr-x 3 vmonteco root 4096 Jan 1 21:54 .. -rwxr-xr-x 1 vmonteco root 132 Dec 31 22:11 __init__.cpython-34.pyc -rwxr-xr-x 1 vmonteco root 177 Dec 31 22:11 admin.cpython-34.pyc -rwxr-xr-x 1 vmonteco root 174 Dec 31 22:11 models.cpython-34.pyc -rw-r--r-- 1 root root 280 Dec 31 22:28 urls.cpython-34.pyc -rw-r--r-- 1 root root 484 Jan 1 18:54 views.cpython-34.pyc
- Logs :
Lorsque le problème survient (lorsque j'essaie d'accéder avec un navigateur -j'utilise lynx- à test_django.test.fr) j'ai une erreur Bad Request (400).
/var/log/httpd/error_log n'a rien reçu et /var/www/log/httpd/access_log a juste reçu :
CE QUE J'AI DÉJÀ ESSAYÉ :
Code : Sélectionner tout - Visualiser dans une fenêtre à part 127.0.0.1 - - [02/Jan/1970:05:59:56 +0100] "GET / HTTP/1.0" 400 26
-Essayer de mettre la variable DEBUG à False ou True.
-Essayer de mettre '*' dans ALLOWED_HOSTS.
-Faire un print() dans les vues pour essayer d'obtenir des informations supplémentaires, mais on n'a réussi à les récupérer qu'avec runserver, or de cette manière cela fonctionne.
Seulement voilà là je dois avouer que je bloque faute de comprendre le soucis :S
Je rappelle que le projet fonctionne sans soucis avec runserver (donc en développement).
Je vous remercie d'avoir pris le temps de lire et je vous remercie d'avantage si vous avez une idée pouvant résoudre le problème.
Par ailleurs toute remarque pouvant nous aider à la compréhension du problème ou d'un autre soucis que vous estimez digne d'intérêt est bien entendu la bienvenue!
Merci d'avance!
Partager