Technologies avancées



Documents pareils
Django. Framework de développement Web

Django et PostgreSQL sous la charge

Gestion d identités PSL Exploitation IdP Authentic

Les bonnes pratiques. de l hébergement d un CMS

PHP 5.4 Développez un site web dynamique et interactif

Installation UpdatEngine serveur (CentOs apache2 / MySQL)

SYSTÈMES D INFORMATIONS

Sécurité des sites Web Pas un cours un recueil du net. INF340 Jean-François Berdjugin

TP JAVASCRIPT OMI4 TP5 SRC

Devenez un véritable développeur web en 3 mois!

Module BD et sites WEB

Soon_AdvancedCache. Module Magento SOON. Rédacteur. Relecture & validation technique. Historique des révisions

BTS SIO SISR3 TP 1-I Le service Web [1] Le service Web [1]

MANUEL WORDPRESS. Objectif: Refonte d un site web sous Wordpress I PRE-REQUIS: 1 / Créer un backup (sauvegarde) du site:

Module Com231A - Web et Bases de Données Notion 5 : Formulaires et utilisation des Bases de Données avec PHP

«Cachez-moi cette page!»

Nouveautés de Drupal 8. Léon

La double authentification dans SharePoint 2007

Magento. Magento. Réussir son site e-commerce. Réussir son site e-commerce BLANCHARD. Préface de Sébastien L e p e r s

Installation d un serveur HTTP (Hypertext Transfer Protocol) sous Débian 6

Mise en place d un serveur Proxy sous Ubuntu / Debian

Programmation Web. Madalina Croitoru IUT Montpellier

1 / Introduction. 2 / Gestion des comptes cpanel. Guide débuter avec WHM. 2.1Créer un package. 2.2Créer un compte cpanel

DRUPAL Réalisez des développements professionnels avec PHP (2ième édition)

Gérer une forte charge avec ez Publish Obtenir la meilleure réactivité de publication. Solutions natives ez. Solution spécifique.

Installation d'un serveur sftp avec connexion par login et clé rsa.

Content Switch ou routage de niveau HTTP

Master1 ère année. Réseaux avancés I. TP nº5 filière ISICG

Hébergement de site web Damien Nouvel

BOUCHARD Nicolas. GENTILE Pierre

Préparation d un serveur Apache pour Zend Framework

PHP et mysql. Code: php_mysql. Olivier Clavel - Daniel K. Schneider - Patrick Jermann - Vivian Synteta Version: 0.9 (modifié le 13/3/01 par VS)

Principales failles de sécurité des applications Web Principes, parades et bonnes pratiques de développement

Attaques applicatives

équipement radio Procédure

Conférence Développeurs Magento. 27 novembre 2013 mageconf.org

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

Modélisation PHP Orientée Objet pour les Projets Modèle MVC (Modèle Vue Contrôleur) Mini Framework

les techniques d'extraction, les formulaires et intégration dans un site WEB

Introduction aux concepts d ez Publish

STID 2ème année : TP Web/PHP

PLUGINS Guide du Développeur STEPHANE FERRARI. P l u X m l 5.4

Module pour la solution e-commerce Magento

Editer un script de configuration automatique du proxy

La programmation orientée objet Gestion de Connexions HTTP Manipulation de fichiers Transmission des données PHP/MySQL. Le langage PHP (2)

Sécurité des applications web. Daniel Boteanu

Nouveautés joomla 3 1/14

Serveur d'application Client HTML/JS. Apache Thrift Bootcamp

1. Installation du Module

GUIDE D INSTALLATION. Portaneo Enterprise Portal version 4.0

Documentation Technique

Documentation de conception

Faire fonctionner symfony sous wamp et windows avec des vhost. Installation de wamp

Introduction. PHP = Personal Home Pages ou PHP Hypertext Preprocessor. Langage de script interprété (non compilé)

INF8007 Langages de script

Système Normalisé de Gestion des Bibliothèques -SYNGEB : version Réseau-

Comparatif CMS. Laurent BAUREN S Bérenger VIDAL Julie NOVI Tautu IENFA

Sommaire. 1 Introduction Présentation du logiciel de commerce électronique 23

PHP CLÉS EN MAIN. 76 scripts efficaces pour enrichir vos sites web. par William Steinmetz et Brian Ward

L installation du module Webmail nécessite également quelques prérequis, à savoir :

Panel des technologies Web

SUPPORT DE COURS / PHP PARTIE 3

HTML, CSS, JS et CGI. Elanore Elessar Dimar

