Archives de la catégorie: Web

Développement Mac OS X NodeJS Ruby Ruby on Rails Web

Installer un environnement de développement moderne sous OS X 10.8

Beaucoup de développeurs utilisent de plus en plus Ruby, son framework Ruby on Rails et les autres outils de développement modernes.

Nous allons voir comment installer le tout de manière « propre ».

Vous aurez alors un environnement de développement complet et performant !

Mettre à jour OS X

La dernière version en date est OS X 10.8.3. Pensez à mettre à jour votre système.

Mettre à jour Java

Java peut être nécessaire pour obtenir un environnement de développement complet.

La dernière version en date est Java 7.

Le tout est disponible sur le site Oracle.

Installer XCode et les outils en ligne de commande

XCode est disponible sur le Mac App Store.

Une fois installé, ouvrez ses préférences afin d’installer les outils en ligne de commande.

La base : Homebrew

Homebrew vous permet de disposer des bibliothèques et outils open-source en environnement OS X.

Installez Homebrew via une ligne de commande du Terminal :

ruby -e "$(curl -fsSL https://raw.github.com/mxcl/homebrew/go)"

Vous aurez peut-être à vous y reprendre à plusieurs fois.

Une fois installé, et à chaque fois que vous souhaitez installer quoi que ce soit via Homebrew, utilisez d’abord cette ligne de commande :

brew doctor

Cette ligne de commande vous demandera peut-être de supprimer, par exemple, iconv. Renommez vos fichiers, c’est plus prudent.

Si les fichiers de s’installent pas du premier coup, désinstallez puis ré-installez.

Au final, tout devrait fonctionner correctement.

Sur une installation « propre », tout se passe sans encombres.

RVM (Ruby & Ruby on Rails)

RVM vous permet d’installer plusieurs versions de Ruby sur votre Mac.

Vous pourrez également installer Ruby on Rails (RoR).

Les versions actuelles sont Ruby 2.0.0 et RoR 3.2.13.

RVM vous permet également d’installer, par exemple, la version 4.0 beta 1 de RoR. En cohabitation avec le reste : pratique !

Pour installer Ruby et Rails avec toutes les dépendances liées à Homebrew, une seule ligne de commande suffit :

\curl -L https://get.rvm.io | bash -s stable --rails --autolibs=enabled

Et voilà, votre système est complètement prêt pour le développement Ruby et RoR.

