環境
Mac | 13.1(22C65) |
Docker | 20.10.23 |
Docker Compose | v2.15.1 |
Ruby | 2.7.0 |
Rails | 5.2.8.1 |
MySQL | 5.7 |
Rails+MySQLの環境構築を行う
Railsを動かすwebコンテナとMySQLを動かすdbコンテナを作る。 webコンテナのイメージはDockerfileを使ってビルドし、dbコンテナのイメージはDocker Hubのmysqlのイメージをそのまま使う。 コンテナはDocker Composeでまとめて操作する。
手順は以下の通り。
- 必要なファイルを作る
- Railsのプロジェクトを作成する
- イメージをビルドする
- データベースの接続設定を行う
- Docker Composeでコンテナを起動する
- データベースを作成する
- Webサーバーにアクセスして、Railsのページを確認する
1. 必要なファイルを作る
Rails+MySQL環境を構築するために必要なファイルを作る。
作るファイルは以下の4つ。
- Dockerfile
- docker-compose.yml
- Gemfile
- Gemfile.lock
Dockerfile
webコンテナのイメージを作るためにDockerfileを作成する。
FROM ruby:2.7.0 RUN apt-get update -qq && apt-get install -y build-essential nodejs default-mysql-client RUN mkdir /src WORKDIR /src COPY Gemfile /src/Gemfile COPY Gemfile.lock /src/Gemfile.lock RUN bundle install COPY . /src
FROM
でベースイメージにrubyを指定する。
FROM ruby:2.7.0
RUN
はLinuxのコマンドを実行する。
apt-get update -qq
でパッケージをインストールする前にアップデートする。-qq
はログを表示しないためのオプション。
apt-get install -y
で必要なパッケージをインストールする。-y
はインストール時のいくつかの質問をすべてyesで省略するオプション。
RUN apt-get update -qq && apt-get install -y build-essential nodejs default-mysql-client
build-essential
は開発に必要なビルドツールを提供するパッケージ。
nodejs
はRailsのフロント部分のために必要なパッケージ。
default-mysql-client
はMySQLを使うために必要なパッケージ。
コンテナ内にsrcディレクトリを作成する。
RUN mkdir /src
ワーキングディレクトリをsrcにする。
WORKDIR /src
ホストのGemfileとGemfile.lockをコンテナの/src配下にコピーする。GemfileとGemfile.lockについては後述。
COPY Gemfile /src/Gemfile COPY Gemfile.lock /src/Gemfile.lock
コンテナ内でGemをインストールする。Gemについては後述。
RUN bundle install
ホスト側に作られたRailsのプロジェクトをコンテナにコピーする。
COPY . /src
docker-compose.yml
Docker Composeを使うための、docker-compose.yml
は以下の内容を記述する。
version: '3' services: web: build: dockerfile: Dockerfile context: . command: bundle exec rails s -p 3000 -b '0.0.0.0' ports: - '3000:3000' volumes: - type: bind source: . target: /src depends_on: - db db: image: mysql:5.7 ports: - '3306:3306' environment: MYSQL_ROOT_PASSWORD: password volumes: - type: volume source: mysql target: /var/lib/mysql volumes: mysql:
最初のversion:
はDocker Composeのバージョンを指定。
最後のvolumes:
はデータベースのデータが消えてしまわないようにボリュームを作成する。
間のservices:
にwebコンテナとdbコンテナの設定を書いていく。
webコンテナ
build:
でビルドするDockerfileを指定する。
build: dockerfile: Dockerfile context: .
command:
はコンテナを起動したときに実行するコマンドを指定する。ここにはRailsのサーバーを起動するコマンドを記述。
command: bundle exec rails s -p 3000 -b '0.0.0.0'
bundle exec
はインストールされたgemのコマンドを実行するコマンド。rails s -p 3000
でRailsのサーバーをポート番号3000で起動し、 -b '0.0.0.0'
でコンテナの外からサーバーにアクセスできるようにする。
ports:
でホストのポート番号と、コンテナ内のポート番号を紐づける。ここではホストでRailsのサーバーのポート番号を3000に指定した時に、コンテナ内のサーバーの3000番ポートにアクセスする。
ports: - '3000:3000'
volumes:
ではバインドマウントを設定する。バインドマウントはホストとコンテナでファイルを共有するための仕組み。これによってホストのソースコードを更新したらコンテナに反映されるようにする。
voluems: - type: bind source: . target: /src
depends_on:
はwebコンテナをdbコンテナに依存させるための記述。これによってdbコンテナが起動してからwebコンテナを起動し、反対にwebコンテナが終了してからdbコンテナを修了させるようにする。
depends_on: - db
dbコンテナ
image:
でDocker Hubのイメージを指定する。
images: mysql:5.7
ports:
は3306に指定する。
ports: - '3306:3306'
environment:
でコンテナで使用する環境変数を指定する。
environment: MYSQL_ROOT_PASSWORD: password
volumes:
でボリュームをマウントする。これによってコンテナを終了してもデータベースのデータを保持できる。
volumes: - type: volume source: mysql target: /var/lib/mysql
Gemfile
RailsはGemとBundlerを使ってインストールする。
GemとはRubyのライブラリのこと。RailsもGemの1つ。
Bundlerとはgemを一括で管理するためのGemのこと。
GemfileはBundlerを使ってGemの管理を行うためのファイル。インストールしたいGemとそのバージョンを記述すれば、bundle install
で一括でインストールできる。
source 'https://rubygems.org' gem 'rails', '5.2.1'
source
はgemのダウンロード元を指定する。
gem 'rails', '5.2.1'
はバージョンが5.2.1のrailsのgemをインストールするための記述。
Gemfile.lock
Gemfile.lockはインストールしたGemとバージョンと依存関係が記述されるファイル。 Railsをインストールする前は空のGemfile.lockを作成し、インストール後も開発者が直接編集することはない。
2. Railsのプロジェクトを作成する
必要なファイルを用意できたら、以下のコマンドでRailsのプロジェクトを作成する。
docker compose run web rails new . --force --database=mysql
docker compose run web
なので、web
コンテナを起動して一度だけ後ろに続くコマンドを実行する。
web
の後ろのrails new . --force --database=mysql
はRailsのコマンドとオプションで、Railsのプロジェクトを作成している。
rails new .
がRailsのプロジェクトを現在のディレクトリに作成する。ここでの現在のディレクトリはコンテナ内の/src
を指す。
--force
は既存のファイルが存在している場合上書きするオプション。
--database=mysql
はRailsで使用するデータベースをMySQLに指定するオプション。
Railsのプロジェクトがインストールされると、以下のようなディレクトリ構成になる。
. ├── app/ ├── bin/ ├── config/ ├── db/ ├── lib/ ├── log/ ├── public/ ├── storage/ ├── test/ ├── tmp/ ├── vendor/ ├── .gitignore ├── .ruby-version ├── config.ru ├── docker-compose.yml ├── Dockerfile ├── Gemfile ├── Gemfile.lock ├── package.json ├── Rakefile └── README.md
GemfileとGemfile.lockは以下のように更新される。
ssource 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '2.7.0' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.2.8', '>= 5.2.8.1' # Use mysql as the database for Active Record gem 'mysql2', '>= 0.4.4', '< 0.6.0' # Use Puma as the app server gem 'puma', '~> 3.11' # Use SCSS for stylesheets gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' # See https://github.com/rails/execjs#readme for more supported runtimes # gem 'mini_racer', platforms: :ruby # Use CoffeeScript for .coffee assets and views gem 'coffee-rails', '~> 4.2' # Turbolinks makes navigating your web application faster. Read more: https://github.com/turbolinks/turbolinks gem 'turbolinks', '~> 5' # Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder gem 'jbuilder', '~> 2.5' # Use Redis adapter to run Action Cable in production # gem 'redis', '~> 4.0' # Use ActiveModel has_secure_password # gem 'bcrypt', '~> 3.1.7' # Use ActiveStorage variant # gem 'mini_magick', '~> 4.8' # Use Capistrano for deployment # gem 'capistrano-rails', group: :development # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', '>= 1.1.0', require: false group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] end group :development do # Access an interactive console on exception pages or by calling 'console' anywhere in the code. gem 'web-console', '>= 3.3.0' gem 'listen', '>= 3.0.5', '< 3.2' # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' end group :test do # Adds support for Capybara system testing and selenium driver gem 'capybara', '>= 2.15' gem 'selenium-webdriver' # Easy installation and use of chromedriver to run system tests with Chrome gem 'chromedriver-helper' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
GEM remote: https://rubygems.org/ specs: actioncable (5.2.8.1) actionpack (= 5.2.8.1) nio4r (~> 2.0) websocket-driver (>= 0.6.1) actionmailer (5.2.8.1) actionpack (= 5.2.8.1) actionview (= 5.2.8.1) activejob (= 5.2.8.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) actionpack (5.2.8.1) actionview (= 5.2.8.1) activesupport (= 5.2.8.1) rack (~> 2.0, >= 2.0.8) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) actionview (5.2.8.1) activesupport (= 5.2.8.1) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.3) activejob (5.2.8.1) activesupport (= 5.2.8.1) globalid (>= 0.3.6) activemodel (5.2.8.1) activesupport (= 5.2.8.1) activerecord (5.2.8.1) activemodel (= 5.2.8.1) activesupport (= 5.2.8.1) arel (>= 9.0) activestorage (5.2.8.1) actionpack (= 5.2.8.1) activerecord (= 5.2.8.1) marcel (~> 1.0.0) activesupport (5.2.8.1) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 0.7, < 2) minitest (~> 5.1) tzinfo (~> 1.1) addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) archive-zip (0.12.0) io-like (~> 0.3.0) arel (9.0.0) bindex (0.8.1) bootsnap (1.16.0) msgpack (~> 1.2) builder (3.2.4) byebug (11.1.3) capybara (3.39.2) addressable matrix mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) rack-test (>= 0.6.3) regexp_parser (>= 1.5, < 3.0) xpath (~> 3.2) chromedriver-helper (2.1.1) archive-zip (~> 0.10) nokogiri (~> 1.8) coffee-rails (4.2.2) coffee-script (>= 2.2.0) railties (>= 4.0.0) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) concurrent-ruby (1.2.2) crass (1.0.6) date (3.3.3) erubi (1.12.0) execjs (2.8.1) ffi (1.15.5) globalid (1.1.0) activesupport (>= 5.0) i18n (1.14.1) concurrent-ruby (~> 1.0) io-like (0.3.1) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) listen (3.1.5) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) ruby_dep (~> 1.2) loofah (2.21.3) crass (~> 1.0.2) nokogiri (>= 1.12.0) mail (2.8.1) mini_mime (>= 0.1.1) net-imap net-pop net-smtp marcel (1.0.2) matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) mini_portile2 (2.8.2) minitest (5.18.1) msgpack (1.7.1) mysql2 (0.5.5) net-imap (0.3.6) date net-protocol net-pop (0.1.2) net-protocol net-protocol (0.2.1) timeout net-smtp (0.3.3) net-protocol nio4r (2.5.9) nokogiri (1.15.2) mini_portile2 (~> 2.8.2) racc (~> 1.4) public_suffix (5.0.1) puma (3.12.6) racc (1.7.1) rack (2.2.7) rack-test (2.1.0) rack (>= 1.3) rails (5.2.8.1) actioncable (= 5.2.8.1) actionmailer (= 5.2.8.1) actionpack (= 5.2.8.1) actionview (= 5.2.8.1) activejob (= 5.2.8.1) activemodel (= 5.2.8.1) activerecord (= 5.2.8.1) activestorage (= 5.2.8.1) activesupport (= 5.2.8.1) bundler (>= 1.3.0) railties (= 5.2.8.1) sprockets-rails (>= 2.0.0) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.6.0) loofah (~> 2.21) nokogiri (~> 1.14) railties (5.2.8.1) actionpack (= 5.2.8.1) activesupport (= 5.2.8.1) method_source rake (>= 0.8.7) thor (>= 0.19.0, < 2.0) rake (13.0.6) rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) regexp_parser (2.8.1) rexml (3.2.5) ruby_dep (1.5.0) rubyzip (2.3.2) sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) sass-rails (5.1.0) railties (>= 5.2.0) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) selenium-webdriver (4.9.0) rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2, < 3.0) websocket (~> 1.0) spring (2.1.1) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) spring (>= 1.2, < 3.0) sprockets (3.7.2) concurrent-ruby (~> 1.0) rack (> 1, < 3) sprockets-rails (3.4.2) actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) thor (1.2.2) thread_safe (0.3.6) tilt (2.2.0) timeout (0.3.2) turbolinks (5.2.1) turbolinks-source (~> 5.2) turbolinks-source (5.2.0) tzinfo (1.2.11) thread_safe (~> 0.1) uglifier (4.2.0) execjs (>= 0.3.0, < 3) web-console (3.7.0) actionview (>= 5.0) activemodel (>= 5.0) bindex (>= 0.4.0) railties (>= 5.0) websocket (1.2.9) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) xpath (3.2.0) nokogiri (~> 1.8) PLATFORMS ruby DEPENDENCIES bootsnap (>= 1.1.0) byebug capybara (>= 2.15) chromedriver-helper coffee-rails (~> 4.2) jbuilder (~> 2.5) listen (>= 3.0.5, < 3.2) mysql2 (>= 0.4.4, < 0.6.0) puma (~> 3.11) rails (~> 5.2.8, >= 5.2.8.1) sass-rails (~> 5.0) selenium-webdriver spring spring-watcher-listen (~> 2.0.0) turbolinks (~> 5) tzinfo-data uglifier (>= 1.3.0) web-console (>= 3.3.0) RUBY VERSION ruby 2.7.0p0 BUNDLED WITH 2.1.2
Gemfileには、Railsを使うためのgemが一覧として記述されており、Gemfile.lockには実際にインストールされたgemとそのバージョンが記述されている。
複数人で開発する場合バージョンを揃える必要があるので、このGemfile.lockを共有する。
3. イメージをビルドする
RailsのプロジェクトをインストールしたことでGemfileが更新されているので、以下のコマンドで再度ビルドする。
docker compose build
4. データベースの接続設定を行う
Railsのプロジェクトが作られると、config
ディレクトリが作られ、その配下にdatabase.yml
が作られる。このファイルによってデータベースの接続設定を行う。
# MySQL. Versions 5.1.10 and up are supported. # # Install the MySQL driver # gem install mysql2 # # Ensure the MySQL gem is defined in your Gemfile # gem 'mysql2' # # And be sure to use new-style password hashing: # https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html # default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: host: localhost development: <<: *default database: src_development # Warning: The database defined as "test" will be erased and # re-generated from your development database when you run "rake". # Do not set this db to the same as development or production. test: <<: *default database: src_test # As with config/secrets.yml, you never want to store sensitive information, # like your database password, in your source code. If your source code is # ever seen by anyone, they now have access to your database. # # Instead, provide the password as a unix environment variable when you boot # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database # for a full rundown on how to provide these environment variables in a # production deployment. # # On Heroku and other platform providers, you may have a full connection URL # available as an environment variable. For example: # # DATABASE_URL="mysql2://myuser:mypass@localhost/somedatabase" # # You can use this database configuration with: # # production: # url: <%= ENV['DATABASE_URL'] %> # production: <<: *default database: src_production username: src password: <%= ENV['SRC_DATABASE_PASSWORD'] %>
この部分のpassword:
とhost:
を変更する。
default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: root password: password host: db
password
はdocker-compose.ymlのdb:
のenvironment:
のMYSQL_ROOT_PASSWORD
と合わせる。
db
はdocker-compose.ymlのservices:
のdb:
。
5. Docker Composeでコンテナを起動する
docker compose up -d
でコンテナを起動する。
docker compose up -d
もしコンテナが起動してもすぐにExited
になってしまう場合はdocker compose up
でログを表示するように実行する。
6. データベースを作成する
docker compose run web rails db:create
でデータベースを作成する。
docker compose run web rails db:create
db:create
はデータベースを作成するRailsのコマンド。
7.Railsのページが表示されているか確認する。
docker-compose.yml
でwebコンテナのポートを3000に指定しているので、http://localhost:3000
でRailsのページが表示されるか確認する。表示されれば環境構築の完了。