Joomla! Création et administration d'un site web - Version numérique

Technologies du Web Master COMASIC Technologies côté serveur

Serveur de partage de documents. Étude et proposition d'une solution afin de mettre en place un serveur de partage de documents.

Serveur d Applications Web : WebObjects

Auteur LARDOUX Guillaume Contact Année 2014 DEVELOPPEMENT MOBILE AVEC CORDOVA

Présentation du Framework BootstrapTwitter

Failles XSS : Principes, Catégories Démonstrations, Contre mesures

Découvrir le CMS. et l utiliser dans une approche pro!

ECLIPSE ET PDT (Php development tools)

Installation d un hébergement Web à domicile

Nuxeo 5.4 : les nouveautés

Drupal (V7) : principes et petite expérience

Alfstore workflow framework Spécification technique

Procédure d'installation

Bases de Données et Internet

TP réseaux 4 : Installation et configuration d'un serveur Web Apache

Internet. Web Sécurité Optimisation

Un serveur web léger et ouvert

Imprimantes et partage réseau sous Samba avec authentification Active Directory

Installation d OwnCloud 8.0 sous Debian Avec connexion des utilisateurs active directory et mise en place de HTTPS

Savoir- Faire Offres mé1ers Offres technologiques

1. La plate-forme LAMP

HTML/CSS - Travaux Pratiques 2

INSTALLATION ET CONFIGURATION D'UN SERVEUR WEB SUR MAC OS X

SERVEUR WEB. Christian Dupaty BTS Systèmes Numériques Lycée Fourcade Gardanne Académie d Aix Marseille

Utiliser un CMS: Wordpress

Installation FollowMe Q server

UwAmp. Serveur d'evaluation

Construire une application marketing Facebook sur la plateforme Windows Azure

INTERNET est un RESEAU D ORDINATEURS RELIES ENTRE EUX A L ECHELLE PLANETAIRE. Internet : interconnexion de réseaux (anglais : net = réseau)

Tutoriel: Création d'un Web service en C++ avec WebContentC++Framework

Installation d'un serveur FTP géré par une base de données MySQL

PARTAGER UN ANNUAIRE COLLECTIF DE SIGNETS AVEC DEL.ICIO.US

Transcription:

Objectif Connaître les bases Django Olivier Pons / 2015

1 Django Installation Etapes qui vont suivre 1. Installation de l'environnement 2. Installation de Django 3. Création d'un projet vide 4. Création d'une application monblog 3 / 71

1 Django Installation Création de l'environnement virtuel mkdir monenv cd monenv python3 -m venv myvenv myvenv/bin/activate source bin/activate myvenv/bin/pip install --upgrade pip myvenv/bin/pip install django 4 / 71

1 Django Installation Création de l'environnement virtuel Python 2.x mkdir monenv cd monenv virtualenv myvenv source myvenv/bin/activate myvenv/bin/pip install requests myvenv/bin/pip install --upgrade pip myvenv/bin/pip install django 5 / 71

Création du projet > myvenv/bin/django-admin.py startproject monprojet. > tree monprojet monprojet/ init.py settings.py urls.py wsgi.py Editez monprojet/settings.py Et mettez le en français, avec TIMEZONE à Europe/Paris 6 / 71

Les fichiers de base monprojet/ init.py settings.py urls.py wsgi.py Dossier racine monprojet est un module configuration du site Web résolution des routes (urlresolver) Web Server Gateway Interface = serveur 7 / 71

Création du projet Le fichier manage.py est une sorte d'enveloppe de django-admin L'interface d'administration n'existe pas car elle est générée automatiquement! En attendant il faut demander à générer la base de données dont se servent les modules de base Puis générer une application. En général : un projet, qui contient plusieurs applications 8 / 71

Création de la base de données myvenv/bin/python3 manage.py migrate 9 / 71

Lancement du serveur myvenv/bin/python3 manage.py runserver 10 / 71

Nouvelle application >> myvenv/bin/python3 manage.py startapp monblog >> tree monblog/ monblog/ init.py admin.py migrations init.py models.py tests.py views.py 11 / 71

Nouvelle application Ajouter dans monprojet/settings.py l'application 'monblog' INSTALLED_APPS = ( 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'monblog', ) 12 / 71

Technologies avancées Modèle exemple Mettre dans monblog/models.py : from django.db import models from django.utils import timezone class Post(models.Model): author = models.foreignkey('auth.user') title = models.charfield(max_length=200) text = models.textfield() created_date = models.datetimefield( default=timezone.now) published_date = models.datetimefield( blank=true, null=true) def publish(self): self.published_date = timezone.now() self.save() def str (self): return self.title 13 / 71

Modèle exemple >> myvenv/bin/python3 manage.py makemigrations monblog >> myvenv/bin/python3 manage.py migrate monblog 14 / 71

QuerySet >> myvenv/bin/python3 manage.py shell >> from monblog.models import Post >> from django.contrib.auth.models import User >> User.objects.all() >> User.objects.create(username='olivier') >> User.objects.all() >> User.objects.get(username='olivier') >> moi = User.objects.get(username='olivier') >> Post.objects.create( author = moi, title = 'Mon titre', text = 'Test') >> Post.objects.filter(author=moi) 15 / 71

QuerySet >> post = Post.objects.get(id=1) >> post.publish() >> Post.objects.filter(published_date isnull=false) >> Post.objects.order_by('created_date') >> Post.objects.order_by('-created_date') >> exit 16 / 71

Administration Créer un superadmin : myvenv/bin/python3 manage.py createsuperuser Mettre dans monblog/admin.py : from django.contrib import admin from.models import Post admin.site.register(post) Relancer le serveur myvenv/bin/python3 manage.py runserver Aller sur : http://127.0.0.1:8000/admin/ 17 / 71

18 / 71

Urls Ajouter l'url dans monprojet/urls.py : urlpatterns = [ url(r'^admin/', include(admin.site.urls)), url(r'', include('monblog.urls')), ] Créer le fichier en conséquence : monblog/urls.py from django.conf.urls import patterns, include, url from. import views urlpatterns = patterns('', url(r'^$', views.post_list), ) 19 / 71

Templating Ajouter l'url dans monblog/views.py : from django.shortcuts import render def post_list(request): return render(request, 'blog/post_list.html', {}) Créer les dossiers puis le fichier en conséquence : >>> mkdir monblog/templates >>> mkdir monblog/templates/blog >>> vim monblog/templates/blog/post_list.html 20 / 71

Comparaison Python / Php 21 / 71

Comparaison Python / Php Symfony : générer l'interface d'administration / Sonata - Installer le bundle - Rajouter / modifier le routing - Publier les assets - Décommenter le traducteur (multilangue) - Supprimer les routes inutiles - Générer toutes les classes d'admin. - Eventuellement, activer cmf_tree ( 3 actions en plus) http://symfony.com/doc/current/cmf/tutorial/sonata-admin.html Django : rien à faire. Si, si. Rien. 22 / 71

Templates / Données dynamiques Lancer python local : myvenv/bin/python3 Puis import os os.environ['django_settings_module']='monprojet.settings' from django.contrib.auth.models import User import monblog.models posts = monblog.models.post.objects\.filter(published_date isnull=false)\.order_by('published_date') posts 23 / 71

Templates / Données dynamiques Toutes les conditions possibles sont après : xxx.filter(nomchamp lte = xx) xxx.filter(nomchamp gt = xx) xxx.filter(nomchamp startwith = xx) xxx.filter(nomchamp endswith = xx) xxx.filter(nomchamp exact = xx) xxx.filter(nomchamp iexact = xx) xxx.filter(nomchamp contains = xx) xxx.get(id = xx) xxx.objects.all()[:5] 24 / 71

Templates / Données dynamiques Ajouter dans monblog/views.py : from django.shortcuts import render from.models import Post def post_list(request): posts = Post.objects\.filter(published_date isnull=false)\.order_by('published_date') return render( request, 'blog/post_list.html', {'posts': posts} ) Relancer le serveur Web 25 / 71

Templates / Données dynamiques Ajouter dans monblog/templates/blog/post_list.html : {% for post in posts %} <div> <p>publié le : {{ post.published_date }}</p> <h1><a href="">{{ post.title }}</a></h1> <p>{{ post.text linebreaks }}</p> </div> {% endfor %} Relancer le serveur Web 26 / 71

Templates / Données statiques Créez le dossier static à la racine puis css : mkdir static mkdir static/css Modifiez monprojet/settings.py : STATICFILES_DIRS = ( os.path.join(base_dir, "static"), ) Relancer le serveur Web 27 / 71

Templates / Données statiques Modifier première ligne de monblog/templates/blog/post_list.html : {% load staticfiles %} Puis dans le <head></head> ajouter : <link rel="stylesheet" href="{% static "css/blog.css" %}"> Relancer le serveur Web Intégrer totalement un boilerplate au choix (voir après) 28 / 71

