2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Rails6/MySQL5】Docker環境とローカル環境両方でデータベースを使えるようにする方法

Last updated at Posted at 2021-05-31

※2022年から技術系の記事は個人ブログに投稿しております。ぜひこちらもご覧ください→yamaday0u Blog

以前書いた以下の記事の関連で、Docker環境とローカル環境両方でデータベースを使えるようにする設定について紹介します。
【Rails6/MySQL5】既存アプリにDocker環境を構築した方法(Capistrano・Amazon S3にも対応)

解決したいこと

rails sコマンドを使いローカル環境でサクッとデータベースの動作を確認したい。

基本はdockerで立ち上げたコンテナ環境で動作確認しているけど、ちょこっとデータベースの動きを確認をするためだけにdockerを立ち上げるのが面倒と感じている。

開発環境・前提

  • Ruby 2.6.5
  • Rails 6.0.3.6
  • Docker 20.10.6
  • docker-compose 1.29.1
  • mysql 5.6.50

docker-compose.ymlの記述

docker-compose.yml
#docker-composeのバージョン
version: '3'
services:
  db:
    # 既存アプリとあわせる/ターミナルで[$ mysql --version]で確認
    image: mysql:5.6.50
    # 環境変数の設定
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root
    # ポート番号を指定/[ローカル:コンテナ]
    ports:
      - "4306:3306"
    # 名前付きボリュームでDBのデータを永続化
    # [データボリューム名:コンテナ内のパス]
    volumes:
      - mysql_data:/etc/mysql/conf.d
  web:
    # Dockerfileのパスをカレントディレクトリに指定
    build: .
    # server.pidファイルを削除してからrailsサーバー起動
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    # 環境変数の設定
    environment:
      - MYSQL_HOST=db
      - MYSQL_PASSWORD=password
    # ディレクトリのマウント
    volumes:
      - .:/group_calendar
    ports:
      # ポート番号を指定/[ローカル:コンテナ]
      - 3000:3000
    # サービス間の依存関係を指定
    # この場合、db → webの順でサービスを起動
    depends_on:
      - db
    # コンテナを起動させ続けるための設定
    # make container stay launched
    tty: true
    # stdinはstandard input(標準入力)の略
    # コンテナの外から命令を送るための設定
    stdin_open: true
volumes:
  # db:volumes:で作成したボリューム名を記述
  mysql_data:

特に特別な記述はしていないのですが、注目ポイントはservices:db:environment:以下の環境変数です。
後述のdatabase.ymlでの記述に活かされます。

docker-compose.yml
services:
  db:
    # 環境変数の設定
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: root

database.ymlの記述

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: <%= ENV['MYSQL_PASSWORD'] || '' %> # 記述箇所
  socket: /tmp/mysql.sock
  host: <%= ENV['MYSQL_HOST'] || 'localhost' %> # 記述箇所

解説

概要

passwordhostのところの記述が肝です。

||は比較演算子で、左側の値が真であればその値を返し、偽であれば右側の値を評価してその値を返します。
Ruby 3.0.0 リファレンスマニュアル 演算子式 or

左側の環境変数MYSQL_PASSWORDMYSQL_HOSTdocker-compose.ymlで定義した環境変数です。

右側はrails sコマンドでローカル環境を立ち上げるときに使用されるデータベースのhostpasswordの値です。

補足:順番も大事

左側にDocker環境用の変数を置き、右側にローカル環境用の値を置いていることにも意味があります。

もし、以下のように左側にローカル環境用の値を記述してしまうと、たとえdocker-compose upでDocker環境を立ち上げたとしても、ローカル環境用のデーターベースに接続しようとしてしまい、接続エラーを起こしてしまいます。

config/database.yml
default: &default
  password: <%= '' || ENV['MYSQL_PASSWORD'] %> # 左右の順番を入れ替え
  host: <%= 'localhost' || ENV['MYSQL_HOST'] %> # 左右の順番を入れ替え

Image from Gyazo

その理由はDocker環境の外にあるローカル環境のデータベースに接続することができないからです。

これを回避するために、Docker環境用のデータベースに接続するための記述を比較演算子の左側に記述する必要があります。

rails sでローカル環境を立ち上げる場合は、ローカル環境に環境変数MYSQL_PASSWORDMYSQL_HOSTの値がなく「偽」となるため、右側の値が返されるという仕組みになっています。

参考資料

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?