LoginSignup
1
1

More than 1 year has passed since last update.

【メモ】Rails+MySQLの環境構築をDockerでおこなう

Last updated at Posted at 2020-05-10

前提

ローカル環境

  • macOS Mojave10.14.6
  • Docker for mac 2.2.0.5

バージョン

  • Ruby...2.6.3 2.6.6
  • Rails...5.2.4.1 5.2.8.1
  • alpine Debian

バージョン変更について

Rails

初投稿時には問題なかったが、久々に本記事どおりに構築を進めた際、rails new した時に mimemagic install error: "Could not find MIME type database in the following locations..."と出たので変更

mimemagic問題についての情報を集めていく場所

Ruby

Herokuへのデプロイ時に heroku The Ruby version you are trying to install does not exist on this stack. と出たのでその解決策。Rubyのバージョンを 2.6.6 か、 2.7.2 か、 3.0.0 に変更すると解決する。

【解決】heroku-20 You are trying to install ruby-2.6.5 on heroku-20. The Ruby version you are trying to install does not exist on this stack.

その他

プロジェクト用ディレクトリ、ファイルを用意

$ mkdir myapp
$ cd myapp
$ mkdir -p mnt/mysql \
  docker/mysql/{init,conf.d} \
  docker/ruby \
  src
$ touch .env.example .gitignore docker-compose.yml \
  mnt/mysql/.gitignore \
  docker/mysql/init/init.sql \
  docker/mysql/conf.d/my.cnf \
  docker/ruby/Dockerfile \
  src/{Gemfile,Gemfile.lock}

各ファイルを編集

.env.example

DB_NAME=rails_tutorial
DB_TEST_NAME=rails_tutorial_test
DB_USER=admin
DB_PASS=admin
DB_ROOT_PASS=password
DB_PORT=23306
TZ=Asia/Tokyo
APP_PORT=13000
$ cp .env.example .env

.gitignore

.gitignore
.env
mnt/mysql/.gitignore
*
!.gitignore

my.cnf

docker/mysql/conf.d/my.cnf
# MySQLサーバーへの設定
[mysqld]
# 文字コード/照合順序の設定
character-set-server = utf8mb4
collation-server = utf8mb4_unicode_ci

# タイムゾーンの設定
#default-time-zone=SYSTEM

# 以下はMYSQLのみなので
#log_timestamps=SYSTEM

# エラーログの設定
log-error = /var/log/mysql/error.log

# ログ関連
# スロークエリログの設定
slow_query_log = 1
slow_query_log_file = /var/log/mysql/slow.log
long_query_time = 5
log_queries_not_using_indexes = 0

# 実行ログの設定
#general_log = 1
#general_log_file = /var/log/mysql/query.log

#max_allowed_packet = 32M

# windows tool box 対策
#innodb_use_native_aio=0


wait_timeout = 28800
interactive_timeout = 28800
max_allowed_packet = 100M

# mysqlオプションの設定
[mysql]
# 文字コードの設定
default-character-set = utf8mb4


# mysqlクライアントツールの設定
[client]
default-character-set = utf8mb4

init.sql

docker/mysql/init/init.sql
-- テスト時にDBを分けたいので、初期立ち上げ時にテスト用DBを作成 
CREATE DATABASE IF NOT EXISTS `rails_tutorial_test`;
GRANT ALL ON rails_tutorial_test.* TO 'admin'@'%';

docker-compose.yml

docker-compose.yml
version: "3"
services:
  app:
    build:
      context: .
      dockerfile: ./docker/ruby/Dockerfile
    volumes:
      - ./src:/var/www/src
    command: rails s -p 8000 -b '0.0.0.0'
    ports:
      - ${APP_PORT:-13000}:8000
    links:
      - db

  db:
    image: mysql:5.7
    environment:
      - MYSQL_DATABASE=${DB_NAME:-rails_tutorial}
      - MYSQL_USER=${DB_USER:-admin}
      - MYSQL_PASSWORD=${DB_PASS:-admin}
      - MYSQL_ROOT_PASSWORD=${DB_ROOT_PASS:-password}
      - MYSQL_ALLOW_EMPTY_PASSWORD="yes"
      - TZ=${TZ:-Asia/Tokyo}
    ports:
      - ${DB_PORT:-23306}:3306
    volumes:
      - ./mnt/mysql:/var/lib/mysql
      - ./docker/mysql/conf.d:/etc/mysql/conf.d # my.cnfを共有
      - ./docker/mysql/init:/docker-entrypoint-initdb.d # 立ち上げ時にテスト用DBを作成するため

Dockerfile

Dockerfile
FROM ruby:2.6.6

