Skip to content

Instantly share code, notes, and snippets.

@pyguerder
Last active March 12, 2023 16:01
  • Star 24 You must be signed in to star a gist
  • Fork 11 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save pyguerder/6c67248c4fbcc3b88871 to your computer and use it in GitHub Desktop.
Installation de Django sur un hébergement mutualisé OVH

La méthode présentée ici permet d'installer un site Django sur un hébergement mutualisé OVH.

Lisez d'abord le fichier README puis copiez les fichiers .htaccess et django.cgi vers votre hébergement, ainsi que le code source de Django et le code source de votre site web.

Options +ExecCGI
AddHandler cgi-script .cgi
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ django.cgi/$1 [QSA,L]

OVH permet l'exécution du code Python sur son hébergement mutualisé. La version de Python utilisée est 2.6 mais Django n'est pas installé en standard (vérifier).

La version de Django la plus récente qui puisse fonctionner avec Python-2.6 est Django-1.6 (vérifier). Elle est téléchargeable à cette adresse.

Une fois l'archive téléchargée, extraire le dossier Django-1.6.10/django. C'est ce dossier qui sera installé sur l'espace d'hébergement.

L'arborescence proposée pour le code est la suivante :

/
├ projects/
│ ├ django/
│ │ ├ bin/
│ │ ├ conf/
│ │ ├ contrib/
│ │ ├ core/
│ │ ├ db/
│ │ ├ dispatch/
│ │ ├ forms/
│ │ ├ http/
│ │ ├ middleware/
│ │ ├ shortcuts/
│ │ ├ template/
│ │ ├ templatetags/
│ │ ├ test/
│ │ ├ utils/
│ │ ├ views/
│ │ └ __init__.py
│ └ app/
│   ├ django_app/
│   | ├ __init__.py
│   | ├ settings.py
│   | ├ urls.py
│   | └ wsgi.py
│   ├ monsite/
│   | ├ migrations/
│   | ├ static/
│   | ├ template/
│   | ├ __init__.py
│   | ├ admin.py
│   | ├ models.py
│   | ├ tests.py
│   | ├ urls.py
│   | └ views.py
│   ├ manage.py
│   └ database.sqlite
└ www/
  ├ static/
  │ ├ admin/
  │ │ ├ css/
  │ │ ├ img/
  │ │ └ js/
  │ └ monsite/
  │   ├ style.css
  │   └ favicon.png
  ├ django.cgi
  ├ .htaccess
  ├ sitemap.gz
  └ robots.txt

Le code de Django-1.6.10/django se place donc dans le dossier /projects/django et le code « maison » dans le dossier /projects/app. Il est possible de personnaliser cela grâce aux instructions sys.path.append du fichier django.cgi.

Ces instructions sont également à adapter en fonction du nom de votre compte OVH (moncompte dans le fichier ci-joint). En cas de doute, vous pouvez obtenir cette information en créant dans le dossier www un fichier PHP contenant <?php echo getcwd(); ?>.

Le fonctionnement repose sur les fichiers /www/.htaccess et /www/django.cgi donnés ci-joints.

Il est essentiel que les permissions du fichier /www/django.cgi soient 755 ou supérieures. Le problème est que le serveur OVH remet les permissions à 604 dès que le fichier est modifié. Pensez-y quand vous rencontrez des erreurs 500 !

Astuce : si vous hébergez votre site sur un contrat start10m (donc avec 10 Mo d'espace disque), il est tout-à-fait possible de faire fonctionner Django. Commencez par supprimer les dossiers correspondant aux traductions que vous n'utilisez pas, dans les répertoires /locale/. Pour ma part, je ne garde que les dossiers /locale/en. Le dossier Django-1.6.10/django passe alors de 26 Mo à 6 Mo et il vous reste donc 4 Mo pour héberger votre code, votre base de données et les fichiers statiques. Cependant, par défaut, Python va stocker les fichiers bytecode (*.pyc) et ceux-ci réduiront d'autant l'espace disponible pour l'hébergement. Les lignes suivantes, à ajouter au fichier django.cgi, permettent d'empêcher Python de stocker ces fichiers (au prix d'une réduction des performances) :

os.environ['PYTHONDONTWRITEBYTECODE'] = '1'
sys.dont_write_bytecode = True

N'oubliez pas de configurer les variables ALLOWED_HOSTS au(x) bon(s) nom(s) de domaine et DEBUG et TEMPLATE_DEBUG à False dans /projects/app/django_app/settings.py.

#!/usr/bin/python
# encoding: utf-8
import os, sys
sys.path.append("/home/moncompte/projects/django/bin/") # À modifier
sys.path.append("/home/moncompte/projects/django/") # À modifier
sys.path.append("/home/moncompte/projects/") # À modifier
sys.path.append("/home/moncompte/projects/app/") # À modifier
sys.path.append("/home/moncompte/projects/app/django_app/") # À modifier
def run_with_cgi(application):
environ = dict(os.environ.items())
environ['wsgi.input'] = sys.stdin
environ['wsgi.errors'] = sys.stderr
environ['wsgi.version'] = (1,0)
environ['wsgi.multithread'] = False
environ['wsgi.multiprocess'] = True
environ['wsgi.run_once'] = True
if environ.get('HTTPS','off') in ('on','1'):
environ['wsgi.url_scheme'] = 'https'
else:
environ['wsgi.url_scheme'] = 'http'
headers_set = []
headers_sent = []
def write(data):
if not headers_set:
raise AssertionError("write() before start_response()")
elif not headers_sent:
# Before the first output, send the stored headers
status, response_headers = headers_sent[:] = headers_set
sys.stdout.write('Status: %s\r\n' % status)
for header in response_headers:
sys.stdout.write('%s: %s\r\n' % header)
sys.stdout.write('\r\n')
sys.stdout.write(data)
sys.stdout.flush()
def start_response(status,response_headers,exc_info=None):
if exc_info:
try:
if headers_sent:
# Re-raise original exception if headers sent
raise exc_info[0], exc_info[1], exc_info[2]
finally:
exc_info = None # avoid dangling circular ref
elif headers_set:
raise AssertionError("Headers already set!")
headers_set[:] = [status,response_headers]
return write
result = application(environ, start_response)
try:
for data in result:
if data: # don't send headers until body appears
write(data)
if not headers_sent:
write('') # send headers now if body was empty
finally:
if hasattr(result,'close'):
result.close()
try:
os.environ['DJANGO_SETTINGS_MODULE'] = 'django_app.settings' # À modifier
import django.core.handlers.wsgi
run_with_cgi(django.core.handlers.wsgi.WSGIHandler())
except Exception, inst:
print("Content-type: text/html\n\n")
print(inst)
@charlycoste
Copy link

C'est quand même honteux que, depuis plus de 10 ans, OVH se permette d'écrire que leur mutualisé prend en charge les scripts CGI python et C alors qu'il n'y a aucune documentation ni aucune information officielle sur le mode de fonctionnement.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment