Lexpage, comme ça se prononce    —  Chandler

Discussions

Amazon Web Services / Heroku

Guybrush 8428 Bob
Coucou,

Y en a-t-il parmi vous qui utilisent les Amazon Web Services (AWS pour faire court) ? Je découvre peu à peu ce qu'ils proposent, mais c'est un peu une jungle pour moi, et leur page commerciale est plutôt mal conçue :-D

Je sais qu'OVH propose aussi du Cloud, mais je ne me suis jamais penché sur les avantages du cloud pour l'hébergement "classiques" d'apps/services. Ca vaut la peine ? Est-ce qu'on ne finit pas par bricoler des solutions pour limiter au maximum l'usage en mémoire/calcul en idle, pour limiter les coûts ? (par ex, y a 2 workers Django systématiquement up sur Lexpage, 4 au cas où les 2 premiers sont occupés... mais ces workers "coûtent" s'ils étaient hébergés sur le cloud, notamment parce qu'ils maintiennent Django + Lexpage en mémoire pour limiter les calculs/disk-io à chaque fois).

Et tiens, tant que j'y suis, est-ce que quelqu'un s'est déjà laissé tenter par Heroku ? Il faudrait que je creuse aussi de ce coté, y a des choses plutôt sympathiques...
Guybrush 8428 Bob
Azure ? Leur vidéo de "découverte" parle surtout d'informations de paiement, et de tarifications :-D


En fait, je cherche aussi un peu à professionnaliser la structure du Lexpage. Actuellement, y a pas mal de points de travail (allant de choses spécifiques à pas du tout spécifiques) :
- Aucun (ou presque) test. Même pas des tests unitaires, encore moins des tests fonctionnels. Que dalle, nada, rien. Il faut vraiment que j'en écrive, au moins des tests fonctionnels basiques, parce que j'ai déjà cassé pas mal de choses dans le code en faisant de bêtes petits changements. C'est honteux, je sais :-D
- Aucun contrôle de version. Pour la v4, vu que j'ai codé ça en 2 semaines environ, je ne me suis pas encombré d'un git (j'utilisais bzr, d'ailleurs, pas git, pour mes autres projets). Ce n'est pas trop trop grave vu que je suis seul dev dessus, mais bon...
- Dans le même ordre d'idée, ça aurait été bien de faire un bug tracker pour le site, surtout pour les premiers mois :-D
- Ma logique se situe au niveau des views, pas des modèles. Mauvaise habitude que j'ai prise en Django pour Lexpage, et qui rend l'implémentation d'une API difficile tant que je n'aurai pas réglé ce souci.
- Aucun outil pour gérer les environnements. J'ai juste des fichiers de configuration différents pour l'environnement de test et celui de prod. Mais c'est ultra basique : logger différent (oui, je devrais me pencher sur Sentry), backend mail simulé, database différente (et le SQLite en local me masque certains bugs que je rencontre avec MariaDB en prod, bouuh !!), ...
- Dans la même veine, je n'ai jamais utilisé virtualenv (gestion d'environnements virtuels, pour bundler les bonnes versions de chaque librairie requise par le site) ni pip (gestionnaire de paquets Python). Tant que Lexpage est le seul (enfin, le "master") site sur le serveur, c'est pas problématique, car les autres projets "s'adaptent" si nécessaire, mais c'est moche dans l'absolu :-D C'est bête, parce que j'utilise virtualenv et pip sur à peu près 99% des autres projets (que ce soit web ou autre). Au passage, pew remplace parfaitement bien virtualenvwrapper (avec un CLI bien plus simple !).
- Et encore moins d'outils pour le déploiement (je compte pas passer à Docker et ses containers, faut pas exagérer, je ne gère pas un parc d'applications ^^). Je regarde doucement du coté de Fabric (toujours du Python) pour faciliter un peu ça. Cela dit, si le VPS venait à cracher méchamment, il me faudra bien 24h pour remettre tout en place (j'ai rien pour le déploiement/config de MariaDB, ni de Nginx, encore moins de phpfpm, ... j'ai juste de quoi rebuilder rapidement la config WSGI du Lexpage :-D).

Ouais, en fait, Lexpage fait exactement tout le contraire de ce que je conseille à tour de bras dès que j'en ai l'occasion. Mais le dev était particulier : fait par tranches de 30 minutes dès que j'avais 30 minutes de libre, et c'était à priori surtout un prototype pour une vraie v4 (et puis la flemme de recommencer, alors...).

