DBをMySQL
にしたRails API
環境をdocker-compose
を使って構築しました。
前提
Docker & docker-composeをインストール済み
動作環境
- macOS Catalina 10.15.7
- Ruby 2.7.1
- Ruby on Rails 6.0.3
- MySQL 8.0.23
- Docker 20.10.2
- docker-compose 1.27.4
ディレクトリ構成
最終的なディレクトリ構成は以下です。MySQLのデータを格納するmysql
と、rails
内の各ディレクトリ以下の内容は省略しています。
rails_api_mysql
├── docker-compose.yml
├── db
└── app
├── Dockerfile
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── lib
├── log
├── public
├── storage
├── test
├── tmp
└── vendor
手順
プロジェクトを作成します。
mkdir rails_api_mysql
cd rails_api_mysql
docker-compose.yml
を作成します。
version: '3'
services:
db:
image: mysql:8.0.23
environment:
MYSQL_ROOT_PASSWORD: password
volumes:
- ./mysql:/var/lib/mysql
command: ["--default-authentication-plugin=mysql_native_password"]
ports:
- 3306:3306
app:
build: rails
volumes:
- ./rails:/usr/src/app
command: ["rails", "server", "-b", "0.0.0.0"]
ports:
- 3000:3000
depends_on:
- db
MySQLのデータをホスト側で管理するために、services
の db
にvolume
を指定しています。
MySQLのデータを格納するためのdb
ディレクトリを作成します。中身は空で大丈夫です。
mkdir db
Railsアプリケーションを格納するためのapp
ディレクトリを作成し、その中にGemfile
Gemfile.lock
Dockerfile
を作成します。
source 'https://rubygems.org'
gem 'rails', '6.0.3'
空で大丈夫です
FROM ruby:2.7.1-alpine3.11
ENV BUNDLER_VERSION=2.1.4
WORKDIR /usr/src/app
COPY Gemfile .
COPY Gemfile.lock .
RUN apk update && \
apk add --no-cache \
shared-mime-info \
linux-headers \
libxml2-dev \
curl-dev \
make \
gcc \
libc-dev \
g++ \
build-base \
mariadb-dev \
tzdata && \
gem install bundler && \
bundle install
COPY . .
EXPOSE 3000
rails new
を実行し、アプリケーションを作成します。これでrails
ディレクトリに各ファイルが生成されます。
docker-compose run --rm --no-deps app rails new . --force --database=mysql --skip-keeps -M -C -S -J -B
/app/config/database.yml
を編集します。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password # docker-compose.ymlのMYSQL_ROOT_PASSWORDと同じにします
host: db # docker-compose.ymlのservicesのdbのことです
development:
<<: *default
database: app_development
test:
<<: *default
database: app_test
production:
<<: *default
database: app_production
username: app
password: <%= ENV['APP_DATABASE_PASSWORD'] %>
dockerイメージをもう1度ビルドします。上記のrails new
を実行したことによりGemfile
Gemfile.lock
の内容が変わっているためです。
docker-compose build
コンテナを起動します。
docker-compose up
コンテナにアクセスし、DBを構築します。
docker-compose run app rails db:create
localhost:3000
にアクセスし、起動画面が表示されれば成功です。
動作確認
MySQLが正常に動作しているか確認します。
コンテナにログインします。
docker-compose exec app sh
controller
と model
を作成します。
rails g controller Users index --no-template-engine --no-test-framework --no-assets
rails g model User name:string --no-test-framework
/db/seeds.rb
に以下を追記してテストデータを定義します。
User.create name: "Pythagoras"
DBを初期化し、テストデータを反映させます。
rails db:migrate
rails db:seed
/app/controllers/users_controller.rb
のindexアクションを以下に変更します。
def index
@users = User.all
render json: @users
end
localhost:3000/users/index
にアクセスすると以下の様に表示されるはずです。
コンテナを1度破棄し、再び起動します。
docker-compose down
docker-compose up
もう1度localhost:3000/users/index
にアクセスして以下の様に表示されれば成功です。ちゃんとホスト側のMySQLデータが読み込まれていますね。
読んでいただきありがとうございました!ご指摘やご意見などありましたらコメントしていただけると嬉しいです🐳