⚠️ Traduction non officielle - Cette documentation est une traduction communautaire non officielle de Docker.

Conteneuriser une application Ruby on Rails

Prérequis

  • Vous avez installé la dernière version de Docker Desktop.
  • Vous disposez d'un client Git. Les exemples de cette section montrent la CLI Git, mais vous pouvez utiliser n'importe quel client.

Aperçu

Cette section vous guide dans la conteneurisation et l'exécution d'une application Ruby on Rails.

À partir de Rails 7.1, Docker est pris en charge nativement. Cela signifie que vous obtiendrez des fichiers Dockerfile, .dockerignore et bin/docker-entrypoint générés pour vous lorsque vous créez une nouvelle application Rails.

Si vous avez une application Rails existante, vous devrez créer les ressources Docker manuellement. Malheureusement, la commande docker init ne prend pas encore en charge Rails. Cela signifie que si vous travaillez avec Rails, vous devrez copier manuellement le Dockerfile et les autres configurations associées à partir des exemples ci-dessous.

1. Initialiser les ressources Docker

Rails 7.1 génère un Dockerfile multi-étapes nativement, voici un exemple d'un tel fichier généré à partir d'un modèle Rails.

Les Dockerfiles multi-étapes aident à créer des images plus petites et plus efficaces en séparant les dépendances de construction et d'exécution, garantissant que seuls les composants nécessaires sont inclus dans l'image finale. En savoir plus dans le guide des constructions multi-étapes.

Bien que le Dockerfile soit généré automatiquement, il est important de comprendre son but et sa fonctionnalité. Il est fortement recommandé d'examiner l'exemple suivant.

Dockerfile
# syntax=docker/dockerfile:1
# check=error=true

# Ce Dockerfile est conçu pour la production, pas pour le développement.
# docker build -t app .
# docker run -d -p 80:80 -e RAILS_MASTER_KEY=<valeur_de_config/master.key> --name app app

# Pour un environnement de développement conteneurisé, voir Dev Containers : https://guides.rubyonrails.org/getting_started_with_devcontainer.html

# Assurez-vous que RUBY_VERSION correspond à la version de Ruby dans .ruby-version
ARG RUBY_VERSION=3.3.6
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base

# L'application Rails réside ici
WORKDIR /rails

# Installer les paquets de base
# Remplacez libpq-dev par sqlite3 si vous utilisez SQLite, ou libmysqlclient-dev si vous utilisez MySQL
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y curl libjemalloc2 libvips libpq-dev && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Définir l'environnement de production
ENV RAILS_ENV="production" \
    BUNDLE_DEPLOYMENT="1" \
    BUNDLE_PATH="/usr/local/bundle" \
    BUNDLE_WITHOUT="development"

# Étape de construction jetable pour réduire la taille de l'image finale
FROM base AS build

# Installer les paquets nécessaires pour construire les gemmes
RUN apt-get update -qq && \
    apt-get install --no-install-recommends -y build-essential curl git pkg-config libyaml-dev && \
    rm -rf /var/lib/apt/lists /var/cache/apt/archives

# Installer les dépendances JavaScript et Node.js pour la compilation des assets
#
# Décommentez les lignes suivantes si vous utilisez NodeJS et avez besoin de compiler les assets
#
# ARG NODE_VERSION=18.12.0
# ARG YARN_VERSION=1.22.19
# ENV PATH=/usr/local/node/bin:$PATH
# RUN curl -sL https://github.com/nodenv/node-build/archive/master.tar.gz | tar xz -C /tmp/ && \
#     /tmp/node-build-master/bin/node-build "${NODE_VERSION}" /usr/local/node && \
#     npm install -g yarn@$YARN_VERSION && \
#     npm install -g mjml && \
#     rm -rf /tmp/node-build-master

# Installer les gemmes de l'application
COPY Gemfile Gemfile.lock ./
RUN bundle install && \
    rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \
    bundle exec bootsnap precompile --gemfile

# Installer les modules node
#
# Décommentez les lignes suivantes si vous utilisez NodeJS et avez besoin de compiler les assets
#
# COPY package.json yarn.lock ./
# RUN --mount=type=cache,id=yarn,target=/rails/.cache/yarn YARN_CACHE_FOLDER=/rails/.cache/yarn \
#     yarn install --frozen-lockfile

# Copier le code de l'application
COPY . .

# Précompiler le code bootsnap pour des temps de démarrage plus rapides
RUN bundle exec bootsnap precompile app/ lib/

# Précompiler les assets pour la production sans nécessiter la clé secrète RAILS_MASTER_KEY
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile

# Étape finale pour l'image de l'application
FROM base

# Copier les artefacts construits : gemmes, application
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}"
COPY --from=build /rails /rails

# Exécuter et posséder uniquement les fichiers d'exécution en tant qu'utilisateur non root pour la sécurité
RUN groupadd --system --gid 1000 rails && \
    useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \
    chown -R rails:rails db log storage tmp
