Utilisation de Docker pour vos projets Ruby on Rails

Partagez cet article :
Partager sur facebook
Partager sur linkedin
Partager sur twitter
Partager sur email

Pour faciliter la collaboration entre les développeurs, il est pertinent de travailler dans des environnements identiques ou du moins le plus proche possible. Docker offre justement la possibilité à chacun, quelle que soit la configuration de son ordinateur, de travailler dans un environnement technique défini. Dans cet article, on vous explique comment utiliser Ruby on Rails et MySQL sous Docker.

Qu’est-ce que Docker ?

Docker est un outil technologique de conteneurisation permettant de travailler en équipe sur un même projet sans que des différences de versions de langages, de configurations logicielles ou matérielles n’aient d’incidences sur la dynamique de travail de l’équipe.

Pourquoi utiliser Docker pour ses projets ?

Par l’intermédiaire de la conteneurisation, Docker crée une image opérationnelle isolée et indépendante du système d’exploitation ou du poste de travail contenant tout le code source de votre application et ses dépendances. Il est donc ainsi possible de la partager au sein de votre équipe, d’avoir le même environnement de travail et d’éviter de vous lancer dans des installations pouvant être répétitives ainsi que des conflits liés au système (version, compatibilités…)

Concrètement, que vous ayez un PC ou un Mac, que vous soyez sous environnement Windows, GNU/Linux ou macOS, vous aurez tous accès à la même version de l’application.

Comment utiliser Docker ?

Pour voir comment utiliser Ruby on Rails et MySQL sous Docker, nous allons créer un projet de blog sous Rails 7. Nous utiliserons :

  • un Macbook Pro sous processeur Intel
  • un terminal
  • un éditeur de texte en l’occurrence VS code 
  • Docker et sa version Desktop

Étape 1 – Création du compte Docker

Après avoir créé votre compte, téléchargez l’application Docker Desktop et installez-la. Ouvrez ensuite votre terminal pour confirmer l’installation via ces deux commandes :

docker -v et docker-compose -v

➜ Desktop ~ docker -v
Docker version 20.10.14, build a224086
➜ Desktop ~ docker-compose -v
docker-compose version 1.29.2, build 5becea4c

Créez ensuite un répertoire sur votre poste à partir du terminal :

mkdir blog
cd blog

Ouvrez un éditeur code avec le projet en question (via la commande `code .` pour utiliser Visual Studio Code par exemple).

Étape 2 – Créer un fichier Gemfile

Créez un fichier Gemfile à la racine de votre projet via cette commande :

touch Gemfile

Il s’agit du fichier qui abrite toutes les gems nécessaires à l’installation de packages dont l’application aura besoin. Les gems sont spécifiques à Rails et sont des features déjà codées et susceptibles de vous faire considérablement gagner du temps en fonction de vos besoins. Commencez par y définir la source de vos gems :

source "https://rubygems.org"

Ajoutez ensuite la ligne ci-dessous :

git_source(:github) { |repo| "https://github.com/#{repo}.git" }

Pour information, cette ligne est directement ajoutée lorsque vous créez un projet depuis Rails 5. Il s’agit de prévenir des erreurs liées à la source des gems.

Ajoutez la version de Ruby que vous utiliserez :

ruby "3.0.0"

Puis ensuite les gems relatives à la version de Rails employée et le service de base de données :

gem "rails", "~> 7.0.2", ">= 7.0.2.2"
gem 'mysql2', '~> 0.5.4'

Voici l’intégralité du Gemfile :

source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.0.0"

# Bundle edge Rails instead: gem "rails", github: "rails/rails", branch: "main"
gem "rails", "~> 7.0.3"

# The original asset pipeline for Rails [https://github.com/rails/sprockets-rails]
gem "sprockets-rails"

# Use mysql as the database for Active Record
gem "mysql2", "~> 0.5"

Étape 3 – Créer un fichier Gemfile.lock

Toujours à la racine du projet, créez un fichier Gemfile.lock qui enregistrera toutes les versions des Gemfile :

touch Gemfile.lock

Veillez à ne rien ajouter dans ce fichier.

Étape 4 – Créer un fichier Dockerfile

Créez un fichier Dockerfile à la racine de votre projet via cette commande :

touch Dockerfile

Ici, il s’agit de définir la configuration ainsi que les commandes à exécuter pour le lancement de votre container (ou image) Docker.

La première instruction sert à définir le langage et sa version servant de base au container :

FROM: ruby:3.0.0

La deuxième instruction permet d’installer le client MySQL pour le container :

RUN apt-get update && apt-get install -y default-mysql-client vim

Il est nécessaire de mettre à jour avant d’installer dans la mesure où apt-get update garantit que toutes les sources et dépendances de packages sont dans leur dernière version. Il ne met pas à jour les packages existants qui ont été installés.

La troisième instruction permet de créer un répertoire, que vous pouvez nommer de manière arbitraire :

RUN mkdir /web

Ce répertoire contiendra le code exécuté dans le container.

La quatrième instruction permet de se rendre dans le répertoire pour y définir des instructions : 

WORKDIR /web

Ajoutez-y ensuite le Gemfile, le Gemfile.lock puis lancez le bundle install pour l’installation des gems :

ADD Gemfile /web/Gemfile 
ADD Gemfile.lock /web/Gemfile.lock 
RUN bundle install

Terminez en ajoutant ce dossier à la racine de l’app, ce qui transfert le code présent dans le projet en local sur la machine vers le container Docker :

ADD . /web

Voici l’intégralité du DockerFile :

FROM ruby:3.0.0

