Rails MySQL docker-compose セットアップ 備忘録

Rails MySQL docker-compose セットアップ 備忘録 バックエンド

はじめに

railsで適当にアプリを作って色々試したい時、セットアップ手順があやふやだったので、備忘録を作っときたい。
できるだけgemとかは入れずにシンプルな構成でセットアップできればOK
以下だけ満たせるようにする

  • docker-compose
  • mysql
  • apiモード
  • Githubと連携

ファイル構成はrailsプロジェクト内にDockerfile, docker-compose.ymlが入る形にする。

手順

リポジトリ作成

何気に忘れがち
Githubにrails_test_appというリポジトリが作ってある前提で以下コマンドを叩く

mkdir rails_test_app
cd rails_test_app
touch Dockerfile
git init
git add .
git commit -m "first commit"
git remote add origin https://github.com/[アカウント名]/rails_test_app.git
git push origin master

Githubのリポジトリ上でDockerfileがアップロードされてればOK

Dockerfile作成・ビルド

一旦パッケージ類のインストールだけして、フォルダのCOPYとかはrailsプロジェクト作成後に追記する
ベースイメージはDockerHubで調べてalpineの最新の使っておけばひとまず良いんじゃないかな。
参考リンク

FROM ruby:3.2.2-alpine3.19
RUN apk update && \
    apk upgrade && \
    apk add --no-cache linux-headers libxml2-dev make gcc vim libc-dev nodejs yarn tzdata bash mysql-dev gcompat && \
    apk add --no-cache -t .build-packages --no-cache build-base curl-dev mysql-client && \
    apk del --purge .build-packages
ENV TZ=Asia/Tokyo
ENV BUNDLER_VERSION=2.3.22

RUN gem install bundler -v ${BUNDLER_VERSION}

イメージをビルドする

docker build . -t [イメージ名]

rails プロジェクト作成

まずはコンテナを起動する。

--mountオプションを指定して起動してるので、ローカル(dockerホスト)にも作成したプロジェクトは反映される。

docker run --mount type=bind,src="$(pwd)",target=/rails_test_app -it [イメージ名]:latest /bin/bash

ここからはコンテナ内の作業

cd rails_test_app
bundle init

Gemfileが作成されるので、以下の内容に変更する
(ローカルのファイルを編集しても、コンテナ内でvimとかで編集してもどっちでもいい)

# frozen_string_literal: true

source "https://rubygems.org"

gem "rails"

rails をインストール・プロジェクト作成する。

  • -Gオプションはgit関係の処理をスキップするらしい。
    プロジェクトを作成するディレクトリに.gitがある場合は指定する。
  • 途中でGemfileが競合するが上書きするかと聞かれるのでyを入力する。
bundle install
rails new . -G -d mysql --api

rails関係のファイルが作成されたらctrl + cでコンテナから抜ける

-Gオプションを指定したことで.gitignore.gitattributesが作成されてないので作成しとく。

/.bundle
/log/*
/tmp/*
!/log/.keep
!/tmp/.keep
/tmp/pids/*
!/tmp/pids/
!/tmp/pids/.keep
/storage/*
!/storage/.keep
.byebug_history
/config/master.key
db/schema.rb linguist-generated
vendor/* linguist-vendored

Dockerfile修正

毎回bundle installするのは面倒なので、イメージビルド時に実行するようにする。

FROM ruby:3.2.2-alpine3.19
RUN apk update && \
  apk upgrade && \
  apk add --no-cache linux-headers libxml2-dev make gcc vim libc-dev nodejs yarn tzdata bash mysql-dev gcompat && \
  apk add --no-cache -t .build-packages --no-cache build-base curl-dev mysql-client && \
  apk del --purge .build-packages
ENV TZ=Asia/Tokyo
ENV BUNDLER_VERSION=2.3.22

RUN gem install bundler -v ${BUNDLER_VERSION}
# ここから追記
COPY . /rails_test_app
WORKDIR /rails_test_app
RUN bundle install

CMD rails s -b 0.0.0.0

docker-compose upしたときにビルドが走るので、今はビルドしなくても良い

docker-compose.yml作成

mysqlコンテナとの連携とローカルファイルとのバインドを設定する。

version: '3'

services:
  db:
    image: mysql:8.0
    command: --default-authentication-plugin=mysql_native_password
    environment:
      - MYSQL_ROOT_PASSWORD=root_password
      - MYSQL_USER=user_name
      - MYSQL_PASSWORD=mysql_password
      - MYSQL_DATABASE=db_name
    ports:
        - "3306:3306"
    volumes:
      - mysql_data:/var/lib/mysql

  rails:
    build:
      context: ./
      dockerfile: ./Dockerfile
    command: >
      bash -c "rails s -b 0.0.0.0"
    volumes:
      - ./:/rails_test_app
    environment:
      - TZ=Asia/Tokyo
    ports:
      - "3000:3000"
    depends_on:
      - db
volumes:
  mysql_data: null

何かの理由でmysqlのコンテナにcommandを指定してたんだけど理由忘れた。
いつか調べてまとめる。Sequence Proを使いたいとかだったっけ。。?

DB連携 & モデル作成

database.ymlを編集する。
どうせローカルの環境ではdevelopment環境しか使わないから他は削除

default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: user_name  # <- 入力
  password: mysql_password  # <- 入力
  host: db  # <- 入力

development:
  <<: *default
  database: db_name  # <- 入力

コンテナに入る

docker-compose run --rm rails /bin/bash

ここからコンテナ内の作業

rails db:create
rails g model parent name:string age:integer
rails g model child name:string age:integer parent:references
rails db:migrate

あとはモデルにアソシエーションを定義して完成
( Childクラスにはbelongs_to :parentが元々記入してあるので省略)

class Parent < ApplicationRecord
  has_many :children  # <- 追記
end

あとはコントローラー作るなり、CORS設定するなりすればOK

エラーハンドル

No such file or directory - git config init.defaultbranch (Errno::ENOENT)

rails new する際に -G オプションをつければ直った。
既存の.gitに対して色々処理してる時に発生するエラー。この処理をスキップするのが -G オプション

NameError: uninitialized constant Gem::Source

bundlerのバージョンを2.3.10にしたら直った。
2.3.7, 2.3.8とかだと発生するらしい。

参考リンク

gem::ext::builderror: error: failed to build gem native extension.

rails が依存してるgemのインストールに失敗してる。
コンテナにmysql-dev等のパッケージが不足しているから発生しているっぽいが、どのパッケージがどのgemに必要なのか、調べてはない。
上記のDockerfileの内容を丸々写すのが無難。

タイトルとURLをコピーしました