USER 1000:1000

# Le point d'entrée prépare la base de données.
ENTRYPOINT ["/rails/bin/docker-entrypoint"]

# Démarrer le serveur via Thruster par défaut, cela peut être surchargé à l'exécution
EXPOSE 80
CMD ["./bin/thrust", "./bin/rails", "server"]

Le Dockerfile ci-dessus suppose que vous utilisez Thruster avec Puma comme serveur d'application. Si vous utilisez un autre serveur, vous pouvez remplacer les trois dernières lignes par ce qui suit :

# Démarrer le serveur d'application
EXPOSE 3000
CMD ["./bin/rails", "server"]

Ce Dockerfile utilise un script à ./bin/docker-entrypoint comme point d'entrée du conteneur. Ce script prépare la base de données et exécute le serveur d'application. Voici un exemple d'un tel script.

docker-entrypoint
#!/bin/bash -e

# Activer jemalloc pour une utilisation réduite de la mémoire et une latence moindre.
if [ -z "${LD_PRELOAD+x}" ]; then
    LD_PRELOAD=$(find /usr/lib -name libjemalloc.so.2 -print -quit)
    export LD_PRELOAD
fi

# Si le serveur rails est en cours d'exécution, créer ou migrer la base de données existante
if [ "${@: -2:1}" == "./bin/rails" ] && [ "${@: -1:1}" == "server" ]; then
  ./bin/rails db:prepare
fi

exec "${@}"

En plus des deux fichiers ci-dessus, vous aurez également besoin d'un fichier .dockerignore. Ce fichier est utilisé pour exclure des fichiers et des répertoires du contexte de la construction. Voici un exemple d'un fichier .dockerignore.

.dockerignore
# Voir https://docs.docker.com/engine/reference/builder/#dockerignore-file pour en savoir plus sur l'ignorance des fichiers.

# Ignorer le répertoire git.
/.git/
/.gitignore

# Ignorer la configuration de bundler.
/.bundle

# Ignorer tous les fichiers d'environnement.
/.env*

# Ignorer tous les fichiers de clés par défaut.
/config/master.key
/config/credentials/*.key

# Ignorer tous les fichiers journaux et temporaires.
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep

# Ignorer les fichiers pid, mais conserver le répertoire.
/tmp/pids/*
!/tmp/pids/.keep

# Ignorer le stockage (fichiers téléversés en développement et toutes les bases de données SQLite).
/storage/*
!/storage/.keep
/tmp/storage/*
!/tmp/storage/.keep

# Ignorer les assets.
/node_modules/
/app/assets/builds/*
!/app/assets/builds/.keep
/public/assets

# Ignorer les fichiers de service CI.
/.github

# Ignorer les fichiers de développement
/.devcontainer

# Ignorer les fichiers liés à Docker
/.dockerignore
/Dockerfile*

Le dernier fichier optionnel que vous pourriez vouloir est le fichier compose.yaml, qui est utilisé par Docker Compose pour définir les services qui composent l'application. Comme SQLite est utilisé comme base de données, il n'est pas nécessaire de définir un service distinct pour la base de données. Le seul service requis est l'application Rails elle-même.

compose.yaml
services:
  web:
    build: .
    environment:
      - RAILS_MASTER_KEY
    ports:
      - "3000:80"

Vous devriez maintenant avoir les fichiers suivants dans votre dossier d'application :

  • .dockerignore
  • compose.yaml
  • Dockerfile
  • bin/docker-entrypoint

Pour en savoir plus sur les fichiers, consultez ce qui suit :

2. Exécuter l'application

Pour exécuter l'application, exécutez la commande suivante dans un terminal à l'intérieur du répertoire de l'application.

$ RAILS_MASTER_KEY=<valeur_de_la_clé_maîtresse> docker compose up --build

Ouvrez un navigateur et affichez l'application à http://localhost:3000. Vous devriez voir une simple application Ruby on Rails.

Dans le terminal, appuyez sur ctrl+c pour arrêter l'application.

3. Exécuter l'application en arrière-plan

Vous pouvez exécuter l'application détachée du terminal en ajoutant l'option -d. À l'intérieur du répertoire docker-ruby-on-rails, exécutez la commande suivante

$ docker compose up --build -d

Ouvrez un navigateur et affichez l'application à http://localhost:3000.

Vous devriez voir une simple application Ruby on Rails.

Dans le terminal, exécutez la commande suivante pour arrêter l'application.

$ docker compose down

Pour plus d'informations sur les commandes Compose, consultez la référence CLI Compose.

Résumé

Dans cette section, vous avez appris comment vous pouvez conteneuriser et exécuter votre application Ruby à l'aide de Docker.

Informations connexes :

Étapes suivantes

Dans la section suivante, vous allez découvrir comment configurer un pipeline CI/CD à l'aide de GitHub Actions.