Conscient de tout ces problèmes, j'ai maintenant une checklist relativement simple pour y remédier (pour de futurs projets, et si j'ai le temps, pour Lexpage aussi). Il me reste juste le déploiement/configuration "hors application" comme MariaDB, Redis, Nginx, etc. Et avant de me lancer dans un "skeleton builder" respectant cette checklist, je voudrai voir où on en est avec les solutions modernes "hypes" et voir si ça s'intègre (ou si c'est pas trop incompatible) avec des services comme AWS, Heroku, etc.
Sysson 1416 Spammeur
Commence par faire un git init dans ton /etc et commit tes configs, j'ai l'impression qu'en 20 secondes tu vas réduire de 20 heures la restauration du lexpage le jour où ton serveur va crasher. Si t'as un peu de place fais un beau tar de ton / et garde le en backup dans un coin.
J'espère aussi que tu as une backup journalière de la bdd, ce serait dommage que la prose des lexpagiens se perde à cause d'un rayon cosmique. :bigsmile:
Fabe 610 Geek
Éventuellement, dépose tes sources sur un repo public, ça permettrait à "d'autres personnes" de jeter un oeil à tes bugs et donner un coup de main, à l'occasion :-)
Guybrush 8428 Bob
SyssonCommence par faire un git init dans ton /etc et commit tes configs
J'ai une copie, mais je ne sais pas dans quelle mesure ça suffit pour "tout remettre rapidement en état", cela dit :-)
SyssonJ'espère aussi que tu as une backup journalière de la bdd, ce serait dommage que la prose des lexpagiens se perde à cause d'un rayon cosmique. :bigsmile:
Oui, heureusement :-)
J'ai bricolé un cron + logrotate pour sauver la db via un compte Dropbox (j'ai parlé de bricolage, hein :-p) :-)
FabeÉventuellement, dépose tes sources sur un repo public, ça permettrait à "d'autres personnes" de jeter un oeil à tes bugs et donner un coup de main, à l'occasion :-)
J'y pense de plus en plus. Je sais que la v4 "première édition" n'avait pas soulevé des foules y a 3-4 ans quand on suggérait que ça pourrait être participatif... mais c'est une idée qui me revient souvent, ne fut-ce que parce que contrairement à la v3, j'ai "confiance" dans le code cette fois-ci :-D

C'est assez marrant, parce qu'au moment où j'ai écrit cette phrase, j'me suis dit "nan mais ton code, il est pas élégant au sens pythonique du terme, et en plus, tu l'as même pas documenté". Alors j'ouvre 2-3 fichiers (les modèles et les vues du "blog" et du "board") et... ah bah si, je l'avais documenté :-D Bon, par contre, coté "élégance", j'vois certains trucs immondes bricolés en triple vitesse pour dire que ça fonctionne, et j'ai déjà honte :-D

Extraits :

Au moins, j'étais honnête quand je parlais de "quick and dirty way" :-p
Documentation pour une fonction de changement de statut pour les billetsShortcut function that provide a quick and dirty way to update
the status of a post based on a given action.
Ou encore, même si la philosophie en Python est plutôt "Easier to Ask for Forgiveness than Permission".
    def get_previous(self):
