[RUBY] Procédure de construction de l'environnement Docker "Rails 6 x MySQL 8" à partager avec les équipes

Cette fois, je vais vous présenter la procédure pour créer un environnement Docker pour une application Web qui combine Rails 6 et MySQL 8.

À partir de Rails 6, webpacker est installé en standard, et à partir de MySQL 8, la méthode d'authentification de l'utilisateur a changé, il y avait donc diverses parties qui étaient bloquées dans la construction de l'environnement, donc j'espère que cela sera utile.

Afin de permettre un développement fluide par plusieurs personnes, l'objectif est de créer un environnement où ** si vous clonez à partir d'un référentiel distant, l'application démarrera simplement par docker-compose up **.

Les différentes versions sont les suivantes.

L'environnement d'exécution utilise Docker Desktop pour Mac (version 2.3.0.4).

Préparation de l'application des rails

Créez / déplacez un répertoire. Le nom de l'application Rails créée cette fois est «sample_app».

$ mkdir sample_app && cd $_

Créez un Gemfile dans votre environnement local en utilisant l'image ruby. -v est une option pour le montage de liaison (synchronisation des répertoires hôte et conteneur).

En synchronisant le répertoire courant de l'hôte avec le répertoire de travail du conteneur, les fichiers créés sur le conteneur sont placés sur l'hôte.

$ docker run --rm -v `pwd`:/sample_app -w /sample_app ruby:2.7.1 bundle init

Décommentez la partie gem" rails " du Gemfile créé et spécifiez la version des rails.

Gemfile


# frozen_string_literal: true

source "https://rubygems.org"

git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
- # gem "rails"
+ gem "rails", '~> 6.0.3.2'

Créez un Dockerfile pour créer un environnement Docker qui exécute rails new.

Rails 6 exécute également rails webpacker: install lorsque vous créez une application, alors n'oubliez pas d'installer ** yarn. ** ** Cette fois, utilisez npm pour installer yarn.

Dockerfile


FROM ruby:2.7.1

RUN apt-get update -qq && \
    apt-get install -y nodejs \
                       npm && \
    npm install -g yarn

#Directeur de travail/sample_Spécifié dans l'application
WORKDIR /sample_app

#Copier Gemfile local sur Dokcer
COPY Gemfile /sample_app/Gemfile

# /sample_installation du bundle sur le répertoire de l'application
RUN bundle install

Démarrez le conteneur en utilisant l'image créée en construisant le Dockerfile, et faites rails new sur le conteneur.

$ docker build -t sample_app .

$ docker run --rm -v `pwd`:/sample_app sample_app rails new . –skip-bundle --database=mysql

Créez docker-compose.yml.

Cette fois, par souci de brièveté, je me connecte à MySQL en tant qu'utilisateur root. Lors de la connexion en tant qu'utilisateur général, il est nécessaire de définir les variables d'environnement suivantes pour l'image MySQL.

Variable d'environnement Contenu
MYSQL_USER Nom d'utilisateur
MYSQL_PASSWORD Mot de passe de l'utilisateur

--Référence: [Docker] Un environnement pour se connecter à plusieurs bases de données MySQL en tant qu'utilisateur général, compris par Rails Procédure de construction

Les informations de la base de données sont conservées en créant un volume nommé mysql_data.

docker-compose.yml



version: '3'
services:
  web: #Conteneur lancé par Ruby on Rails
    build: .
    ports:
      - '3000:3000' #Rendez-le accessible sur le port 3000 de localhost
    volumes:
      - .:/sample_app #Synchronisation des fichiers d'application
    depends_on:
      - db
    command: ["rails", "server", "-b", "0.0.0.0"]
  db: #Conteneur que MySQL démarre
    image: mysql:8.0.21
    volumes:
      - mysql_data:/var/lib/mysql #Persistance des données
    command: --default-authentication-plugin=mysql_native_password #Définissez la méthode d'authentification sur 8 séries ou une version antérieure.
    environment:
      MYSQL_ROOT_PASSWORD: 'pass'
      MYSQL_DATABASE: 'sample_app_development'