Boilerplates Initializr http://www.initializr.com/ 99lime http://www.99lime.com/elements/ Alsacreation http://schnaps.it/ http://fortawesome.github.io/font-awesome/cheatsheet/ 29 / 71

Technologies avancées Templates / Héritage Fichier base.html contient toute la base avec des blocs vides : {% block content %} {% endblock %} Les fichiers qui héritent remplissent ces blocs : monblog/templates/blog/post_list.html : {% block content %} {% for post in posts %} {% endfor %} {% endblock content %} 30 / 71

Url + Template + QuerySet Editer monblog/urls.py y ajouter dans les patterns : url(r'^post/(?p<pk>[0-9]+)/$', views.post_detail), Editer monblog/views.py : from django.shortcuts import render, get_object_or_404 def post_detail(request, pk): post = get_object_or_404(post, pk=pk) return render( request, 'blog/post_detail.html', {'post': post} ) 31 / 71

Url + Template + QuerySet Editer monblog/templates/blog/post_detail.html : {% extends "blog/base.html" %} {% block content %} <div class="date"> {% if post.published_date %} Publié le : {{ post.published_date }} {% endif %} </div> <h1>{{ post.title }}</h1> <p>{{ post.text linebreaks }}</p> {% endblock %} 32 / 71

Formulaires Simples (pas liés à un modèle) Principe Déclarer une classe dérivée de forms.form dans forms.py Déclarer une vue de type FormView dans views.py Mettre la forme en visuel dans les templates (xxx.html) 33 / 71

forms.py Technologies avancées Formulaires Simples (pas liés à un modèle) class RegisterForm(forms.Form): username = forms.charfield() prenom = forms.charfield() etc. prenom = forms.charfield( label=u'entrez votre prénom', max_length=100) Ce ne sont que des définitions de champs = Fields 34 / 71

views.py Technologies avancées Formulaires Simples (pas liés à un modèle) class RegisterView(FormView): template_name = 'applancement/index.html' form_class = RegisterForm def form_valid(self, form): username = form.cleaned_data['username'] prenom = form.cleaned_data['prenom']... return HttpResponseRedirect(u'{0}{1}'.format( site_web, self.request.meta['path_info'] )) 35 / 71

Formulaires Simples (pas liés à un modèle) templates/index.html <form action="{% url 'register' %}" method="post"> {% csrf_token %} {% for field in form %} {{ field.label_tag }}<br />{{ field }}<br /> {% if field.errors %} {{ field.errors }} {% endif %} {{ field.help_text }} {% endfor %} {{ form.non_field_errors }} <input type="submit" value="register!"> </form> 36 / 71

Editer monblog/forms.py : from django import forms from.models import Post Technologies avancées Formulaires class PostForm(forms.ModelForm): formulaires Django notre modèle Classe dérivée class Meta: classe où définir : model = Post - la table fields = ('title', 'text',) - les champs 37 / 71

Formulaires Ajouter le lien vers le formulaire : <a href="{% url "blog.views.post_new" %}" class="top-menu"> <span class="glyphicon glyphicon-plus"></span> </a> 38 / 71

Authentification Autorisation Installation Droits Vérifie que l utilisateur est bien celui qu il prétend être Détermine ce qu un utilisateur authentifié est autorisé à faire Tout est déjà fait (settings.py) django.contrib.auth Authentification django.contrib.contenttypes Association modèles permissions 39 / 71

Décorateurs rom django.views.decorators.http import require_http_methods require_http_methods(["get", "POST"]) ef my_view(request): # arrivé ici = que GET ou POST! pass require_get(), require_post(), require_safe() rom django.contrib.auth.decorators import login_required login_required(login_url='/login/') ef my_view(request):... 40 / 71

Décorateurs rom django.contrib.auth.decorators import permission_required permission_required('polls.can_vote', login_url='/login/') ef my_view(request):... ans l'application polls : lass Poll(models.Model): def can_vote(self, user): return not self.vote_set.filter(user=user).exists() 41 / 71

Décorateurs from django.contrib.auth.decorators import user_passes_test def email_ok(user): return user.email.endswith('@gmail.com') @user_passes_test(email_ok) def my_view(request):... 42 / 71

