En 2014, j'ai créé mon blog technique avec Octopress. J'en suis très satisfait mais je désire le mettre au goût du jour et octopress n'a pas évolué depuis 2015. J'ai regardé dans les sites statiques en Ruby ce qui était encore d'actualité et Jekyll continue sur sa lancé et propose même de nombreuses améliorations.

L'objet de cet article est de permettre à tout le monde mettre en place son site statique rapidement et pour pas cher. Le titre Mon site statique pour 6€ par an peut interloquer, mais c'est vrais ! Vous allez voir que pour 6€ (le prix d'un nom de domaine), vous allez avoir un site internet qui en jette :p

Prérequis

Tout d'abord, il faut avoir Ruby sur votre machine. Installez rvm, on installera Ruby dans la partie suivante.

Installez aussi heroku-cli.

Ensuite, ouvrez un compte chez Heroku, et chez Gitlab.

Pour ceux qui préfèrent rester sur Github, mon article ne couvrira pas leur CI avec cet horrible Jenkins. Je ne suis pas un intégriste, c'est juste un choix au même titre que je n'utilise pas Google mais Qwant ni Chrome mais Firefox.

Installation

C'est parti pour le fun.

rvm install 2.3
rvm use 2.3
gem install bundle jekyll

La commande jekyll -v doit vous dire que vous êtes en version 3 ou plus.

Création du blog

C'est assez simple, on tape la commande jekyll new mon-site. Voilà c'est fini !

On se déplace dans notre nouveau répertoire cd mon-site et on va commencer par fixer la version de ruby en ajoutant ruby '2.3.0' dans le Gemfile.

# Gemfile
source "https://rubygems.org"
ruby '2.3.0'

Plugin admin

On va ajouter un plugin d'administration qui fourni une interface permettant de créer de nouveaux articles sans se soucier du format et du nom du fichier. Attention, ceci retire le live reload !

Dans le Gemfile, j'ajoute gem "jekyll-admin" dans le groupe jekyll_plugins.

group :jekyll_plugins do
   gem "jekyll-feed", "~> 0.6"
   gem "jekyll-admin"
end

Et dans le _config.yml, j'ajoute jekyll-admin dans la liste des plugins.

plugins:
  - jekyll-feed
  - jekyll-admin

J'installe tout ça et je lance mon serveur pour voir.

bundle install
bundle exec jekyll serve

Si vous êtes sur Cloud9, utilisez plutôt la commande bundle exec jekyll serve --host $IP --port $PORT --baseurl ''.

Le site s'affiche avec les informations (titre, description) qu'il y avait dans le fichier _config.yml; je rajoute /admin à mon url (http://localhost:4000/admin) et je tombe sur ma console d'administration, c'est parfait !

Ajouter un thème

Ok, c'est sympathique tout ça, je peux faire plein de choses ; mais mon site a une interface qui date au moins du moyen age !

Heureusement, nous avons des thèmes à disposition sur jekyllthemes !

Sous Jekyll, il n'y a pas de séparation du site et du theme, c'est ce qu'Octopress proposait. Mais si l'on regarde bien le gemfile, on s’aperçoit qu'il y a une ligne gem "minima", "~> 2.0" qui est ensuite reprise dans le fichier _config.yml : theme: minima.

Le thème peut donc simplement être géré par la gem tel qu'expliqué sur le site de Jekyll.

J'ai choisi pour thème Forty, sur leur page de présentation, il y a un lien vers le repo github forty_jekyll_theme, je vais donc sous rubygems rechercher si une gem de ce nom existe. Et il y en a une; je n'ai plus qu'à remplacer minima

# Gemfile

gem 'forty_jekyll_theme', '~> 1.3'
# _config.yml

theme: forty_jekyll_theme

Je relance mon serveur pour voir comment la page par défaut a changé.

bundle install
bundle exec jekyll serve

Livraison en production

Bon, on a bien avancé sans faire grand chose, il est temps de travailler maintenant.

Intégration continue

Pour livrer mon site en production sous Heroku, je vais créer un fichier .gitlab-ci.yml et configurer divers étapes après avoir chargé l'image ruby 2.3.0 de Docker.

image: "ruby:2.3.0"

# Cache gems in between builds
cache:
  paths:
    - vendor/ruby

before_script:
  - apt-get update >/dev/null
  - apt-get install -y locales >/dev/null
  - echo "en_US UTF-8" > /etc/locale.gen
  - locale-gen en_US.UTF-8
  - export LANG=en_US.UTF-8
  - export LANGUAGE=en_US:en
  - export LC_ALL=en_US.UTF-8

test:
  script:
  - ruby -v                                          # Print out ruby version for debugging
  - apt-get update -q && apt-get install nodejs -yqq # rails app needs a JS runtime
  - gem install bundler  --no-ri --no-rdoc           # Bundler is not installed with the image
  - bundle install -j $(nproc) --path vendor         # Install dependencies into ./vendor/ruby
  - bundle exec rake -P RAILS_ENV=production         # Contrôle si Heroku va pouvoir pré-compiler l'application
  - bundle exec jekyll build

production:
  type: deploy
  environment: production
  script:
  - gem install dpl
  - dpl --provider=heroku --app=$HEROKU_PRODUCTION_APP_NAME --api-key=$HEROKU_PRODUCTION_API_KEY
  - "curl -n -X POST https://api.heroku.com/apps/$HEROKU_PRODUCTION_APP_NAME/ps -H \"Accept: application/json\" -H \"Authorization: Bearer ${HEROKU_PRODUCTION_API_KEY}\""
  only:
  - master

La partie before_script permet principalement de mettre l'image à jour et d'installer l'UTF-8 car le runner ne l'a pas forcement (cf. cette issue).

La partie test permet de vérifier que le build se passe bien.

Et finalement, on livre en utilisant les variables d'environnement suivantes qui nous permet d'avoir un CI totalement sécurisé et DRY !

  • $HEROKU_PRODUCTION_APP_NAME
  • $HEROKU_PRODUCTION_API_KEY

La configuration d'heroku

Sous Heroku, je vais créer mon projet via leur cli.

J'initialise un repo git avant (vous allez voir pourquoi).

git init

Je m'identifie et je crée un projet.

heroku login
heroku create mon-site --region eu
Creating ⬢ mon-site... done, region is eu

Maintenant, si je fait un git remote -v, je m’aperçois que Heroku est configuré, c'est pour ça que c'était intéressant d'initialiser git avant, même sans faire de commit.

git remote -v
heroku  https://git.heroku.com/monn-site.git (fetch)
heroku  https://git.heroku.com/monn-site.git (push)

Reste à ajouter le fichier qu'Heroku attend pour lancer l'application, j'ai nommé Procfile.

# Procfile
web: rackup

Il faut créer un fichier Rakefile qui va être utilisé par Heroku pour générer le site. Heroku va automatiquement lancer la tâche assets:precompile, donc j'en profite.

# Rakefile
namespace :assets do
  task :precompile do
    sh 'bundle exec jekyll build'
  end
end

Pour faire tourner un site statique sur Heroku, il faut le faire fonctionner comme une application Rack; je dois donc créer un fichier config.ru.

# config.ru
require "rack/contrib/try_static"

use Rack::TryStatic, {
  root: "_site",
  urls: %w[/],
  try:  %w[
    .html index.html /index.html
    .js .css .xml .json
    .eot .svg .ttf .woff .woff2
  ],
  :header_rules => [
    # Cache all static files in public caches (e.g. Rack::Cache)
    #  as well as in the browser
    [%w[json], {'Content-Type' => 'application/json'}]
  ]
}

La section Rack::Trystatic va tenter de livrer les fichiers statiques générés à Heroku. Si le processus ne fonctionne pas, il lancera une erreur 404. Pour ceci, il faut avoir ajouté gem 'rack-contrib' au Gemfile.

# Gemfile
source "https://rubygems.org"
ruby '2.3.0'

gem 'jekyll', '3.5.1'
gem 'forty_jekyll_theme', '~> 1.3'

# If you have any plugins, put them here!
group :jekyll_plugins do
   gem 'redcarpet', '~> 3.4'
   gem 'pygments.rb', '~> 1.1', '>= 1.1.2'
   gem 'jekyll-feed', '~> 0.6'
   gem 'jekyll-admin'
end

# Lancer jekyll sur heroku
gem 'rake', '~> 12.0'
gem 'rack-contrib'

# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]

La configuration des variables d'environnement

Je passe maintenant à mon repo gitlab, je crée un projet, je récupère son adresse git (git@gitlab.com:al1_andre/mon-site.git) par exemple et je l'ajoute à ma liste de remote.

git remote add origin git@gitlab.com:al1_andre/mon-site.git

Ensuite, je vais récupérer la clé Heroku dont j'ai besoin pour configurer mon gitlab dans la partie API Key de mon compte.

Sous gitlab, dans la partie settings, puis pipeline, je descend jusqu’à la partie Add a variable et j'en crée deux :

  • HEROKU_PRODUCTION_APP_NAME avec le nom de mon projet (ici mon-site)
  • HEROKU_PRODUCTION_API_KEY avec la clé Heroku

Livraison

Tout est en place, je n'ai plus qu'à écrire mon premier article, dès que je vais faire un push, Gitlab-CI va lancer les tests et livrer mon site.

Sur Heroku, dans la partie settings de mon projet, je n'ai qu'à remplir la zone Domains and certificates et faire pointer mon DNS.

Ajout de plugins interessants

Personnelement, j'ajoute les plugins sitemap, piwik et disqus.

Sitemap

Comme le dit Google, Un sitemap est un fichier où vous pouvez répertorier les pages Web de votre site pour fournir à leurs services et aux autres moteurs de recherche des informations sur la structure du contenu de votre site. Les robots d'exploration des moteurs de recherche comme Googlebot lisent ce fichier pour explorer plus intelligemment votre site.

Vous l'avez compris, c'est assez important d'en avoir un. Heureusement pour nous, le plugin jekyll-sitemap est à disposition.

Pour que ça fonctionne, il suffit d'ajouter la gem au Gemfile

# Gemfile 
group :jekyll_plugins do
  gem 'jekyll-sitemap'
end

Puis aux plugins de la configuration.

plugins:
  - jekyll-sitemap

Maintenant, lors de la génération du site bundle exec jekyll build, il doit y avoir un fichier sitempa.xml dans le repertoire _site

Piwik

Piwik est un logiciel libre et open source de mesure de statistiques web, successeur de PhpMyVisites et conçu pour être une alternative libre à Google Analytics. (wikipedia)

Je l'utilise depuis 2012, l'année où j'ai décidé de dire au revoir à Google et j'en suis plus que satisfait. C'est un outil complet, libre et performant.

Il suffit de constituer un fichier _includes/piwik.html avec le code suivant.

{% if site.piwik.tracking_id %}

<script type="text/javascript">
  var _paq = _paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u=(("https:" == document.location.protocol) ? "https" : "http") + "://{{ site.piwik.base_url }}/";
    _paq.push(['setTrackerUrl', u+'piwik.php']);
    _paq.push(['setSiteId', {{site.piwik.tracking_id}}]);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
<noscript><p><img src="//{{ site.piwik.base_url }}/piwik.php?idsite={{site.piwik.tracking_id}}" style="border:0;" alt="" /></p></noscript>

{% endif %}

Rajouter dans le fichier de configuration les informations suivantes :

  • tracking_id : Le numéro de tracking du site
  • url : l'adresse du serveur piwik
#_config.yml

# Piwik Analytics
piwik:
  tracking_id: 1
  tracking_id: alain-andre.fr/piwik

Il ne reste plus qu'à ajouter dans le footer la ligne d'inclusion.

{% include piwik.html %}

Disqus

Disqus est un service Web de discussion et de commentaires d'articles centralisé avec authentification unique. Il permet à des sites Internet de se décharger de la gestion des commentaires d'articles. (wikipedia)

La gem jekyll-disqus permet d'ajouter simplement ce plugin.

Il suffit d'ajouter la gem au Gemfile

# Gemfile 
group :jekyll_plugins do
  gem "jekyll-disqus"
end

Et la configuration suivante dans le fichier _config.yml

plugins:
  - jekyll-disqus

disqus:
  username: alain

Il ne reste plus qu'à ajouter la ligne {% disqus %} dans l'un des layouts (celui des articles en général).

Catégories

Il est possible d'ajouter une gem géant les catégories pour nous -c'est à dire qu'elle va créer une liste d'articles par catégorie existante- . Un blog sans possibilité de recherche ou de trie d'article est quelque peux impraticable ; on est loin du user friendly !

Vous pouvez rechercher sur rubygems en tapant jekyll categories qui va vous lister plein de gem permettant de gérer les catégories. Je vous conseille jekyll-category_generator car elle est simple d'utilisation, ressente et propose des helpers indispensables... et puis en plus c'est une de mes gems :p

Pour l'installation et l'utilisation, suivez les documentations.

Publié dans les catégories suivantes

ruby
comments powered by Disqus

Téléphone

+33 637 700 504

Adresse

Bordeaux, 33300
France