はじめに
DockerでrailsとMySQLの環境構築を初めてしていく中で「ここなんでこうなるの!?」という箇所が何個かあったり、私がエラーで詰まった場所があったので共有したいと思います。
バージョン
下記のバージョンで実行環境を構築しました。
- ruby 3.2
- rails 6.1.2
- MySQL 8.0
- Docker 20.10.12
必要なファイルを作成
任意のディレクトリを作成し、その直下に
Dockerfile
docker-compose.yml
Gemfile
Gemfile.lock
entrypoint.sh
を作成します。
今回はmy_rails
というディレクトリで進めていきます。
Dockerfile
FROM ruby:3.2
RUN apt-get update && apt-get install -y \
build-essential \
libpq-dev && \
curl -fsSL https://deb.nodesource.com/setup_19.x | bash - && \
apt-get install -y nodejs && \
npm install --global yarn
WORKDIR /my_rails
COPY Gemfile Gemfile.lock /my_rails/
RUN bundle install
# コンテナー起動時に毎回実行されるスクリプトを追加
COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000
# イメージ実行時に起動させる主プロセスを設定
CMD ["rails", "s", "-b", "0.0.0.0"]
まず前提にですが、rails6からwebpacker
がインストール必須になります。
そのwebpacker
をインストールするためにnode.js
とyarn
を使います。
apt-getでnode.jsとyarnをインストールしてはだめなの?
apt-getでインストールしてくる
node.js
やyarn
は古いバージョンのものなので別の方法でインストールしなくてはいけないです。
今回はcurl
でnode.js
、npm
でyarn
をインストールしています。
npm
はnode.js
をインストールしてからでないと使うことができないので
npm install --global yarn
は最後に記述する必要があります。
entrypoint.shを実行するプロセスは必要なの?
これはRailsアプリ特有の問題でサーバー内にserver.pidというファイルが先に存在していたときに、サーバーが再起動できなくなる問題を回避するために置いています。
MySQLは
Dockerfile
でインストールしなくていいの?
docker-compose.yml
ファイルにmysqlの記述をすることでmysqlのimagesを取得できます
docker-compose.yml
version: '3'
volumes:
db-data:
services:
web:
build: .
ports:
- '3000:3000'
volumes:
- '.:/my-rails'
tty: true
stdin_open: true
depends_on:
- db
db:
image: mysql:8
volumes:
- 'db-data:/var/lib/mysql'
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: password
imageキーにmysql:8を指定することでmysqlをDockerで使うことができるようになります。
command: --default-authentication-plugin=mysql_native_password
environment:
MYSQL_ROOT_PASSWORD: password
この3行についてはmysql8.0から必要になったみたいです。参照
mysqlのコンテナが起動できない場合はここが原因かもしれません。
Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 6.1.7'
railsのバージョンを指定してあげればDockerfileをビルドすることでbundle install
が実行され、railsがインストールされます。
Gemfile.lock ファイルには特に何も記述しなくて大丈夫です。
entrypoint.sh
#!/bin/bash
set -e
# Rails に対応したファイル server.pid が存在しているかもしれないので削除する。
rm -f /rails-docker-mysql/tmp/pids/server.pid
# コンテナーのプロセスを実行する。(Dockerfile 内の CMD に設定されているもの。)
exec "$@"
rails特有の問題を処理するためのファイルです。参照
railsアプリ作成
コンテナに入ってから
rails new . --force --database=mysql
をすることでrailsのデフォルトのファイルが作成され、mysqlが使えるようになります。
webpackerがインストールされないよというエラーが出た場合はコンテナ内でrails webpacker:install
を実行してください。
database.ymlの編集
rails newによってconfig
というディレクトリが作られ、その直下にdatabase.yml
が存在します。
default: &default
adapter: mysql2
encoding: utf8mb4
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
port: 3306
username: <%= ENV.fetch("MYSQL_USERNAME", "root") %>
password: <%= ENV.fetch("MYSQL_PASSWORD", "password") %>
host: db
portはmysqlのデフォルトのポート番号が3306なのでそれを指定します。
コンテナでサーバーを起動
コンテナで
rails db:create
をしてサーバーを作成してからホストに戻って
docker-compose up
でDockerfileのCMD
が実行され、localhost:3000でサーバーが立ち上がります。
さいごに
まだ学び始めて日が浅いので言葉足らずな説明もあるかもしれませんが、誰かの役に立てれば嬉しいです。
参考
【Rails】Rails 6.0 x Docker x MySQLで環境構築
Dockerで、Rails 6系とMySQL8の開発環境の構築(OS : mac)
DockerのMySQLイメージ起動時に渡す環境変数
既存の開発環境をDocker化する手順 Rails6+Webpacker+Postgresql+Sidekiq