ans urls.py Technologies avancées 2 Django Suppléments URLs paramétrées rlpatterns = [... rl(_(r'^vente-groupee/(?p<slug>[a-za-z0-9-_]+)/$'), p_views.detailview.as_view(), name='vente_groupee'),... ans un fichier de template : a href="{% url 'vente_groupee' monparam %}">Ici<a/> 43 / 71

2 Django Suppléments Sessions Dans settings.py vérifier que MIDDLEWARE_CLASSES contient django.contrib.sessions.middleware.sessionmiddlewarer Puis dans les vues : Le premier paramètre d'une vue est un objet HttpRequest Via cet objet, on accède à la propriété session requestion.session.['id']=654654 exemple = requestion.session.get('id') del request.session['id'] Fonctions les plus utilisées de session : keys(), items(), setdefault(), clear(), flush() https://docs.djangoproject.com/fr/1.8/topics/http/sessions/ 44 / 71

2 Django Suppléments Namespace Définition du namespace dans la route principale Ajouter dans urls.py urlpatterns = [ url(_(r'^monapp/'), include('monapp.urls', namespace="produits")), url(r'^admin/', include(admin.site.urls)), ] 45 / 71

2 Django Suppléments Namespace éfinition des routes dans l'application même : blog/urls.py rom django.conf.urls import include, url rom django.contrib import admin rom. import views rlpatterns = [ url(r'^$', views.indexview.as_view(), name='index'), 46 / 71

Technologies avancées 2 Django Suppléments Modèles : choix multiple rom django.db import models rom django.utils.translation import gettext_lazy as _ IFFICULTY = (('easy', _('Easy')), ('medium', _('Medium')), ('hard', _('Hard'))) lass Exercise(models.Model): name = models.charfield(max_length=300, unique=true) level = models.charfield( max_length=15, choices=difficulty) 47 / 71

Technologies avancées 2 Django Suppléments Modèles : base abstraite class BaseModel(models.Model): date_creation = models.datetimefield( auto_now_add=true ) date_last_modif = models.datetimefield( auto_now=true ) class Meta: abstract = True 48 / 71

2 Django Suppléments Modèles : exemple de filtre ttps://docs.djangoproject.com/fr/1.8/topics/db/queries/ Dans le modèle : class Produit(BaseModel): tags = models.manytomanyfield( Tag, related_name='produits' ) Dans la vue : Tag.objects.filter( produits in=produit.objects.all() ).distinct() 49 / 71

Technologies avancées 2 Django Suppléments Administration : ManyToMany class ProduitTagsInline(admin.TabularInline): model = Produit.tags.through extra = 0 class ProduitDescriptionsInline(admin.TabularInline): model = Produit.descriptions.through extra = 0 class ProduitAdmin(admin.ModelAdmin): inlines = [ProduitTagsInline, ProduitDescriptionsInline] exclude = ('descriptions', 'tags') 50 / 71

2 Django Suppléments Administration : ManyToMany 51 / 71

Technologies avancées 2 Django Suppléments Administration : même clé étrangère models.py class LangueTraduction(BaseModel): src = models.foreignkey('langue', related_name='langue_src') dst = models.foreignkey('langue', related_name='langue_dst') nom = models.charfield(max_length=50) admin.py class LangueTraductionsInline(admin.TabularInline): #! fk_name = obligatoire sinon pas visible : fk_name = 'src' model = LangueTraduction extra = 0 class LangueAdmin(admin.ModelAdmin): inlines = [LangueTraductionsInline] 52 / 71

2 Django Suppléments Administration : même clé étrangère 53 / 71

Traduction Au moment où la fonction est appelée from django.utils.translation import ugettext as _ Au moment où la chaîne est réellement utilisée from django.utils.translation import ugettext_lazy as _ Créer un dosser locale dans le projet Avec manage.py shell : makemessages -l fr makemessages -l en compilemessages 2 Django Suppléments 54 / 71

2 Django Suppléments Traduction Pour qu'il charge ces chaines : Dans settings.py, ajouter : LOCALE_PATHS = ( os.path.join(base_dir, 'locale'), ) 55 / 71

Champs de type ImageField Répertoire des fichiers téléversés : Dans settings.py, ajouter : MEDIA_ROOT = os.path.join(base_dir, 'uploads') Puis dans urls.py, ajouter : urlpatterns = [... url(r'^public/(?p<path>.*)$', 'django.views.static.serve', {'document_root': settings.media_root}), ] 2 Django Suppléments 56 / 71

Technologies avancées 2 Django Suppléments Lancer des commandes SQL en direct Exemple ici pour simuler le DESC [table] de mysql : Lancer python en ligne de commande from django.db import connection cursor = connection.cursor() cursor.execute("pragma table_info(ventegroupee)") for row in cursor: print(row) Pour la note : cursor est une classe iterable, donc on peut faire un for dessus 57 / 71

2 Django Suppléments Outils Django déjà en production Allez ici : https://github.com/divio/django-cms Installez le en suivant les instructions. 58 / 71

utre exemple models.py : Technologies avancées 3 Django Jeu de rôle Modèle exemple rom django.db import models rom django.utils import timezone rom django.utils.translation import ugettext_lazy as _ lass CharacterClass(models.Model): name = models.charfield(_(u'nom de la Classe'),max_length=80) playable = models.booleanfield(_(u'le joueur peut le choisir')) def str (self): return self.name 59 / 71

3 Django Jeu de rôle Modèle exemple Types existants : CharField BooleanField EmailField PositiveIntegerField TextField ForeignKey OneToOneField ManyToManyField 60 / 71

3 Django Jeu de rôle Modèle exemple class CharacterManager(models.Manager): def get_query_set(self): return super(charactermanager, self)\.get_query_set()\.filter(playable = True) class CharacterClass(models.Model):... objects = models.manager() # Manager par défaut playable_character = CharacterManager() # Playable Manager playable = CharacterClass.objects.filter(Playable = True) playable = CharacterClass.playable_character.all() 61 / 71

monblog/urls.py Technologies avancées 3 Django Jeu de rôle Vues génériques on peut y ajouter directement : from django.conf.urls import url from django.views.generic import TemplateView urlpatterns = [ url(r'^apropos/$', TemplateView.as_view( template_name='apropos.html' )) ] 62 / 71

3 Django Jeu de rôle Vues génériques : dérivation # monapp/views.py from django.views.generic import TemplateView class AproposView(TemplateView): template_name = "apropos.html" # urls.py from django.conf.urls import url from monapp.views import AproposView urlpatterns = [ url(r'^apropos/', AproposView.as_view()), ] 63 / 71

3 Django Jeu de rôle Vues génériques : listes class IndexView(generic.ListView): template_name = 'produits/index.html' context_object_name = 'liste_produits' def get_queryset(self): """ Dites ce que cela renvoie : """ return Produit.objects.order_by( '-date_v_fin', '-date_v_debut' )[:5] 64 / 71

3 Django Jeu de rôle Vues génériques : détail from django.views.generic.detail import DetailView from django.utils import timezone from.models import Produit class MaDetailView(DetailView): template_name = 'produits/detail.html' model = Produit def get_context_data(self, **kwargs): context = super(madetailview, self).get_context_data(**kwargs) context['now'] = timezone.now() return context 65 / 71

Technologies avancées 3 Django Sujet à faire Choisissez un site à faire parmi les suivants Réservation de places de concert Médiathèque Blog multi-utilisateurs multi rôles Vente de services (développement, formation) Rencontre entre professionnels ( à la LinkedIn ) SAAS de comptabilité basique Création communautaire de livres Présentation et statistiques détaillées d'un MMORPG Crowdfunding ( à la kickstarter / indiegogo ) Site d'apprentissage en ligne Réservation de tables d'un restaurant 66 / 71

4 Structure classique Varnish Configuration de varnish : /etc/varnish/default.vcl : backend apache {.host = "127.0.0.1";.port = "8080"; } backend nodejs {.host = "127.0.0.1";.port = "3000"; }... 67 / 71

4 Structure classique Varnish... sub vcl_recv { if (req.url ~ "(?i)\.(jpeg jpg... html htm)$") { unset req.http.cookie; } if ( (req.http.host ~ "olivierpons\.(.*)") (req.http.host ~ "krystallopolis\.(.*)") ) { set req.backend_hint = apache; set req.http.x-server = req.http.host; }... 68 / 71

... }... Technologies avancées 4 Structure classique Varnish # Surcharge pour NodeJS if ( (req.http.host ~ "node\.wogwog\.(.*)") ) { set req.backend_hint = nodejs; set req.http.x-server = req.http.host; # "pass" = passer direct sans cache possible return(pass); } 69 / 71

4 Structure classique Varnish... sub vcl_deliver { set resp.http.server = "WTF Server"; # Supprimer toutes les signatures : unset resp.http.via; unset resp.http.x-powered-by; unset resp.http.x-varnish; } 70 / 71

Apache httpd.conf Listen 8080 Technologies avancées 4 Structure classique Apache / NodeJS / Python NodeJS bin/www var port = normalizeport(process.env.port '3000'); Python / Django python manage.py runserver 8080 71 / 71