""" Return the previous post by date_published, only for
published post. """
try:
return BlogPost.published.filter(date_published__lt=self.date_published).order_by('-date_published')[0]
except IndexError:
pass
Bon en fait, y a pas grand chose de trop moche quand même dans le code. J'pense que le principal problème, c'est que ma maitrise de Django a beaucoup évolué pendant le dev, et donc certains trucs sont un peu mélangés (par exemple, les class-based-view où je mélange l'usage des vues classiques, des mixins, des vues builtins, etc. avec à chaque fois des hacks pour que ça corresponde à ce que je veux, alors que ça existe déjà :-D).

Ok, ok... je vais y réfléchir (peut-être refactorer un peu tout ça avant quand même) :-D


Ce message a été modifié 1 fois. Dernière modification : 30 janvier 2015 à 14:56 par Guybrush.

Sysson 1416 Spammeur
Des backups avec lesquelles tu n'as jamais testé de restauration ne sont pas des backups :old2:
Tchou 3587 Bob
Guybrush - Aucun contrôle de version. Pour la v4, vu que j'ai codé ça en 2 semaines environ, je ne me suis pas encombré d'un git (j'utilisais bzr, d'ailleurs, pas git, pour mes autres projets). Ce n'est pas trop trop grave vu que je suis seul dev dessus, mais bon...
Ça résoudrai ton soucis de déploiement, aussi, et ton système de serveur test.

Alors, je ne suis pas une référence, je travaille aussi en solo, mais voilà mon workflow :
- développement et tests (pas unitaires, à la mano, oui, je sais, aussi, faudrait) sur un serveur de test, au plus proche de mon serveur de prod. Qui peut être une VM, dans certains cas (cas d'un serveur avec une config différente). Avec git. Une fois que j'ai une version publiable, je git push sur ...
- un dépot privé, crée via un git clone --bare (de mémoire)
- et mon serveur de prod. Une fois que j'ai une version fonctionnelle en test, je ssh sur le serveur de prod, je me place dans le répertoire, et je git pull dedans.

Mes fichiers de config sont dans le .gitignore et donc différents entre prod et test. Et les fichiers non fondamentaux (images et fichiers uploadés par exemple) sont dans le gitignore aussi.

Tu créé une VM sur ta machine, un quasi clone de ton serveur de prod, et tu as un moyen de tester efficacement pré-déploiement. Depuis que j'utilise un tel système (quelques années, le raffinement avec le déploiement via git ne date que de 2-3), je n'ai _jamais_ plus eu de "tiens, ma modif vient de planter le site" ou autre "merde, ma modif a planté un autre truc".

bzr, c'est la première fois que j'en entends parler.
Guybrush - Ma logique se situe au niveau des views, pas des modèles. Mauvaise habitude que j'ai prise en Django pour Lexpage, et qui rend l'implémentation d'une API difficile tant que je n'aurai pas réglé ce souci.
Alors là, je vais me faire troller je sens, je devrai fermer ma mouille je le sens bien, mais ... c'est pas dans le controller qu'il faut caler la logique ? Le modèle servant "uniquement" à traiter la donnée.
SyssonCommence par faire un git init dans ton /etc et commit tes configs, j'ai l'impression qu'en 20 secondes tu vas réduire de 20 heures la restauration du lexpage le jour où ton serveur va crasher.
Ça, c'est pas con. Un peu bricolage, mais pas con du tout.
GuybrushOui, heureusement :-)
J'ai bricolé un cron + logrotate pour sauver la db via un compte Dropbox (j'ai parlé de bricolage, hein :-p) :-)
Hiiiiii ! :sad:
Alors, le smiley aurai pu être :frightened: si la technique avait été "je m'envoie sur mon webmail", mais là c'pas glop quand même : si quelqu'un pirate le dropbox (ou a un accès sans pirater, genre c'est quelle nationalité dropbox ? ah !), il choppe la bdd, incluant la table users avec son champ (crypté certes).
Ok pour le bricolage, mais je reste toujours un brin touchy dès qu'il y a des données persos voire des passwords dans un fichier.
GuybrushOk, ok... je vais y réfléchir (peut-être refactorer un peu tout ça avant quand même) :-D
Un projet qu'on ne réécrit pas entièrement plusieurs fois sous le fallacieux prétexte de "ah, mais je peux le refaire plus élégamment" n'est pas un projet auquel on tient ! :bigsmile:
Guybrush 8428 Bob
TchouAlors, je ne suis pas une référence, je travaille aussi en solo, mais voilà mon workflow :
- développement et tests (pas unitaires, à la mano, oui, je sais, aussi, faudrait) sur un serveur de test, au plus proche de mon serveur de prod. Qui peut être une VM, dans certains cas (cas d'un serveur avec une config différente). Avec git. Une fois que j'ai une version publiable, je git push sur ...
- un dépot privé, crée via un git clone --bare (de mémoire)
- et mon serveur de prod. Une fois que j'ai une version fonctionnelle en test, je ssh sur le serveur de prod, je me place dans le répertoire, et je git pull dedans.
Je crois que c'est une bonne idée, même si dans le cas du développement Python, l'environnement joue peu (une fois que ça tourne sous Gunicorn, le serveur web importe peu au final, sauf pour la gestion des fichiers statiques et des petites bizarreries que je n'utilise pas sur Lexpage). Donc cloner l'environnement de production n'est pas trop difficile (même version de Python + librairies, via Virtualenvwrapper). Il reste le cas de la database, où j'utilise SQLite en local, et MariaDB en prod. Y a quelques subtilités, mais dans l'absolu, les bugs qui y sont potentiellement liés sont rares et faciles à identifier (par exemple, le bug de la recherche par étiquette pour les billets qui fait appel à iregex ^^).
TchouMes fichiers de config sont dans le .gitignore et donc différents entre prod et test. Et les fichiers non fondamentaux (images et fichiers uploadés par exemple) sont dans le gitignore aussi.
En général, je mets tout dans le git, sauf ce qui est privé (clé de chiffrement de l'application, password, etc.). Pour Lexpage, c'est "pire" car tout est dans mon fichier de settings pour l'environnement de prod. Je pense qu'il faudrait que je stocke ça dans une variable d'environnement sur le serveur, et que j'y accède via Python, comme ça je ne trimballe pas de choses sensibles via git le jour où j'y passe :-D
TchouAlors là, je vais me faire troller je sens, je devrai fermer ma mouille je le sens bien, mais ... c'est pas dans le controller qu'il faut caler la logique ? Le modèle servant "uniquement" à traiter la donnée.
Django est un peu différent et se définit plutôt comme un "MVT" : Modèle / Vue / Template. Django part du principe que le "controller", c'est Django et les différents middleware. De ce principe, on a :
- Les modèles, incluant l'ORM et les méthodes de manipulation des données (d'où le fait d'inclure le maximum de validation directement sur le modèle). Par "modèle", cela comprend aussi les managers (des sortes de queryset) pour récupérer les données filtrées.
- Les vues, qui grosso-modo définissent quelles sont les données qui vont peupler le contexte de ta template. Cela inclut la manipulation des formulaires (pour faire la passerelle entre les données utilisateurs et les modèles), ainsi que le gros du comportement "URL" (redirection, etc. si besoin) et l'authentification. C'est dans les vues qu'on va aussi gérer typiquement le cache "fin" si nécessaire.
- Les templates, qui définissent juste le gabarit à utiliser pour la vue (disons que c'est plutôt la vue qui définit son gabarit, mais bon). La logique y est très limitée (par rapport à Rails, notamment).

Le contrôleur classique n'existe pas vraiment : il y a un peu de contrôleur dans le modèle (pour la manipulation des données), dans les vues (pour les données utilisateurs) et dans Django (routage, middleware (authentification, db, cache, ...)).

L'avantage (à mes yeux), c'est que l'essentiel de la logique "données" se situe réellement au niveau du modèle, et que l'essentiel de la présentation se situe au niveau de la template (où tu as notamment la possibilité de charger des données de la db si besoin, via des tags que tu définis dans ton application, et qui sont "juste" appelés dans la template, comme les slogans sur Lexpage, par exemple, ou encore via un ContextManager qui va systématiquement peupler ton context avec des données avant de l'envoyer à la template (par exemple, pour l'authentification et le profile utilisateur). On utilise ce dernier principalement quand les données sont dépendantes de la requête (ce qui n'est pas le cas des slogans).

Donc si on suit proprement cette approche, il est très simple de définir de nouvelles "vues" pour manipuler/afficher des données du modèle sans avoir à ré-écrire une grosse partie de la logique (et on peut donc facilement proposer une API, une version mobile (en dehors du "responsive", etc. sans se prendre la tête). Pour la v4, j'ai une approche hybride avec pas mal de choses au niveau du modèle, mais malheureusement, encore pas mal de logique au niveau des vues (notamment tout ce qui concerne les notifications et la gestion des droits, même si j'ai un middleware "permissions" pour faciliter le travail).
TchouAlors, le smiley aurai pu être :frightened: si la technique avait été "je m'envoie sur mon webmail", mais là c'pas glop quand même : si quelqu'un pirate le dropbox (ou a un accès sans pirater, genre c'est quelle nationalité dropbox ? ah !), il choppe la bdd, incluant la table users avec son champ (crypté certes).
Je crois qu'il est plus facile d'avoir accès à la db directe qu'à Dropbox... Pour limiter la parano, je pourrai à la rigueur chiffrer les archives contenant la db avant de les envoyer. Cela dit, vos mots de passe sont hashés, salés et chiffrés avec la clé privée du Lexpage. Il n'est pas possible (enfin, pas envisageable plutôt) de déduire votre password en clair à partir de ces données, et si un accès non-autorisé devait avoir lieu sur Lexpage, il me suffirait de générer une nouvelle clé, déchiffrer et rechiffrer le hash avec une nouvelle clé et le souci est réglé.

Django est plutôt robuste de ce coté et fournit un bon nombre de mécanismes pour garantir un bon degré de sécurité.
TchouUn projet qu'on ne réécrit pas entièrement plusieurs fois sous le fallacieux prétexte de "ah, mais je peux le refaire plus élégamment" n'est pas un projet auquel on tient ! :bigsmile:
Tout à fait :jap:
pom 145 Padawan
Github c'est génial, ne serait-ce que pour documenter son code (en commençant par un bon vieux README) avec des fichiers markdown.

Ensuite, tu peux utiliser dploy qui récupère ton repo git tel qu'il est et qui ne déploie sur une machine (de préprod, de prod) que le delta des modifications.

Et si tu décides de faire les choses proprement, tu passes par des VM et Vagrant. Après avoir configuré ton vagrantfile, un petit "vagrant up" et tu as sur ton poste la stack technologique cible, et donc 1/ tu éviteras des bugs qui dépendent de l'os, des librairies, etc.. et 2/ tu peux multiplier sur ton poste de dev les projets dans des technos différentes, en faisant à chaque fois des vm étanches (et 3/ n'importe quel autre développeur peut récupérer exactement le même environnement que toi).

Je crois que Docker va un cran plus loin (et est plus performant puisqu'on évite un superviseur et une installation d'os nécessaire dans le cas des vm) mais j'avoue que ça donne encore plus de liberté (et de migraines) et de choix sur la granularité du container : dois-je faire un méga container ou plein de petits pour simuler toutes les briques de mon serveur de prod?

Répondre

Vous devez être inscrit et identifié.