volumes:
  mysql_data: #Enregistrement du volume de données

--Référence: Persistez les données Docker! Introduction à la construction de l'environnement à partir de la compréhension du volume de données

Je vais donner une explication supplémentaire du docker-compose.yml ci-dessus.

L'image MySQL Docker crée une base de données avec le nom défini sur MYSQL_DATABASE. Puisque l'environnement de développement de Ruby on Rails utilise la base de données «[nom de l'application] _development», «sample_app_development» est enregistré dans «MYSQL_DATABASE». Vous pouvez maintenant préparer la base de données pour l'environnement de développement sans exécuter rails db: create.

À partir de MySQL 8, la méthode d'authentification est passée de mysql_native_password à caching_sha2_password. Avec la méthode d'authentification standard MySQL 8 caching_sha2_password, il n'est pas possible de se connecter à la base de données, et le message d'erreur suivant s'affiche au démarrage de l'application Rails.


Mysql2::Error::ConnectionError

Plugin caching_sha2_password could not be loaded: /usr/lib/x86_64-linux-gnu/mariadb19/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory

スクリーンショット 2020-09-15 9.15.45.png

Par conséquent, --default-authentication-plugin = mysql_native_password utilise la méthode d'authentification précédente de mysql_native_password.

Ensuite, configurez la connexion à la base de données pour Ruby on Rails.

config/database.yml



default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: pass # (Cette fois c'est la racine)MYSQL_ROOT_Match avec PASSWORD
  host: db #Définir le nom du conteneur de base de données

Confirmation du lancement de l'application Rails

Maintenant que nous avons un environnement Docker qui combine Ruby on Rails 6 et MySQL 8, commençons-le.


$ docker-compose up

C'est OK si vous accédez à localhost: 3000 et l'écran suivant s'affiche.

スクリーンショット 2020-09-15 9.23.43.png

Vérifions également la persistance des données dans la base de données. Par exemple, créez une fonction liée à «événement» avec «échafaudage».


$ docker-compose exec web rails g scaffold event title:string
$ docker-compose exec web rails db:migrate

Accédez à localhost: 3000 / events / new et enregistrez un enregistrement appelé" sample event "comme exemple.

C'est OK si les données restent même si le conteneur est supprimé et démarré.

$ docker-compose down
$ docker-compose up

$ docker-compose exec web rails c
> Event.last.title
=> "Exemple d'événement"

Création d'une base de données pour l'environnement de test

En créant une base de données dans l'environnement de développement à l'aide de «MYSQL_DATABASE», l'application Rails peut être démarrée sans exécuter «db: create».

Cependant, ** cela seul ne suffit pas comme environnement de développement ** car la base de données ([nom de l'application] _test) de l'environnement de test utilisé dans le code de test n'a pas été créée.

Dans l'image MySQL Docker, si vous placez le script (.sql, .sh, .sql.gz) dans / docker-entrypoint-initdb.d, il sera exécuté au démarrage du conteneur. il y a. [^ docker-entrypoint-initdb] Tirez parti de cette fonctionnalité pour créer une base de données pour l'environnement de test.

** Les scripts sont exécutés dans l'ordre alphabétique **, donc s'il y a des dépendances entre les scripts, soyez également conscient du nom du fichier.

$ mkdir docker-entrypoint-initdb.d && cd $_
$ vim 00_create.sql

00_create.sql


--Créer une base de données pour l'environnement de test
CREATE DATABASE sample_app_test;

De plus, le droit d'accès à la base de données des utilisateurs généraux est uniquement la base de données définie sur MYSQL_DATABASE. Par conséquent, ** Lors de la connexion à une base de données en tant qu'utilisateur général, il est nécessaire non seulement de créer la base de données, mais également d'accorder les droits d'accès suivants. ** **

01_grant.sql


--Lors de l'utilisation d'un utilisateur général nommé webapp
GRANT ALL ON `sample_app_test`.* TO webapp@'%';

--Référence: [Docker] Un environnement pour se connecter à plusieurs bases de données MySQL en tant qu'utilisateur général, compris par Rails Procédure de construction

Ajoutez un montage de liaison afin que le script créé puisse être lu sur le conteneur.

docker-compose.yml


version: '3'
services:
  web:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - .:/sample_app
    depends_on:
      - db
    command: ["rails", "server", "-b", "0.0.0.0"]
  db:
    image: mysql:8.0.21
    volumes:
      - mysql_data:/var/lib/mysql
+     - ./docker-entrypoint-initdb.d:/docker-entrypoint-initdb.d
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: 'pass'
      MYSQL_DATABASE: 'sample_app_development'
volumes:
  mysql_data:

Confirmez que la base de données est créée automatiquement

Supprimez et démarrez le conteneur db et vérifiez si la base de données est créée automatiquement. Ce n'est pas grave si les bases de données «[nom de l'application] _development» et «[nom de l'application] _test» existent.

#Créer une base de données à partir de zéro en supprimant également les informations de persistance de la base de données
$ docker-compose down --volumes

$ docker-compose up

$ docker-compose exec db mysql -uroot -ppass -D sample_app_development

mysql> show databases;
+------------------------+
| Database               |
+------------------------+
| information_schema     |
| mysql                  |
| performance_schema     |
| sample_app_development |
| sample_app_test        |← La base de données pour le test a été créée
| sys                    |
+------------------------+
6 rows in set (0.00 sec)

Vous pouvez également vous connecter avec succès depuis une application Rails.

$ docker-compose exec web rails c

> ENV['RAILS_ENV']
=> "development

$ docker-compose exec web rails c -e test

> ENV['RAILS_ENV']
=> "test"

Faites démarrer l'environnement simplement par "clone → docker-compose up"

Les modèles suivants sont souvent considérés comme un moyen de créer un environnement de développement Rails avec Docker.

#Lancer le conteneur
$ docker-compose up

#Créer une base de données
$ docker-compose exec web rails db:create

#Migration de table
$ docker-compose exec web rails db:migrate

L'application Rails et la base de données sont liées par docker-compose, et la base de données utilisée par l'application est construite sur le conteneur.

Il n'y a pas de problème avec la méthode ci-dessus, mais dans ce cas ** Il faut du temps pour créer manuellement la base de données et la table sur le conteneur au premier démarrage. ** **

Considérant le cas du partage d'un environnement Docker avec plusieurs personnes, il est idéal que l'environnement puisse être démarré en faisant simplement docker-compose up après le clonage du fichier d'application à partir du référentiel distant.

Si possible, je voudrais éviter la situation où je dois prendre la peine de dire aux membres partagés "Créer la base de données sur le conteneur au premier démarrage".

À partir de là, si vous clonez à partir d'un référentiel distant, faites simplement docker-compose up pour configurer les paramètres afin que l'application Rails puisse être démarrée.

Exécutez l'installation de fil au démarrage du conteneur

Dans l'environnement de développement, la synchronisation du code source à l'aide de bind mout (synchronisation des répertoires hôte et conteneur) est souvent utilisée.

Le fichier d'application cloné à partir du référentiel distant a un répertoire package.json, mais pas de répertoire node_modules. Par conséquent, si vous faites docker-compose up après le clonage, le répertoire sans node_modules sera monté en liaison. En conséquence, une erreur vous invitant à exécuter yarn install se produit et l'application ne peut pas être démarrée.


========================================
  Your Yarn packages are out of date!
  Please run `yarn install --check-files` to update.
========================================

To disable this check, please change `check_yarn_integrity`
to `false` in your webpacker config file (config/webpacker.yml).

yarn check v1.22.5
info Visit https://yarnpkg.com/en/docs/cli/check for documentation about this command.

Pour éviter cela, vous devez exécuter yarn install au démarrage du conteneur. Par exemple, vous pouvez exécuter yarn install lors du démarrage du conteneur en procédant comme suit.

docker-compose.yml


version: '3'
services:
  web:
    build: .
+   command: ["./start.sh"]
-   command: ["rails", "server", "-b", "0.0.0.0"]
    ports:
      - '3000:3000'
    volumes:
      - .:/sample_app
    depends_on:
      - db
  db:
    image: mysql:8.0.21
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: 'pass'
      MYSQL_DATABASE: 'sample_app_development'

start.sh


#!/bin/bash -eu
yarn
rails server -b '0.0.0.0'

Modifiez les autorisations du shell.

$ chmod 755 start.sh

Le shell est appelé par la commande lors du démarrage du conteneur, et "yarn install" est exécuté dans le shell. Après avoir exécuté yarn install, l'application Rails démarrera sur rails server, donc l'erreur précédente sera résolue.

Autoriser la migration à s'exécuter automatiquement

Comme pour yarn install, la migration de la table doit être exécutée par le script shell qui est appelé au démarrage du conteneur.

start.sh


#!/bin/bash -eu
yarn
+ rails db:migrate
rails server -b '0.0.0.0'

Cependant, bien que vous puissiez contrôler l'ordre de démarrage des conteneurs en utilisant depend_on de docker-compose.yml, vous ne pouvez pas attendre le début du conteneur [^ startup-order], alors préparez-vous à démarrer le conteneur db. Si db: migrate est exécuté avant la fin de, la migration échouera.

[^ startup-order]: Docker Doc "Contrôle de l'ordre de démarrage dans Compose"

Pour automatiser la migration, vous devez attendre que le conteneur db démarre avant que db: migrate ne soit exécuté.

Il existe plusieurs façons d'attendre que la base de données soit prête, mais cette fois wait-for-it Voici comment utiliser>.

Si vous placez wait-for-it.sh dans le répertoire courant et créez docker-compose.yml comme suit, le script sera exécuté après avoir attendu le démarrage de la base de données.

docker-compose.yml


version: '3'
services:
  web:
    build: .
-   command: [""./start.sh"]
+   command: ["./wait-for-it.sh", "db:3306", "--", "./start.sh"]
    ports:
      - '3000:3000'
    volumes:
      - .:/sample_app
    depends_on:
      - db
  db:
    image: mysql:8.0.21
    command: --default-authentication-plugin=mysql_native_password
    environment:
      MYSQL_ROOT_PASSWORD: 'pass'
      MYSQL_DATABASE: 'sample_app_development'

Résumé

Ceci conclut l'introduction de la procédure de création d'un environnement Docker pour Rails 6 + MySQL 8.

En exécutant le shell au démarrage du conteneur, l'environnement de développement peut être construit en douceur même lorsque plusieurs personnes utilisent l'environnement Docker. Cette fois, en appelant le shell au démarrage du conteneur, yarn install et db: migration sont sûrement exécutés, mais le contrôle de la commande lorsque le conteneur démarre est <a href =" https: // ". Vous pouvez également le faire avec un outil appelé github.com/progrium/entrykit "target =" _ blank "> Entrykit .

À propos de Entrykit Comment installer Entrykit dans l'environnement Rails Docker et exécuter automatiquement l'installation du bundle </ strong> Il est introduit dans un>, alors jetez un œil si vous êtes intéressé.

  • Résumé de cette époque
  • À partir de Rails 6, vous devez installer le fil à l'avance.
  • Si une erreur d'authentification MySQL 8 se produit, résolvez-la en revenant à l'authentification standard.
  • En exécutant le shell au démarrage du conteneur, il est possible d'automatiser la création de table, etc.

à la fin

Je travaille sur Twitter ( @ nishina555 ). J'espère que vous me suivrez!

Article de référence

Recommended Posts

Procédure de construction de l'environnement Docker "Rails 6 x MySQL 8" à partager avec les équipes
[Construction de l'environnement avec Docker] Rails 6 et MySQL 8
Procédure de création d'un environnement de développement d'applications Rails avec Docker [Rails, MySQL, Docker]
[Docker] Construction de l'environnement Rails 5.2 avec docker
Environnement Build Rails (API) x MySQL x Nuxt.js avec Docker
Construction d'environnement avec Docker pour les débutants
Rails sur la procédure de construction de l'environnement Docker
Créez un environnement de développement d'applications Rails avec Docker [Docker, Rails, Puma, Nginx, MySQL]
Construction d'environnement de rails avec Docker (apocalypse personnelle)
Construire un environnement Rails 6 + MySQL avec Docker compose
Construire un environnement pour Laravel + MySQL + phpMyadmin avec Docker
Procédure de construction d'environnement pour l'utilisation de PowerMock avec JUnit
Procédure de construction et de développement de l'environnement local Wordpress avec Docker
[Rails API x Docker] Construction facile de l'environnement avec contrôle de la coque et du fonctionnement avec Flutter
Manuel de construction de l'environnement de développement stable pour "Rails6" avec "Docker-compose"
Procédure pour introduire Docker dans l'environnement de développement des applications Rails existantes [Rails, MySQL, Docker]
Rails5 + MySQL8.0 + Construction d'environnement de volumes de premier niveau avec docker-compose
[Java] Procédure de construction de l'environnement pour le développement de struts 1.3 avec Eclipse
[Rails / MySQL] Construction de l'environnement Mac
Créer un environnement Node.js avec Docker Compose
Création d'un environnement de développement pour Ruby on Rails à l'aide de Docker + VSCode (Remote Container)
Rails 6 (mode API) + création d'environnement MySQL Docker par docker-compose (pour Mac)
Comment créer un environnement Rails + Vue + MySQL avec Docker [dernière version 2020/09]
Créer un environnement de développement pour Django + MySQL + nginx avec Docker Compose
Construction de l'environnement GPU avec Docker [version d'octobre 2020]
Construction de Rails 6 et environnement PostgreSQL avec Docker
Construction de l'environnement de développement Laravel avec Docker (Mac)
Déployer sur heroku avec Docker (Rails 6, MySQL)
Modifier Mysql avec des commandes dans l'environnement Docker
Rails & React & Webpacker & Manuel de construction de l'environnement MySQL
Construction de l'environnement CentOS8.2 (x86_64) + ruby2.5 + Rails5.2 + MariaDB (10.3.17)
Comment créer un environnement Rails 6 avec Docker
Créer un environnement de débogage sur un conteneur - Créer un environnement de développement local pour les didacticiels Rails avec Docker -
J'ai construit un environnement de rails avec docker et mysql, mais j'étais malade
[Construction de l'environnement] Rails + MySQL + Docker (les débutants peuvent également l'utiliser en 30 minutes!)
[Construction de l'environnement Rails & Docker & MySQL] J'ai démarré le conteneur, mais je ne trouve pas MySQL ...?
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 6.x)
Créez un environnement de développement local pour les didacticiels Rails avec Docker (Rails 6 + PostgreSQL + Webpack)
Comment créer un environnement de développement Ruby on Rails avec Docker (Rails 5.x)
Créer un environnement de développement pour Docker + Rails6 + Postgresql
Présentation de Rspec avec Ruby on Rails x Docker
[Rails] Procédure de liaison de bases de données avec Ruby On Rails
[Rails] Comment créer un environnement avec Docker
[Première construction d'environnement] J'ai essayé de créer un environnement Rails6 + MySQL8.0 + Docker sur Windows 10.
Comment créer un environnement Docker avec Gradle pour IntelliJ
Docker x Rails 6 (Mémo)