Pensez à mettre à jour, si nécessaire, votre fichier .profile. (et faire le lien via source pour les fichiers .bashrc et autres)

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function* [[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm"

Sur une installation « propre », il n’y a rien d’autre à faire.

Sinatra

Sinatra vous permet de concevoir rapidement des prototypes d’applications web, voir des applications web complètes, dans le sens où cet outil est très léger.

Son installation en une ligne de commande :

gem install sinatra

Node.js

Node.js vous permet de faire la même chose de Sinatra, du moins sur le même principe, avec de meilleures performances (potentiellement) mais moins de maturité et en Javascript (moteur V8).

brew install nodejs

PHP

Les plus nostalgiques d’entre nous souhaiterons sûrement installer ce bon vieux PHP. Pour cela, installez d’abord XQuartz.

Ensuite, installez les dépendances nécessaires :

brew tap dupes brew tap josegonzalez/homebrew-php

Ensuite, installez PHP 5.4 en choisissant judicieusement vos options :

brew options php54 brew install php54

Installez également l’extension intl :

brew install php54-intl

Et configurez le fichier /usr/local/etc/php/5.4/php.ini :

date.timezone = Europe/Paris

 Avec Symfony 2

Symfony 2 est un framework PHP qui modernise la plateforme en la rapprochant de RoR et autres.

Pour utiliser le serveur intégré à PHP 5.4 avec Symfony 2, placez-vous dans le sous-répertoire web de votre projet. Puis exécutez :

php -S 127.0.0.1:8080

Vous pourrez alors accéder à Symfony 2 dans votre navigateur via http://127.0.0.1:8080/app_dev.php.

PostgreSQL / PostGIS

Passez tout simplement par Homebrew :

brew install postgis

Des composantes de Python auront peut-être besoin d’êtres installées. Suivez les instructions à l’écran.

Initialisez votre base de données :

initdb /usr/local/var/postgres -E utf8

Lancez automatique PostgreSQL à l’ouverture de session :

ln -sfv /usr/local/opt/postgresql/*.plist ~/Library/LaunchAgents

Lancez PostgreSQL dès maintenant :

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist

Connectez-vous à votre base de données (nom d’utilisateur = nom d’utilisateur de session) :

psql postgres

Vous pouvez alors voir la liste des extensions installées :

SELECT * FROM pg_available_extensions;

« \q » pour quitter la console PostgreSQL.

MongoDB

Encore une fois, Homebrew est parfaitement adapté :

brew install mongodb

Lancez MongoDB à chaque ouverture de session :

ln -sfv /usr/local/opt/mongodb/*.plist ~/Library/LaunchAgents

Lancez MongoDB dès maintenant :

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mongodb.plist

Ou, ponctuellement, via le Terminal :

mongod

Connectons-nous au serveur :

mongo

Testons un peu mongo :

db.test.save({ age: 29, "fullname":"Florent Morin"}) db.test.find()

Qui devrait retourner quelque-chose comme :

{   "_id" : ObjectId("51a9bb4d6121d24a661f17a0"),   "age" : 29,   "fullname" : "Florent Morin" }

Memcached

Si on veut bien faire les choses, et pour bien tester les projets en mode « staging » avant de les envoyer en production, l’installation de « memcached » est indispensable.

brew install memcached

Pour le lancement automatique à l’ouverture de session :

ln -sfv /usr/local/opt/memcached/*.plist ~/Library/LaunchAgents

Pour le lancement immédiat :

launchctl load ~/Library/LaunchAgents/homebrew.mxcl.memcached.plist

Testons :

telnet localhost 11211

Puis, en telnet :

stats

Pour quitter :

quit
Share
Développement Ruby Ruby on Rails Serveur Web

Installation de Ruby et Rails sur un serveur Ubuntu 12.10

Nous allons découvrir dans cet article comment avoir un serveur clé en main, idéal comme machine virtuelle.

Installer et mettre à jour Ubuntu Server 12.10

Téléchargez Ubuntu Server 12.10 et installez le système à votre guise.

Pour ma part, j’ai fait l’installation dans une machine virtuelle Parallels 8 à partir de l’image disque Ubuntu officielle.

Afin d’accéder à la machine à distance, pensez à installer le serveur OpenSSH.

Ensuite, une mise à jour des paquets ne peut pas faire de mal.

Installer RVM

Pour installer RVM, une simple ligne de commande suffit.

curl -L get.rvm.io | bash -s stable

Ensuite, chargez RVM.

source ~/.profile

Puis activez RVM autolibs.

rvm autolibs enable

Lancez RVM requirements afin de mettre à jour automatiquement votre système.

rvm requirements

Installer Ruby

RVM permet d’installer plusieurs versions de Ruby sur une même machine. Nous allons donc installer la dernière en date : Ruby 2.0.0.

rvm install 2.0.0

Puis nous allons définir cette version comme version à utiliser par défaut.

rvm --default 2.0.0

Vérifiez l’installation. Vous devriez voir 2.0.0.

ruby --version

Parfois, il faut se déconnecter et se reconnecter afin que RVM soit bien rechargé.

Installer RubyGems

Pour continuer d’utiliser RVM afin d’installer les gems Ruby, utilisez la commande suivante.

rvm rubygems current

 Installer Rails

Nous allons utiliser gems afin d’installer Rails dans sa dernière version (3.2 à ce jour)

gem install rails

L’environnement Ruby on Rails est maintenant installé.

Il va maintenant falloir faire en sorte de pouvoir l’exécuter sur un serveur de production.

Installer Passenger

Passenger permet d’exécuter une application Rails au sein d’un serveur apache ou nginx.

gem install passenger

Tant que la version 4.0 n’est pas stable, installez-la via la commande suivante.

gem install passenger --version 4.0.0.rc6

Installer nginx et son module Passenger

RVM permet de simplifier l’installation du serveur nginx et du module Passenger.
Tout d’abord, installez les bibliothèques nécessaires.

sudo apt-get install libcurl4-openssl-dev

Ensuite, lancez l’assistant.

rvmsudo passenger-install-nginx-module

Pressez « Entrer ».
Prenez le choix par défaut en tapant « 1″, puis pressez la touche « Entrer ».
Validez le répertoire par défaut.
Laissez le système faire la suite : ça peut durer une petit moment. (5-10 minutes)

Lancer automatiquement nginx au démarrage

Première étape : arrêter toute instance éventuelle de nginx.

sudo kill `cat /usr/local/nginx/logs/nginx.pid`

Ensuite, éditez le fichier /etc/init.d/nginx

#! /bin/sh   ### BEGIN INIT INFO # Provides:          nginx # Required-Start:    $all # Required-Stop:     $all # Default-Start:     2 3 4 5 # Default-Stop:      0 1 6 # Short-Description: starts the nginx web server # Description:       starts nginx using start-stop-daemon ### END INIT INFO   PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/opt/nginx/sbin DAEMON=/opt/nginx/sbin/nginx NAME=nginx DESC=nginx   test -x $DAEMON || exit 0   # Include nginx defaults if available if [ -f /etc/default/nginx ] ; then         . /etc/default/nginx fi   set -e   case "$1" in   start)         echo -n "Starting $DESC: "         start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \                 --exec $DAEMON -- $DAEMON_OPTS         echo "$NAME.\n"         ;;   stop)         echo -n "Stopping $DESC: "         start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \                 --exec $DAEMON         echo "$NAME.\n"         ;;   restart|force-reload)         echo -n "Restarting $DESC: "         start-stop-daemon --stop --quiet --pidfile \                 /opt/nginx/logs/$NAME.pid --exec $DAEMON         sleep 1         start-stop-daemon --start --quiet --pidfile \                 /opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS         echo "$NAME.\n"         ;;   reload)       echo -n "Reloading $DESC configuration: "       start-stop-daemon --stop --signal HUP --quiet --pidfile /opt/nginx/logs/$NAME.pid \           --exec $DAEMON       echo "$NAME.\n"       ;;   *)         N=/etc/init.d/$NAME         echo "Usage: $N {start|stop|restart|force-reload}\n" >&2         exit 1         ;; esac exit 0

Rendez ce fichier exécutable.

sudo chmod +x /etc/init.d/nginx

Mettez à jour les runlevels des scripts lancés au démarrage.

sudo /usr/sbin/update-rc.d -f nginx defaults

Vous pouvez également ajouter /opt/nginx/sbin/ à votre PATH.

Ajoutez ensuite un utilisateur nginx à votre système.

sudo adduser --system --no-create-home --disabled-login --disabled-password --group nginx

Redémarrez votre serveur pour être bien sûr que tout fonctionne.

Si vous vous connectez via un navigateur web à votre serveur, vous devriez être accueilli par le message « Welcome to nginx! ».

Liez votre serveur web à votre app

Si ce n’est déjà fait, installez NodeJS. Certaine dépendances sont nécessaires au bon fonctionnement de Rails (en particulier grâce à la bibliothèque Javascript V8).

sudo apt-get install nodejs

Editez le fichier de configuration de nginx, /opt/nginx/conf/nginx.conf, en particulier la partie serveur :

server {   listen 80;   server_name demo.com;   passenger_enabled on;   root /var/www/app/public; }

Créons le répertoire /var/www et positionnons-nous à sa racine.

sudo mkdir -p /var/www && cd /var/www && chmod -R 777 .

Installons bundler.

gem install bundler

Il ne reste plus qu’à créer l’app de test.

rails new app && cd app

Pré-compilez les assets.

RAILS_ENV=production rake assets:precompile

Accédez à votre serveur depuis un navigateur : vous arriverez sur l’écran d’accueil de Rails.

Initialiser un dépôt git

Nous allons supprimer le contenu de l’app de test sur le serveur pour réinitialiser le répertoire /var/www/app.

Depuis le répertoire /var/git/app.git (nouvellement créé), initialisons le dépôt git.

git init --bare

Allons sur notre machine de développement.
Ajoutons le répertoire distant. (à personnaliser)

git remote add virtual ssh://ubuntu@192.168.1.39/var/git/app.git

Envoyons le contenu du code sur le serveur.

git push virtual master

Il vous suffit alors de cloner votre dépôt dans le répertoire /var/www/app et le tour est joué !

Si vous voulez faire plus simple…

Dans l’exemple d’aujourd’hui, vous avez vu la méthode « douloureuse » du déploiement Ruby on Rails. C’est formateur mais parfois indigeste.
Si vous n’avez pas trop de temps à perdre, passez par des solutions plus simples et au moins aussi efficaces telles que Heroku.

Share
Développement Web

Les services web RESTful

Les services web sont aujourd’hui au coeur du web et au coeur des applications connectées.

Pour cela, beaucoup de services et d’outils utilisent le modèle REST. Sur iOS, on peut notamment citer l’excellent framework AFNetworking permettant d’accéder aux services web et son prometteur petit frère AFIncrementalStore qui permet lui de synchroniser cache local et service distant.

Pour autant, comment un service web être réellement RESTful ?

Cette question est en suspend depuis quelques années. Au travers de cet article, amené à évoluer, je vais tâcher d’apporter quelques éléments de réponses.

REST : kézako ???

Déjà, qu’est-ce REST ?

C’est un modèle d’organisation de service web exploitant au maximum le protocole HTTP et les standards du web afin d’être aussi léger que performant.

Le principe est d’accéder à des ressources en suivant le modèle objet.

Définition du service web

Afin de définir les ressources du service web, il suffit d’accéder à la racine de l’API.

Par exemple :

{   "url": "https://api.monservice.com",   "resources": {     "cars": {       "url": "https://api.monservice.com/cars"     },     "accounts": {       "url": "https://api.monservice.com/accounts"     }   } }

 

URL des ressources

Les resources sont accessibles via des URL.

Par convention, on utilisera toujours le pluriel pour les collections. Et on utilisera toujours des noms pour identifier les ressources.

Par exemple :

/cars : ensemble de voitures

/cars/count : nombre total de voiture

/cars/12 : voiture « 12″

/cars/12/options : options disponibles pour la voiture « 12″

/cars_models : toutes les relations entre voiture et modèle (many to many)

Options d’affichage

Il est possible de passer des paramètres dans les URL.

Par convention, pour n’afficher que certains champs, on utilisera « fields » séparé par des virgules ».

/cars?fields=immatriculation,color : je veux seulement les champs « immatriculation » et « color »

Egalement, on peut filtrer les résultats sur certains champs en les passant en paramètres.

/cars?color=red : seulement les voitures rouges

/cars?model.name=volvo : seulement les voiture dont le nom du modèle est volvo (certains caractères n’ont volontairement pas été échappés)

Pagination

Certaines options peuvent être passées dans l’URL afin de gérer la pagination.

- offset : premier résultat affiché

- limit : nombre maximal de résultats par page

- until : date maximale de création

- since : date minimale de création

- since_id : identifiant le plus ancien

- max_id : identifiant le plus récent

Cela permet de gérer un chargement progressif de manière très fiable.

L’en-tête HTTP « Link », avec les liens et les options « rel » (« next », « previous ») permet également de paginer la réponse.

L’en-tête HTTP « X-Result-Count » permet d’avoir le nombre total de résultats.

Aussi, on peut utiliser « Content-Range ». Ex. « Content-Range: cars 0-20/2550″. Et l’en-tête en requête serait « Range: cars=0-20″.

Actions

Idéalement, une action est définie par un verbe. La méthode HTTP dépend d’une modification ou non du contenu de la ressource ciblée.

POST /cars/12/buy : acheter la voiture « 12″

GET /cars/search : rechercher une voiture

Les verbes HTTP

Pour les ressources, utilisez la méthodes CRUD (Create, Read, Update, Delete) .

POST /cars : ajouter une voiture (redirige vers la ressource créée)

GET /cars/12 : voir la voiture 12

HEAD /cars/12 : savoir si la voiture 12 existe (aucune ressource retournée)

PUT /cars/12 : mettre à jour intégralement la voiture 12 (redirige vers la ressource mise à jour)

PATCH /cars/12 : mettre à jour intégralement la voiture 12 (redirige vers la ressource mise à jour)

DELETE /cars/12 : supprimer la voiture 12

OPTIONS /cars : description des actions possibles sur les ressources de type « cars » (via l’en-tête Allow, access-control-allow-methods, access-control-allow-origin et une description explicite dans le corps)

Pour les actions, on utilise souvent GET.

Lorsque l’on utilise AJAX, sur les navigateurs web par exemple, on n’a pas accès à PUT ou DELETE.

Ce n’est pas un problème : passez le paramètre « _method » avec comme nom la méthode HTTP à utiliser. Si vous utilisez un framework comme par exemple Ruby on Rails, la méthode sera automatiquement gérée.

Format des données

Plusieurs formats peuvent être utilisés. Ils sont définis en priorité par l’extension de l’URL, mais également par le Content-Type ou le Accept de la réponse et/ou de la requête.

application/xml est le plus ancien.

application/json est le plus courant. Parfaitement adapté aux services web orientés REST.

application/x-www-form-urlencoded est utilisé lors d’envoi de données. Chaque clé correspondant à une propriété de l’objet.

multipart/form-data est lui particulièrement adapté pour l’envoi de données binaires. Chaque champs correspond à une propriété et chacune de ces propriétés peut adopter son propre format. (binaire, XML, JSON, texte)

Format des dates et heures

Les dates et heures ont leur propre standard : ISO-8601.

Utilisez le format court pour les dates et le format complet pour date et heure.

Les codes HTTP

200 : message de réponse bien interprétée

201 : une ressource a été crée

304 : rien n’a été modifié

400 : requête non comprise

401 : accès non autorisé à l’utilisateur

403 : accès purement et simplement interdit

404 : élément non trouvé

500 : erreur du serveur

DNS

Utilisez, dans la mesure du mesure, un nom de domaine spécifique pour vos API.

ex. http://api.monservice.com

Version

Utilisez un chemin spécifique pour chaque version de votre API.

ex. http://api.monservice.com/v1/

Faire référence à une autre ressource

Utilisez les suffixes « _url » ou « _href » qui sont particulièrement adaptées. Surtout si vous faites références à des objets binaires.

Pour une autre entité, vous pouvez utiliser « _id » ou « _identifier ».

Identifier une ressource

On identifie une ressource soit par « id », soit par « identifier ». Parfois aussi par « url » ou « href ».

Représentation binaire

Certains objets ont des propriétés binaires.

Selon le volume d’information, utilisez :

- soit « url » / « href » ou « maprioriete_url »  pour faire référence à une URL de téléchargement

- soit « data » ou « mapropriete_data » afin de proposer une représentation encodée en Base64 des données.

Envoyer / récupérer des données binaires

Pour envoyer par exemple une photo avec un commentaire, utilisez le multipart/form-data.

POST /photos

champs « comment » : contenu texte

champs « photo » : la photo, en binaire

champs « thumb » : la miniature de la photo, en binaire

En réponse, ou à la lecture :

GET /photos/12

{   "id": 12,   "comment": "mon texte",   "photo_url": "http://lien_vers_photo.jpg",   "thumb_url": "http://lien_vers_thumb.jpg" }

C’est finalement très simple. :-)

Vous pouvez également choisir d’avoir des objets spécifiques pour les fichiers à télécharger, ce qui peut être pratique pour avoir par exemple les dates de modification.

{   "id": 12,   "comment": "mon texte",   "photo": {     "url": "http://lien_vers_photo.jpg",     "updated_at": "2013-04-22T06:00:00Z"   },   "thumb": {     "url": "http://lien_vers_thumb.jpg",     "updated_at": "2013-04-22T07:00:00Z"   }, }

 Gestion des erreurs

Ne pas avoir de code erreur autres que 200 ou 500 peut parfois s’avérer utile.

Pour cela, utilisez le paramètre « suppress_error_codes » dans votre URL.

Egalement, pensez à renvoyer un message d’erreur explicite.

{   "errors": [     {       "message": "Password length is at least 8 characters.",       "code": 400     },     {       "message": "Email format is invalid.",       "code": 400     }   ] }

Gestion du cache

L’utilisation des en-têtes Etag/If-not-match permet une gestion plus efficace du cache.

Egalement, les en-têtes Last-Modified/If-modified-since sont très efficaces côté performances.

Authentification

Si vous souhaitez authentifier votre client et/ou votre utilisateur, je ne peux que vous recommander le protocole OAuth 2.0.

Il est simple, fiable et performant. Particulièrement adapté aux services web moderne.

L’authentification basique sur du HTTPS est également fiable et a l’avantage d’être la plus simple de toutes.

Limites

Les limites d’accès aux ressources peuvent être définies via les en-têtes HTTP X-RateLimit-Limit et X-RateLimit-Remaining. X-RateLimit-Reset permet de définir à quelle date/heure la limite va être réinitialisée.

Outils de développement

Les outils de développement les plus adaptés sont les suivants.

Si vous ne connaissez que le PHP, utilisez le framework Symfony 2 (Dailymotion) qui est bien conçu pour les services web.

Si vous êtes plus à l’aise avec Java/Scala, le framework Play est assez sympa, bien qu’un peu jeune.

Si vous êtes à l’aise avec Ruby, je ne peux que vous conseiller le framework Ruby on Rails (Twitter, Shopify, Groupon, GitHub, Linkedin) et/ou son petit cousin Sinatra (idéal pour le prototypage rapide).

Si vous êtes aventurier et que vous visez plus de performances, Node.js (Linkedin, eBay) peut être utilisé seul ou en parallèle de l’un des frameworks pré-cités.

Share
Web

Installer Ruby 1.9, Ruby on Rails 3 et Passenger sur un serveur Apache 2 sous Ubuntu 12.04

Comme beaucoup aujourd’hui, vous avez choisi d’utiliser les services d’Amazon Web Service pour vos déploiements de solutions web.

Seulement, plutôt que d’utiliser le classique Apache + PHP + MySQL, vous vous orientez vers une solution à base de Ruby on Rails.

Les instances EC2 d’Amazon utilisent, dans leur version Linux, Ubuntu 12.04 Server LTS. Et c’est là qu’est le problème : Ubuntu 12.04 est fourni en standard avec Ruby 1.8. Les dernières versions de Rails 3 nécessitent la version 1.9 de Ruby et il en va de même pour les futures versions.

Je vais donc considérer que vous avez en place un système Ubuntu 12.04 fonctionnel, ainsi que le serveur Apache 2 pleinement opérationnel.

Cet article est fortement inspiré d’une autre source orientée Nginx / PostgreSQL.

Première étape : installer les paquets pré-requis

Mettez à jour vos paquets via Aptitude.

sudo aptitude update;sudo aptitude upgrade

Puis, installez les paquets nécessaires à la suite des opérations.

sudo aptitude install build-essential zlib1g-dev libssl-dev libreadline-dev libyaml-dev libcurl4-openssl-dev curl git-core python-software-properties wget apache2-prefork-dev

Si vous utilisez une base de données MySQL

sudo aptitude install libmysqlclient-dev

Ou PostgreSQL

sudo aptitude install libpq-dev

Installer Ruby 1.9

Au moment de la rédaction de cette article, la dernière version en date de Ruby est la 1.9.3-p374.

Téléchargez et décompressez l’archive.

wget ftp://ftp.ruby-lang.org/pub/ruby/1.9/ruby-1.9.3-p374.tar.gz tar -xvzf ruby-1.9.3-p374.tar.gz

Allez dans le répertoire des sources et compiler le tout.

cd ruby-1.9.3-p374/ ./configure make

Installez Ruby. (installé dans /usr/local)

sudo make install

Configurez Gem. (optionnel mais conseillé dans une configuration serveur)

echo "gem: --no-ri --no-rdoc" >> ~/.gemrc

Enfin, installez le gem Bundler.

sudo gem install bundler

Installer Passenger

Passenger permet de lancer des applications Ruby on Rails directement via Apache ou Nginx.

Installons Passenger.

sudo gem install passenger

Installons maintenant le module Passenger pour Apache 2.

sudo passenger-install-apache2-module

Un assistant va se lancer : laissez le faire son job.

Il faut maintenant créer les fichiers de configuration.

/etc/apache2/mods-available/passenger.conf

PassengerRoot /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.19 PassengerRuby /usr/local/bin/ruby PassengerUserSwitching off PassengerDefaultUser www-data

/etc/apache2/mods-available/passenger.load

LoadModule passenger_module /usr/local/lib/ruby/gems/1.9.1/gems/passenger-3.0.19/ext/apache2/mod_passenger.so

Ensuite, activons le module passenger.

sudo a2enmod passenger sudo service apache2 restart

Pour déployer une application Ruby on Rails, il suffit de créer le fichier de configuration correspondant dans le répertoire /etc/apache2/sites-available.
Appelons ce fichier /etc/apache/sites-available/test.

On considère que le répertoire où est installée l’application est /var/www/test.

<VirtualHost *:80>     ServerAdmin webmaster@test.fr     ServerName test.fr       PassengerDefaultUser www-data       DocumentRoot /var/www/test/public     <Directory /var/www/test/public>         AllowOverride all         Options -MultiViews     </Directory> </VirtualHost>

Le fichier est configuré. Vérifiez les autorisations sur /var/www/test.
Vérifiez que vous avez installé les gems nécessaires et que vous avez pré-compilé vos assets.
Dans le répertoire de l’application, pensez à réinitialiser l’app.

touch tmp/restart.txt

Ensuite, on peut activer le site.

sudo a2ensite test sudo service apache2 reload

Normalement, tout devrait être opérationnel. :-)

Share
Développement Web

Installer Symfony 2 sur un serveur mutualisé OVH

Votre application Symfony 2 fonctionne à merveille chez vous. Tout va dans le meilleur des mondes. On passe au déploiement et là : c’est le drame.

Si, vous aussi, vous avez connu ce genre de scenario sur un serveur mutualisé OVH, vous êtes au bon endroit.

Voici une procédure toute simple pour faire fonctionner le tout sans avoir à passer systématiquement par le répertoire /web.

Etape 1 : vérifiez que votre application web est prête

Attention aux fichiers CSS et Javascript générés par l’app : ils doivent être accessibles à la racine de l’app.

Etape 2 : installer l’application

Copiez le contenu de votre application web à la racine du site.

Mettez les droits en 755. Au besoin, mettez les droits de /app/cache à 777.

Pensez à vider le répertoire de cache.

Etape 3 : .htaccess à la racine du site

Voici un exemple de fichier .htaccess qui fonctionne :

SetEnv SHORT_OPEN_TAGS 0 SetEnv REGISTER_GLOBALS 0 SetEnv MAGIC_QUOTES 0 SetEnv SESSION_AUTOSTART 0 SetEnv ZEND_OPTIMIZER 1 SetEnv PHP_VER 5_3  AddType x-mapp-php5 .php   RewriteEngine on   RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ web/app.php [QSA,L]

Etape 4 : .htaccess dans le répertoire web

Un autre fichier .htaccess doit être créé, mais dans le répertoire /web :

SetEnv SHORT_OPEN_TAGS 0 SetEnv REGISTER_GLOBALS 0 SetEnv MAGIC_QUOTES 0 SetEnv SESSION_AUTOSTART 0 SetEnv ZEND_OPTIMIZER 1 SetEnv PHP_VER 5_3  AddType x-mapp-php5 .php   RewriteEngine On   RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ app.php [QSA,L]

Etape 5 : testez

Normalement, tout est en place. Vous pouvez accéder à votre site depuis la racine.

Share
Développement Mac OS X Web

Le développement web sur Mac

Un rapide article pour vous présenter les différents outils vous permettant d’être rapidement opérationnel pour le développement web sur Mac OS X.

Apache / PHP / Ruby On Rails / MySQL

Concernant Apache, il faut savoir que le serveur est déjà installé d’origine sur le Mac, il y a juste à le configurer dans les options de partage. Il en va de même pour PHP 5 et Ruby.

Pour installer Ruby On Rails, gem sera votre allié.

Pour ce qui est de MySQL, ce n’est guère plus compliqué : vous trouverez la version serveur sur le site officiel. Je vous conseille également l’outil MySQL Workbench qui est très bien fait pour gérer ses bases de données.

L’éditeur TextMate

L’éditeur ViM est intégré à Mac OS X. Cependant, je ne suis pas certain qu’il satisfasse tout le monde.

Personnellement, j’utilise TextMate. Il coûte 45 € mais il est très performant. On peut le tester pendant 30 jours gratuitement.

Son gros avantage est qu’il est généraliste et intègre de nombreux Bundles, et certains se trouvent également sur le web : ActionScript, PHP, Apache, JavaScript, HTML, CSS, Git, Subversion, SQL, Prototype / Script.aculo.us, JQuery, JQTouch,  Ruby On Rails, SproutCore, XML, Perl, Cake PHP, Python… Et ça, uniquement pour les langages web.

Il permet par exemple de compresser le JavaScript, déboguer le code, avoir une auto-complétion efficace.

CyberDuck

Une fois que l’on a testé le code localement, on souhaite bien entendu l’envoyer sur un serveur. CyberDuck permet de gérer correctement tout type de serveur. Il est relativement puissant et regorge de fonctionnalités et de protocoles. (FTP, FTPS, SSH, ..)

Il est disponible en version gratuite (donation optionnelle) ou payante si le logiciel convient. ( 18,99 € sur le Mac App Store )

Synchronisation FTP / SSH avec MacFusion

Pouvoir éditer le code avec TextMate en sélectionnant les fichiers dans CyberDuck, c’est bien.

Pouvoir accéder au projet complet dans un répertoire donnée synchronisé avec le serveur, c’est mieux !

Pour cela, installez MacFUSE.

Ensuite, installez Macfusion.

Et c’est parti, vous pouvez synchroniser comme vous voulez n’importe quel répertoire en montant le répertoire distant localement.

Le débogage

Les différents navigateurs intègrent chacun leurs outils de débogage.

Concernant Safari, le navigateur par défaut de Mac OS X, vous pouvez afficher le menu Développement en passant par les préférences avancées.

Par exemple, grâce à l’inspecteur web (qui s’affiche justement via le menu développement), vous pouvez voir comment sont gérées les ressources, comment est organisée la hiérarchie de votre page, vous pouvez également entrer du code javascript à la volée… c’est vraiment très pratique.

Tester les services web

Souvent, nous avons accès à des services web permettant d’exploiter telle ou telle ressource. Cependant, il est souvent bien difficile de les tester.

Il y a bien entendu l’outil curl, accessible en ligne de commande, qui permet d’effectuer des tests complets, mais qui reste très austère.

Personnellement, j’utilise HTTP Client, disponible pour 1,59 € sur le Mac App Store. Il permet d’effectuer des tests rapidement et de voir les données HTTP brutes, le tout dans une interface graphique simple mais efficace.

RapidWeaver : l’éditeur WYSIWYG

RapidWeaver est disponible sur le Mac App Store pour 39,99 € et vous permet de concevoir très rapidement des sites web, sans connaissances techniques.

Pour les applications web

Le kit de développement fourni avec XCode intègre Dashcode, qui permet de concevoir visuellement des applications web pour Mac, iPhone et iPad.

MobDis, disponible gratuitement sur le Mac App Store, permet de concevoir des applications web également.

Share
iPad iPhone Mac OS X Web

Apple, le marché des apps : aujourd’hui et demain

Les parts de marché d’Apple sur ses différents secteurs d’activité méritent parfois quelques explications. Cet article a pour but d’éclaircir un peu les choses.

Le Mac

A ce jour, les parts de marché du Mac sont grosso-modo de 10 % au niveau mondial. L’évolution est régulière, avec une croissance annuelle de 23 % environ, soit 8 fois plus que les ventes de PC.

Ce qu’il faut savoir, c’est que 50 % des ventes sont des migrations de PC vers Mac.

De plus, depuis Janvier, le Mac dispose d’un App Store. Et le développement sur Mac repose sur la même base que le développement sur iOS. Hors, les iPad et iPhone doivent leur succès essentiellement à l’App Store.

Dernier élément à prendre en compte, l’arrivée imminente de Mac OS X Lion, prévu pour l’été 2011 (Windows 8 sortira en 2012). Tout comme l’iPad ou l’iPhone, il est centré autour des mêmes éléments qui ont été la recette du succès :

  • Mac App Store : un App Store totalement intégré au système, plus besoin de chercher des logiciels douteux sur le web ou bien acheter 4 fois la même application
  • du multi-touch : tout est centré autour du multi-touch, comme sur iOS, avec des actions à 1-2-3-4 doigts (retourner, agrandir, défiler, tapoter)
  • Launchpad : pour faire simple, il s’agit d’avoir une interface d’accès aux applications similaire à celle de l’iPad ou de l’iPhone
  • les apps en plein écran : la plupart des app peuvent être exécutées en plein écran et le passage de l’une à l’autre se fait en un glissement de doigts
  • quand on arrête une application, on reprend là où on était, comme sur iOS.

Il y a en plus tous les avantages du Mac : enregistrement automatique des différentes versions d’un fichier (avec machine à voyager dans le temps pour revenir à une précédente version) , les outils principaux pré-installés, les fonctionnalités serveur intégrées et un aspect fiabilité / sécurité mis à l’épreuve.

Aujourd’hui, un iMac coûte 1200 euros, un Macbook Air coûte 1000 euros, un Macbook coûte 1000 euros. C’est beau, c’est écologique et c’est prévu pour durer dans le temps. (compter 5 ans avant d’être obsolète, contre 3 ans pour un PC)

De là à dire que cela va favoriser son adoption auprès du grand public, ce serait comme dire que le grand public achètera un jour des applications sur son téléphone ou bien une tablette moins puissante qu’un ordinateur et plus grosse qu’un smartphone.

iPad

L’iPad n’aurait, selon les experts, jamais dû fonctionner car « inutile et trop grand ». « Il ne fait même pas téléphone ». « C’est un iPhone en plus gros ». Certes.

l’iPad 2 sort en mars 2011. Il est 2 fois plus rapide que son prédécesseur, 9 fois plus rapide sur les jeux vidéo (se situe au dessus de la Wii, un peu en dessous de la XBox 360). Il possède une sortie TV le poussant donc vers le jeu vidéo. Là où il est déjà expert. (Unreal Engine 3, moteur 3D présent sur de nombreuses consoles, a été adapté à iOS)

Il est leader du marché avec 90% des parts.

Son App Store est le plus gros existant.

Il est le moins cher de tous.

Il a même forcé Samsung à revoir sa stratégie.

Que dire de plus ?

iPhone

Encore une fois, un produit qui n’aurait jamais dû marcher : « Trop cher. », « Qui installerait des applications sur un téléphone ? », « On ne pourra jamais détrôner Sony et Nintendo avec les consoles portables ».

10 milliards de téléchargements sur App Store plus tard, 500 000 apps disponibles : c’est la plateforme d’applications qui a le plus grand succès et qui rapporte le plus aux développeurs.

En termes de parts de marchés des smartphones connectés en France, on est à 70 % environ selon GS StatsCounter, malgré 30% des ventes. On compte environ 30 % aux Etats-Unis. Les grands concurrents sont Blackberry (sur le déclin) et Android.

« Android est en plein essor » : oui, on remplace les téléphone Samsung avec OS maison par des Samsung Android. Et après ? Proportionnellement, Android devrait terrasser Apple sur le marché App Store. Hors, c’est loin d’être le cas. C’est d’ailleurs ce que les statistiques mettent en avant : si 30 % des ventes sont sur Android, partagées équitablement avec iOS et Blackberry, les connexions à Internet (Web, Mail, App Store) se font pour 70 % sur iOS, 20 % sur Android et 10 % sur les autres appareils. Et la découverte de plusieurs vers sur la plateforme de Google ne va pas arranger les choses.

Ce qu’il faut également prendre en compte, au delà du fait que l’Androphone est bien pour mémé qui a l’impression d’avoir un iPhone, c’est que le coût de développement est supérieur sur Android. On entâme donc la rentabilité. Surtout si la plateforme n’a pas un succès prépondérant sur le téléchargement des applications.

En terme de qualité, il faut également savoir que les consommateurs regardent de plus en plus au côté écolo. Hors, Apple travaille sur ce créneau, en faisant le bon équilibre avec la puissance du matériel et en favorisant le recyclage. L’entrée de gamme n’a jamais été en faveur de cet aspect.

Un autre point à ne pas négliger est l’arrivée de l’iPhone sur les réseaux CDMA, ce qui va apporter de nouvelles parts de marché à Apple aux Etats-Unis et en Asie.

Dernier point essentiel à prendre en compte est l’arrivée de l’iPhone 5, qui comme son grand frère l’iPad devrait être plus puissant et équipé du même type de matériel. L’aspect console de jeu dans la poche risque donc de se confirmer.

Avec iOS 4.3, la compatibilité iPhone 3G disparaît : un boulet en moins pour les développeurs. Les nouvelles applications seront donc compatibles avec ce matériel, mais pas de manière optimale. C’est l’obsolescence programmée. Chaque utilisateur pourra revendre son iPhone à son opérateur pour en acheter un neuf, moyennant une centaine d’euros en plus.

Qui dit matériel récent, dit de nouvelles possibilités en termes de développement.

iOS 5 : arrivée imminente

Que peut-on imaginer avec iOS 5, qui arrive cet été :

  • base Mac OS Lion au lieu de Snow Leopard (n’intéresse que les développeurs)
  • base matérielle limitée : de nouvelles possibilités en terme d’interface, avec plus d’effets
  • tout le matériel compatible est compatible avec OpenGL ES 2.0 : les jeux vidéos seront encore plus beaux
  • qui dit OpenGL ES 2.0 dit WebGL : le standard WebGL 1.0 vient d’être arrêté, son développement sur Mac est bien avancé et son développement sur iOS ne doit pas être loin derrière
  • exploitation optimale de Grand Central Dispatch : cette technologie qui est arrivée avec iOS 4 permet d’exploiter au mieux le multi-coeurs des nouveaux appareils, les applications existantes sont donc déjà optimisées
  • accéléromètre, GPS et boussole à tous les étages : tout le matériel supporté par iOS 5 permet la réalité augmentée, grâce à la disparition de l’iPhone 3G
  • caméra en façade sur les appareils récents, donc nouvelles possibilités
  • plus de puissance minimale = nouveaux outils pour les développeurs

En clair, la stratégie d’Apple consistant à avoir une visibilité sur 2-3 ans permet d’écraser la concurrence de la manière suivante :

  • le système iOS est très souple, donc le travail de migration d’une app vers iOS 5 est limité si on s’y est préparé
  • un nombre d’appareils limité signifie un travail d’optimisation moins long
  • ce même aspect favorise l’exploitation maximale des capacités techniques
  • la mise à jours de l’OS permet de redonner un coup de fouet au matériel, comme nous l’avons vu avec la sortie de iOS 4 sur iPad

iOS : la sécurité business

Pour conclure, les aspects importants à connaître sont donc les suivants :

  • parts de marché limitées sur le matériel ne signifie en aucun cas parts de marché limitées sur les apps (cf. Blackberry)
  • sans iOS, les tablettes et smartphones seraient livrés avec un stylet, un clavier rétractable et Windows Mobile
  • de tous les mauvais présages, aucun n’est arrivé
  • Apple garantie une compatibilité maximale sur 2 générations, une compatibilité minimale sur 3 générations : le coût est donc à calculer sur 2 ans, sans mauvaise surprise
  • un appareil iOS, ça se recycle : un cycle de consommation immatérielle
  • en restant sur du haut de gamme, Apple conserve ses parts de marchés à un bon niveau
  • Apple reste leader incontesté sur le marché des apps, malgré une concurrence très forte
  • la publicité sur iOS est plus percutante que la publicité télévisuelle
  • qui d’autre peut garantir une visibilité maximale sur la tranche de population la plus consommatrice ?
Share
Applications iPhone Mac OS X Web

Pas de Flash pour l’iPhone ni l’iPad : le détail

Le plugin Flash n’est pas disponible sur plateforme iPhone OS et cela suscite beaucoup d’interrogations. Nous allons donc tâcher d’expliquer le pourquoi du comment.

Historique

Flash est disponible sur plateforme MacOS depuis de nombreuses années. Des cumuls de fonctionnalités sont arrivés les uns à la suite des autres, apportant chacun leur lots de nouveautés.

Cependant, au fur et à mesure des versions, Flash sur Mac OS X s’est avéré de plus en plus lourd et lent.

Puis est arrivé iPhone OS : un Mac OS X mobile. Même architecture, donc portage simplifié.

Cependant, Apple a jugé le plugin trop lourd et trop plantogène pour l’iPhone. Il n’a donc pas été inclus.

Pourquoi Flash est-il lourd sur Mac OS X et iPhone OS ?

La raison est simple : la plateforme Mac a évolué, le plugin Flash n’a pas suivi.

Pour vérifier cela, il suffit de regarder ce qu’utilise le plugin Flash sur Mac OS X.

otool -L /Library/Internet\ Plug-Ins/Flash\ Player.plugin/Contents/MacOS/Flash\ Player

Et que voyons-nous ?

Flash utilise Carbon qui est l’ancienne base de Mac OS conservée pour des raisons de compatibilité. La nouvelle base de Mac OS X est en effet connue sous le nom de Cocoa.

Qu’est-ce que cela implique ?

  • Pas de 64 bits,
  • Le matériel n’est pas exploité de manière optimale,
  • L’intégration au système est minimale,

Du coup, iPhone OS subit les mêmes problèmes (d’autant qu’il n’est pas compatible Carbon) . Et ça, Steve Jobs ne l’accepte pas.

Des efforts en cours

Des efforts pour la prochaine version de Flash semblent mis en oeuvre. En effet, Adobe a annoncé avoir optimisé Flash sur Mac OS X.

Pour cela, ils vont commencer par utiliser Core Animation (Quartz Core) qui permet d’afficher des animations 2D optimisées pour le matériel.

De même, la lecture de vidéo sera optimisée.

Du coup, Core Animation faisant partie de Cocoa, il y a fort à parier qu’une version 64 bits fassent son apparition dans la foulée.

Et si Flash utilise pleinement les possibilités de Cocoa sur Mac OS X, il y a de bonnes chances pour qu’Apple finisse par accepter la version mobile qui, reposant sur la même base, sera optimisée pour l’iPhone OS.

La poêle et le chaudron

Apple semble très fort en donneur de leçon sur ce coup-là.

A en croire leur propos, tous leurs logiciels semblent pleinement optimisés.

Sauf qu’il y a un vilain petit canard. iTunes, l’un des logiciels phares d’Apple, n’utilise Cocoa que partiellement. Ceci est vérifiable ainsi :

otool -L /Applications/iTunes.app/Contents/MacOS/iTunes

On voit en effet apparaître un lien prononcé avec Carbon !

Alors Monsieur Apple, à quand une version d’iTunes pleinement optimisée pour Cocoa ?

Share
Développement

xml_encode() : le XML facile

Les développeurs PHP vont certainement adorer cette fonction.

Elle permet d’encoder un tableau (à indexes ou pas) de manière efficace. Elle est basée sur un autre code qui ne fonctionnait malheureusement pas très bien.
Les CDATA sont également automatiquement insérés au besoin.
Quand il n’y a pas d’index, les données ressortent sous l’intitulé entry et la racine du document sera toujours entries.

function xml_encode($mixed, $domElement = NULL, $DOMDocument = NULL) {     if (is_null($DOMDocument)) {         $DOMDocument = new DOMDocument;         $DOMDocument->formatOutput = true;   		$rootNode = $DOMDocument->createElement('entries'); 		$DOMDocument->appendChild($rootNode);           xml_encode($mixed, $rootNode, $DOMDocument);           echo @$DOMDocument->saveXML();     } else {         if (is_array($mixed)) {             foreach ($mixed as $index=>$mixedElement) {                 if (is_int($index)) { 					$nodeName = 'entry'; 				} else { 					$nodeName = $index; 				} 				$node = $DOMDocument->createElement($nodeName); 				$domElement->appendChild($node); 				xml_encode($mixedElement, $node, $DOMDocument); 			}         } else { 			// TODO: test if CDATA if needed 			$new_node = $DOMDocument->createTextNode($mixed);               $domElement->appendChild($new_node);         }     } }

On l’utilise comme json_encode().

Par exemple :

<?php   header('Content-Type: text/xml');   function xml_encode($mixed, $domElement = NULL, $DOMDocument = NULL) {     if (is_null($DOMDocument)) {         $DOMDocument = new DOMDocument;         $DOMDocument->formatOutput = true;   		$rootNode = $DOMDocument->createElement('entries'); 		$DOMDocument->appendChild($rootNode);           xml_encode($mixed, $rootNode, $DOMDocument);           echo @$DOMDocument->saveXML();     } else {         if (is_array($mixed)) {             foreach ($mixed as $index=>$mixedElement) {                 if (is_int($index)) { 					$nodeName = 'entry'; 				} else { 					$nodeName = $index; 				} 				$node = $DOMDocument->createElement($nodeName); 				$domElement->appendChild($node); 				xml_encode($mixedElement, $node, $DOMDocument); 			}         } else { 			// TODO: test if CDATA if needed 			$new_node = $DOMDocument->createTextNode($mixed);               $domElement->appendChild($new_node);         }     } }   $entree[0] = "texte";   for ($i = 0;$i < 50;$i++) { 	$entree[$i]['nom'] = "texte pour nom ${i}"; 	$entree[$i]['valeur'] = "texte pour valeur ${i}";   	$donnes['debut'] = 0; 	$donnes['fin'] = 100; 	$entree[$i]['donnees'] = $donnes;   	for ($j = 0;$j < 5;$j++) { 		$liste[$j] = "liste ${j}"; 	}   	$entree[$i]['liste'] = $liste;   	$entree[$i]['xml'] = "donnees avec <a>balise xml</a>"; }   echo xml_encode($entree);   ?>

Affichera :

<?xml version="1.0"?> <entries>   <entry>dexte</entry>   <entry>     <nom>texte pour nom 1</nom>     <valeur>texte pour valeur 1</valeur>     <donnees>       <debut>0</debut>       <fin>100</fin>     </donnees>     <liste>       <entry>liste 0</entry>       <entry>liste 1</entry>       <entry>liste 2</entry>       <entry>liste 3</entry>       <entry>liste 4</entry>     </liste>     <xml>donnees avec &lt;a&gt;balise xml&lt;/a&gt;</xml>   </entry>   <entry>     <nom>texte pour nom 2</nom>     <valeur>texte pour valeur 2</valeur>     <donnees>       <debut>0</debut>       <fin>100</fin>     </donnees>     <liste>       <entry>liste 0</entry>       <entry>liste 1</entry>       <entry>liste 2</entry>       <entry>liste 3</entry>       <entry>liste 4</entry>     </liste>     <xml>donnees avec &lt;a&gt;balise xml&lt;/a&gt;</xml>   </entry>   <entry>     <nom>texte pour nom 3</nom>     <valeur>texte pour valeur 3</valeur>     <donnees>       <debut>0</debut>       <fin>100</fin>     </donnees>     <liste>       <entry>liste 0</entry>       <entry>liste 1</entry>       <entry>liste 2</entry>       <entry>liste 3</entry>       <entry>liste 4</entry>     </liste>     <xml>donnees avec &lt;a&gt;balise xml&lt;/a&gt;</xml>   </entry>   ... </entries>

Et voilà !

Share
Développement

Intégrer une image au code HTML

Dans ce rapide tutoriel, nous allons voir comment intégrer une image dans un code HTML.

En effet, cela peut-être pratique par exemple pour embarquer du contenu web dans un base de données.

Pour cela, il suffit d’utiliser la balise img, évidemment, ainsi que le codage base64.

En HTML, cela ressemble à ça :

<img src="data:image/png;base64,..." />

Voici un script bash qui permet d’encoder le tout automatiquement, grâce à openssl.

#!/bin/sh   if [ $# -eq 0 ]; then 	echo "Command: ${0} <image file>" 	exit 1 fi   path=$1 source=$(basename ${path}) extension=${source##*.} base=${source%.*} output="${base}.html" base64=$(openssl base64 -in ${path})   echo "<html><head></head><body><img src=\"data:image/${extension};base64,${base64}\" /></body></html>" > $output   exit 0

Le script fonctionne ainsi :

  • ./monscript.sh monfichierimage.png
  • génération automatique de monfichierimage.html
Share