RUN apt-get update && apt-get install -y git \
  vim \
  less \
  build-essential \
  libpq-dev \
  libxml2-dev \
  libc-dev \
  make \
  gcc \
  g++ \
  nodejs && \
  apt-get clean && \
  rm -rf /var/lib/apt/lists/*

ENV APP_ROOT /var/www/src

WORKDIR $APP_ROOT

COPY ./src/Gemfile $APP_ROOT/Gemfile
COPY ./src/Gemfile.lock $APP_ROOT/Gemfile.lock

RUN bundle install && \
    apt-get update

COPY ./src/ $APP_ROOT
RUN rm -rf /usr/local/bundle/cache/* ${APP_ROOT}/vendor/bundle/cache/*

Gemfile

Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.5'

アプリケーション作成

$ docker compose run app rails new . --force --no-deps --database=mysql --skip-bundle
  • ディレクトリが下記のようにできていれば成功
$ tree -L 1 .
.
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── docker-compose.yml
├── lib
├── log
├── package.json
├── public
├── storage
├── test
├── tmp
└── vendor

config/database.yml を編集

config/database.ymlがなければ作成

$ vi config/database.yml
config/database.yml
# ...

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: admin  # docker-compose.ymlの設定と合わせる
  password: admin  # docker-compose.ymlの設定と合わせる
  host: db         # docker-compose.ymlのサービス名と合わせる

development:
  <<: *default
  database: rails_tutorial  # docker-compose.ymlの設定と合わせる
  host: db                  # docker-compose.ymlの設定と合わせる

# ...

test:
  <<: *default
  database: rails_tutorial_test  # docker-compose.ymlの設定と合わせる
  host: db                  # docker-compose.ymlの設定と合わせる

# ...

production:
  <<: *default
  database: rails_tutorial
  username: admin   # docker-compose.ymlの設定と合わせる
  password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %>

docker-compose

$ docker compose build
$ docker compose up -d
$ docker compose exec app bash
$ rails -v  # バージョンが表示されれば成功
$ rails db:create
Database 'rails_tutorial' already exists
Database 'rails_tutorial_test' already exists

画面確認

  • localhost:13000 にアクセスし、TOP 画面が表示されれば成功
    initial_screen.png

Herokuにデプロイ

Heroku Appの作成 ~ Gitセットアップ

$ cd src
$ heroku --version
# heroku/7.60.2 darwin-x64 node-v14.19.0

$ heroku login
$ heroku apps:create kabatech255railstutorial
# Creating ⬢ [アプリ名]... done
# https://[アプリ名].herokuapp.com/ | https://git.heroku.com/[アプリ名].git
# ...

$ git remote -v
heroku  https://git.heroku.com/[アプリ名].git (fetch)
heroku  https://git.heroku.com/[アプリ名].git (push)
$ git init
$ git add
$ git commit -m "first commit"
$ git branch -M main
# まだプッシュしない

MySQLを使用できるように設定

Herokuはデフォルトで PostgreSQL を採用しているので、MySQLが使えるよう設定する。

# cleardb: クラウド上でMySQLを使えるサービス
# ignite: プラン名。igniteは無料
$ heroku addons:create cleardb:ignite -a kabatech255railstutorial
$ heroku config
CLEARDB_DATABASE_URL: mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true

# 上記を参考にherokuの環境設定を追加
$ heroku config:add DB_NAME='[データベース名]' -a kabatech255railstutorial
$ heroku config:add DB_USERNAME='[ユーザー名]' -a kabatech255railstutorial
$ heroku config:add DB_PASSWORD='[パスワード]' -a kabatech255railstutorial
$ heroku config:add DB_HOSTNAME='[ホスト名]' -a kabatech255railstutorial
$ heroku config:add DB_PORT='3306' -a kabatech255railstutorial
$ heroku config:add DATABASE_URL='mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true' -a kabatech255railstutorial

$ heroku config heroku config -a kabatech255railstutorial
=== [アプリ名] Config Vars
CLEARDB_DATABASE_URL:     mysql://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
DATABASE_URL:             mysql2://[ユーザー名]:[パスワード]@[ホスト名]/[データベース名]?reconnect=true
DB_HOSTNAME:              [ホスト名]
DB_NAME:                  [データベース名]
DB_PASSWORD:              [パスワード]
DB_PORT:                  3306
DB_USERNAME:              [ユーザー名]
# ...

注意

heroku config:add DATABASE_URL=のところで、CLEARDB_DATABASE_URLをコピペして、mysql://~~~でセットすると、あとでエラーが出る。

mysql://のところをmysql2://に修正してセットすること

【Heroku】デプロイ後エラー対処 Could not load the 'mysql' Active Record adapter.

本番用にファイルを編集

routes.rb

この設定をしないとHerokuへデプロイした時に The page you were looking for doesn't exist. とエラーが出る

Herokuへデプロイした時に「The page you were looking for doesn't exist. 」エラーが出る

config/routes.rb
Rails.application.routes.draw do
  # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
  root 'application#hello'
end

application_controller.rb

app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
  protect_from_forgery with: :exception
  
  def hello
    render html: "hello, world!"
  end
end

database.yml

config/database.yml
# ...
production:
  <<: *default
  database: heroku.configのDB_NAME
  username: heroku.configのDB_USERNAME
  password: heroku.configのDB_PASSWORD
  host: heroku.configのDATABASE_URL
  # password: <%= ENV['SRC_DATABASE_PASSWORD'] %>

ソースのプッシュ

$ git push heroku main
$ heroku rake db:migrate
$ heroku open

https://kabatech255railstutorial.herokuapp.com/ にアクセスし、hello., world! と文字列が出ていたらOK。

参考

1
1
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
1
1