はじめに
Dockerを使用して自作のRailsアプリの開発から公開までを記事にしていこうと考えています。
あくまで自分の学習したことのまとめ用に投稿していく予定ですが、同じようにこれから勉強を始める誰かの参考になればいいなと思ってます!
Dockerとは
Dockerとは、近年注目されている仮想化ソフトの一種です。
注目されている理由は、その手軽さにあります。
Dockerは、コンテナ型仮想化と呼ばれる技術を使用しており、従来のホスト型仮想化と異なり、ハードウェアを仮想化しません。そのため、ゲストOSを起動させる必要がなくリソース使用量が少ない点がメリットとして挙げられます。
イメージ、コンテナといったワードがちょこちょこ出てきますが、以下で覚えることにしました。
イメージ・・・OSやアプリを含んだテンプレートです。言わばコンテナのひな形。
コンテナ・・・イメージから生成される仮想サーバー。マシン上で一つのプロセスとして管理されます。
Dockerは、
イメージの構成を「Dockerfile」、
コンテナの構成を「docker-compose.yml」
というファイルで管理します。
Docker for Macのインストール〜起動
※ Macでお勉強中なので、Windowsの人はゴメンナサイ・・・
- 公式サイトからDocker.dmgをダウンロード
- Docker.dmgを実行
- Docker.appをApplicationsにドラッグ&ドロップ
- Docker.appをダブルクリックで起動
やること
Rails用のコンテナとMySQL用のコンテナを作成して画面起動確認までを行いたいと思います。
それぞれバージョンは、
- Ruby:2.5.1
- MySQL:8.0
を使用します。
やることを整理すると以下の通り。
- docker-compose.yml、Dockerfileの作成
- Gemfile、Gemfile.lockの作成
- コンテナの作成
- データベースの設定
- 画面起動確認
ディレクトリ構成
ディレクトリはこんな感じで進めていきます。
root
├── Dockerfile
├── docker-compose.yml
├── mysql-confd
│ └── default_authentication.cnf
└── src
├── Gemfile
└── Gemfile.lock
default_authentication.cnfは、MySQL8.0のデフォルト認証形式を変更するための設定ファイルです。
こちらの記事を参考に作成しました。
これしないで進めてたらデータベース作成時にエラーになりました。。
MySQL5.7と8.0では認証方法が異なることが原因とのこと。
認証方法を5.7に合わせるように設定しています。
1. docker-compose.yml、Dockerfileの作成
docker-compose.ymlの中身はこんな感じ
# docker-compose.ymlフォーマットのバージョン指定
version: '3'
services:
# Railsコンテナ定義
web:
# Dockerfileを使用してイメージをビルド
build: .
# コンテナ起動時のデフォルトコマンド
# ポート番号:3000
# バインドするIPアドレス:0.0.0.0
# ポート3000が来たらrailsサーバーが応答
command: bundle exec rails s -p 3000 -b '0.0.0.0'
# ローカルのsrcをコンテナにマウント
volumes:
- ./src:/app
# コンテナの外部に3000番を公開
# 公開するポート番号:コンテナ内部の転送先ポート番号
ports:
- 3000:3000
# dbコンテナが先に起動するよう設定
depends_on:
- db
# pryを使用してデバッグができるよう設定
tty: true
stdin_open: true
# MySQLコンテナ定義
db:
# mysqlを使用してコンテナ作成
image: mysql:8.0
volumes:
# Mysql8.0のデフォルトの認証形式をmysql_native_passwordに設定
- ./mysql-confd:/etc/mysql/conf.d
# ローカルで保持しているDBをコンテナにマウント
- db-volume:/var/lib/mysql
# コンテナ内の環境変数を定義
environment:
# mysqlのルートユーザーのパスワード設定
MYSQL_ROOT_PASSWORD: password
# DBの内容をローカルに保持
volumes:
db-volume:
Dockerfileの中身はこんな感じ
# Railsコンテナ用Dockerfile
# イメージのベースラインにRuby2.5.1を指定
FROM ruby:2.5.1
# Railsに必要なパッケージをインストール
RUN apt-get update -qq && apt-get install -y build-essential nodejs
# ルートディレクトリを作成
RUN mkdir /app
# 作業ディレクトリを指定
WORKDIR /app
# ローカルのGemfileとGemfile.lockをコピー
COPY src/Gemfile /app/Gemfile
COPY src/Gemfile.lock /app/Gemfile.lock
# Gemのインストール実行
RUN bundle install
# ローカルのsrcをコピー
COPY src /app
COPYコマンドでコピー元(ローカル側)はDockerfileが置いてあるパス以下の相対パス指定しかできないみたいです。(../を使うとエラーになった。。)
2. Gemfile、Gemfile.lockの作成
① srcディレクトリでbundle init
を実行してGemfile新規作成
② Gemfileの中身はこんな感じに編集。この時点でgemはrailsのみ。
# frozen_string_literal: true
source "https://rubygems.org"
git_source(:github) {|repo_name| "https://github.com/#{repo_name}" }
gem 'rails'
③ Gemfile.lockは空で作成
3. コンテナの作成
① docker-compose run web rails new . --force --database=mysql
を実行するとdocker-compose.ymlの内容でコンテナが作成されます。
※ docker-compose.ymlが存在する階層でなければdocker-composeコマンドは実行できないので注意
コマンド解説
docker-compose run web
:指定したコンテナで後に続くコマンドを実行
rails new .
:Railsプロジェクトの新規作成
-- force
オプション:上書きコピー指定
--database=mysql
オプション:使用データベースにMySQLを指定
コマンド実行後のディレクトリ構成がこんな感じになってればOK。
Railsプロジェクトがローカルに作成されていることがわかります。
root
├── Dockerfile
├── docker-compose.yml
├── mysql-confd
│ └── default_authentication.cnf
└── src
├── Gemfile
├── Gemfile.lock
├── README.md
├── Rakefile
├── app
├── bin
├── config
├── config.ru
├── db
├── lib
├── log
├── package.json
├── public
├── storage
├── test
├── tmp
└── vendor
docker-compose ps
を実行すると起動しているDBコンテナのみが表示されます。
Name Command State Ports
------------------------------------------------------------------------
touring_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
docker ps -a
を実行すればrails用のコンテナも作成されていることが確認できます。
次にGemfileを開くと最初に作成した内容が①のコマンド実行により上書きされているのがわかります。
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.5.1'
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.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]
② この状態でdocker-compose build
するとDockerfileの内容が実行され、このGemfileの内容でGemのインストールや作成されたsrc配下がコンテナへとコピーされます。(最初に作ったGemfileは①で行われる初回のDockerfileのビルドを成功させるためのダミー的な扱いです。)
以降にGemを追加したい場合は、
- Gemfile修正
-
docker-compose build
の実行
を繰り返すだけです。
4. データベースの設定
① src/config/database.ymlに接続情報を設定
passwordとhostを以下の内容に書き換えます。
- password:docker-compose.ymlに設定したmysqlのルートユーザーのパスワード
- host:docker-compose.ymlに設定したMySQLコンテナ名
default: &default
adapter: mysql2
encoding: utf8
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
username: root
password: password
host: db
② docker-compose run web rake db:create
を実行してDB作成
5. 画面起動確認
① docker-compose up -d
を実行してコンテナ起動
docker-compose ps
を実行すると起動しているRailsコンテナとDBコンテナが表示されます。StateがUpになっているので両方のコンテナが正しく起動された状態です。
Name Command State Ports
-------------------------------------------------------------------------------
touring_db_1 docker-entrypoint.sh mysqld Up 3306/tcp, 33060/tcp
touring_web_1 bundle exec rails s -p 300 ... Up 0.0.0.0:3000->3000/tcp
この画面が表示されればひとまず完了!