RUN  apt-get update && \
  apt-get install -y default-mysql-client vim

RUN mkdir /web

WORKDIR /web

ADD Gemfile /web/Gemfile

ADD Gemfile.lock /web/Gemfile.lock

RUN bundle install

ADD . /web

Séparer les commandes est une bonne pratique permettant d’éviter de ralentir le build. Toutes ces lignes d’instructions se lanceront lors de la commande :

docker-compose build

Étape 5 – créer un fichier docker-compose.yml

La cinquième étape consiste à créer le fichier docker-compose.yml toujours à la racine du projet :

touch docker-compose.yml

Il s’agit d’y définir simultanément les différents services nécessaires au fonctionnement de l’application (base de données, framework Rails…). Notez qu’il est indispensable de respecter la tenue d’une bonne indentation. Vous pourrez vérifier la validité de votre fichier en vous rendant sur un validateur de YAML et en y copiant l’intégralité de votre fichier.

Ce fichier contiendra les paramètres de configuration du ou des images.

Commencez par indiquer la base de données à utiliser sans oublier de rattacher les ports :

version: "3.7"
services:
    db:
        image: mysql:8.0.29
        command: --default-authentication-plugin=mysql_native_password
        container_name: "dt_mysql"
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: password
            MYSQL_DATABASE: web
            MYSQL_USER: user
            MYSQL_PASSWORD: password
        ports:
            - "3307:3306"
    web:
        build: .

Lancez Rails et attachez-le au port 3000 sur l’addresse locale 0.0.0.0 :

command: bundle exec rails s -p 3000 -b '0.0.0.0'

Les volumes permettent de charger localement et de les répartir dans les partitions de l’espace disque :

volumes:
  -”.:/web”

Configurez ensuite les ports en fonction de vos besoins :

ports: 
  - "3001:3000"

Faites ensuite les liens de dépendances entre l’app et sa base de données.

Si le container de la base de données ne démarre pas, l’application non plus.

depends_on:
  - db
links:
  - db

Enfin, configurez l’environnement :

environment:
            DB_USER: root
            DB_NAME: web
            DB_PASSWORD: password
            DB_HOST: db
            PROTOCOL: http
            HOSTNAME: localhost
            PORT: 3001
            EDITOR: vim

Voici comment le docker-compose.yml devrait s’afficher :

version: "3.7"
services:
    db:
        image: mysql:8.0.29
        command: --default-authentication-plugin=mysql_native_password
        container_name: "dt_mysql"
        restart: always
        environment:
            MYSQL_ROOT_PASSWORD: password
            MYSQL_DATABASE: web
            MYSQL_USER: user
            MYSQL_PASSWORD: password
        ports:
            - "3307:3306"
    web:
        build: .
        command: bundle exec rails s -p 3000 -b '0.0.0.0'
        volumes:
            - ".:/web"
        ports:
            - "3001:3000"
        depends_on:
            - db
        links:
            - db
        environment:
            DB_USER: root
            DB_NAME: web
            DB_PASSWORD: password
            DB_HOST: db
            PROTOCOL: http
            HOSTNAME: localhost
            PORT: 3001
            EDITOR: vim

Créons à présent l’application sous le framework Rails via la commande ci-dessous :

docker-compose run web rails new . --force --database=mysql

Votre container abrite à présent toute la structure de Rails. Vous devriez avoir un fichier nommé database.yml.

Étape 6 – Configurer le fichier database.yml

Il se situe dans le répertoire config de l’application et sert à définir les informations de connexion à la BDD. Voici ci-dessous le fichier tel que vous devriez le configurer pour utiliser MySQL2.

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  database: <%= ENV['DB_NAME'] %>
  username: <%= ENV['DB_USER'] %>
  password: <%= ENV['DB_PASSWORD'] %>
  host: <%= ENV['DB_HOST'] %>

development:
  <<: *default

test:
  <<: *default

La commande `docker-compose build` lancera l’installation de toutes les gems nécessaires à l’application et la commande docker-compose up lancera conjointement l’initialisation de la base de données MySQL ainsi que l’application sous Rails.

Le succès devrait se confirmer en se rendant au localhost 3001

Vous pouvez vous rendre sur le docker docs afin d’avoir une liste de toutes les commandes terminales possibles sous docker.

Voici quelques lignes de commandes :

  • docker-ps pour lister tous les containers ;
  • docker-stop suivi du numéro ID pour stopper un ou plusieurs containers ;
  • docker -rm suivi du numéro ID pour supprimer un ou plusieurs containers ;
  • docker- exec pour lancer une commande dans un container actif.

Vous l’aurez compris, utiliser Docker, chez l’annonceur comme en agence, permet d’uniformiser les environnements de travail de l’équipe de développeurs web en dépit de toutes les différences logicielles ou matérielles. Cet outil offre un gain de temps considérable tout en facilitant le développement et réduisant les risques de non reproductibilité des bugs. L’essayer, c’est l’adopter – en tout cas, chez (agence) BASH, c’est le cas !.

Si vous  souhaitez approfondir le sujet, vous pouvez consulter ces différentes ressources :

https://docs.docker.com/

https://lipanski.com/posts/dockerfile-ruby-best-practices

https://docs.docker.com/compose/compose-file/

Un projet ?

Vous souhaitez lancer votre site Internet ou développer votre présence en ligne ? Vous recherchez une agence partenaire pour vous apporter conseils et accompagnement pour optimiser votre référencement, construire des campagnes marketing ?

Dites-nous vos objectifs et nous vous proposerons une solution sur mesure pour votre projet.