手軽にRails + docker 開発環境テンプレ

rails + dockerの開発環境を作る機会があったので今後簡単に作れる様にテンプレを作成しました。
ローカル環境構築とかdockerとか使ってやってみたいけど、よくわからないという方々も参考にしていただければ、、、。
CircleCIで自動テストとherokuにデプロイまでやります。
自動デプロイまで行けたらなぁ〜

では早速やっていきましょう!

必要なファイルを作成する

プロジェクトを始めるのに必要なファイルを作っていきます。
必要なファイルは以下の6つ。

  • Dockerfile
  • docker-compose.yml
  • Gemfile
  • Gemfile.lock
  • .env
  • Dockerfile-MySQL

1つずつ作って行きます。

Dockerfile

Dockerfileとは?

Docker上で動作させるコンテナの構成情報を記述するためのファイルです。
Dockerとはなにか?Dockerfileとはなにか?

Dockerfileについてもっと知りたい方は引用元記事を読んでみてください。

Dockerfileの内容

FROM ruby:2.6.3
RUN curl -sL https://deb.nodesource.com/setup_10.x | bash && apt-get update -qq && \
    apt-get install -y build-essential libpq-dev nodejs

RUN gem install bundler
ENV APP_HOME /paper_plane
RUN mkdir -p $APP_HOME
WORKDIR $APP_HOME
ADD . $APP_HOME
ADD Gemfile Gemfile
ADD Gemfile.lock Gemfile.lock
RUN bundle install

上記ファイルのコマンドはざっとこんな感じです。

コマンド意味
FROMベースとなるイメージ
RUNdocker buildする時に実行するコマンド
ENV環境変数の設定
ADDホスト→コンテナへファイルコピーする
WORKDIRワーキングディレクトリ

こういうのもあります。

コマンド意味
CMDdocker run の時に実行するコマンド
ENTRYPOINTdocker run の時に実行するコマンド

他にもいろいろあるので気になるか方はこちらへ
Dockerfileによるビルド

Dockerfileはこれで出来上がりです。
paper_planeのところに自分のアプリ名を入れましょう。

docker-compose.yml

次にdocker-compose.ymlを作成します。

docker-compose.ymlとは

拡張子がYAMLの、アプリケーションを動かすための処理を記述しているファイルです。
docker-compose.ymlの書き方について解説してみた

docker-compose.ymlの内容

version: '3.4'
services:
  db:
    image: mysql:5.7
    environment:
      TZ: Asia/Tokyo
    build:
      context : .
      dockerfile: Dockerfile-MySQL
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci
    container_name: 'paper_plane_db'
    volumes:
      - ./db/mysql/volumes:/var/lib/mysql:cached
    ports:
      - "3312:3306"
    env_file: .env
    user: mysql
  web:
    container_name: 'paper_plane_web'
    environment:
      TZ: Asia/Tokyo
    build:
      context : .
      dockerfile: Dockerfile
    command: bash -c "rm -rf /paper_plane/tmp/pids/server.pid && bundle exec rake db:create && bundle exec rails s -p 3007 -b '0.0.0.0'"
    volumes:
      - .:/paper_plane:cached
    ports:
      - "3007:3007"
    env_file: .env
    privileged: true
    depends_on:
      - db
    tty: true
    stdin_open: true

volumes:
  redis-data:
    driver: local

docker-compose.ymlの各コマンドの意味はこんな感じです。

services

servicesは各コンテナをサービスとして定義します。
今回はdbwebです。任意で好きなのに変えられます。

image

imageはコンテナを実行時に元となるイメージを指定します.
dbmysql:5.7を指定しています。

environment

environmentは環境変数の設定です。
TZをAsia/Tokyoにして日本時間に対応させます。

build

buildは構築時に使用するオプションを指定します。
contextDockerfileのディレクトリのパスや GitのURLを指定します。
今回はDockerfileはプロジェクト配下にあるので、context : .となってます。
dockerfileDockerfileの代わりに読み込むものを指定します。

command

commandはデフォルトのコマンドを上書きするので、実行したいコマンドを入れます。

container_name

container_nameは好きなコンテナ名を入れられます。

volumes

volumesはパスをボリュームとしてマウントします。
なのでdocker上だけでなくローカルにもファイルを作成できます。

port

portでポート番号を指定できます。

env_file

env_fileは指定したファイルに記載してある環境変数を追加します。
今回はenv_file: .envのように.envファイルに記載されている環境変数を追加します。

user

userはdockerを実行するユーザーを指定できます。

privileged

privilegedを指定しないとsystemctlコマンドが使えないみたいです。

depends_on

depends_onはサービス間の依存関係を指定します。
docker-compose upを実行すると、依存関係のある順番に従って実行されます
今回はdbwebの順に実行されます。

その他

tty: truestdin_open: trueはbyebugを使うために設定します。

ざっとこのような感じです。

参考:
Compose ファイル・リファレンス
Docker Compose で複数コンテナ構築&管理
Dockerで実行ユーザーとグループを指定する

こちらも`paper_plane`は自分のアプリ名に変えてください。

GemfileとGemfile.lock

続いてGemfileとGemfile.lockです。

GemfileはRailsでアプリケーション開発している方はよくみてますよね?

Gemfileに下記を記述します。

# frozen_string_literal: true

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby '2.6.3'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 5.2.3'

そしてGemfile.lcokも作成します。
しかし、中身は何も記述しない状態のままで問題ありません。

.env

残すところあと2つです。
.envファイルを作成します。環境変数などを記述するファイルで、githubの管理下から普通は外します。

.envファイルの内容
.env

MYSQL_USER=root
MYSQL_PASSWORD=password
MYSQL_ROOT_PASSWORD=password
MYSQL_HOST=db
MYSQL_DATABASE=paper_plane_db

今回はMySQLの環境変数を入れておきます。

こちらも`paper_plane`は自分のアプリ名に変えてください。

Dockerfile-MySQL

最後にDockerfile-MySQLです。

FROM mysql:5.7
RUN { \
    echo '[mysql]'; \
    echo 'default-character-set=utf8mb4'; \
    echo '[mysqld]'; \
    echo 'character-set-server=utf8mb4'; \
    echo 'collation-server=utf8mb4_general_ci'; \
    echo 'init-connect = SET NAMES utf8mb4'; \
    echo 'innodb-file-format=barracuda'; \
    echo 'innodb_file_format_max=barracuda'; \
    echo '[client]'; \
    echo 'default-character-set=utf8mb4'; \
} > /etc/mysql/conf.d/charset.cnf

普通にMySQL使ってると、絵文字が使えなかったりして辛い時がある。これは文字コードをutf8mb4にすることで解決できる。
データベースのutf8mb4対応

これで完成です。
現状こうなっていればOKです。
ls

railsアプリを作成する

6つのファイルが揃ったのでrailsアプリを作成します。
docker-compose run --rm web bundle exec rails new . --force --database=mysql --skip-bundle
上記コマンドを実行します。
railsfiile

このような感じで実行されていって、、、

editor
このように作成されます!

database.ymlを書き換える

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: utf8mb4
  charset: utf8mb4
  collation: utf8mb4_unicode_ci
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: <%= ENV['MYSQL_USER'] %>
  password: <%= ENV['MYSQL_ROOT_PASSWORD'] %>
  host: db

development:
  <<: *default
  database: paper_plane_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: paper_plane_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: paper_plane_production
  username: paper_plane
  password: <%= ENV['PAPER_PLANE_DATABASE_PASSWORD'] %>
コメントは消して良いです。

Gemfileに追加する

Gemfileを追加します。
基本、自分がアプリを作成する時に入れるテンプレみたいなものなので好きにカスタマイズしてください。

source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby '2.6.3'
gem 'rails', '~> 5.2.4', '>= 5.2.4.1'
gem 'mysql2', '>= 0.4.4', '< 0.6.0'
gem 'puma', '~> 3.11'
gem 'sass-rails', '~> 5.0'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.2'
gem 'turbolinks', '~> 5'
gem 'jbuilder', '~> 2.5'
gem 'bootsnap', '>= 1.1.0', require: false

gem 'ridgepole'
# .env
gem 'dotenv-rails'
# bootstrap 4
gem 'bootstrap', '~> 4.3.1'
gem 'jquery-rails'
gem 'jquery-ui-rails'
gem 'mini_racer'
gem 'sprockets-rails'
# font awesome 5
gem 'font-awesome-rails'
group :development, :test do
  gem 'byebug', platforms: [:mri, :mingw, :x64_mingw]
  gem 'factory_bot_rails'
  gem 'rspec_junit_formatter', require: false
  gem 'rubocop', require: false
  gem 'rubocop-performance', require: false
  gem 'rubocop-rails', require: false
  gem 'rubocop-rspec', require: false
  gem 'rails_best_practices', require: false
  gem 'brakeman', require: false
end
group :development do
  gem 'web-console', '>= 3.3.0'
  gem 'listen', '>= 3.0.5', '< 3.2'
  gem 'spring'
  gem 'spring-commands-rspec'
  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 'rspec-rails', '~> 3.8.0'
  gem 'selenium-webdriver'
  # Easy installation and use of chromedriver to run system tests with Chrome
  gem 'webdrivers', '~> 3.0'
  gem 'database_cleaner'
end
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
# gem 'active_admin_flat_skin'
# gem 'activeadmin'
gem 'carrierwave', '~> 1.0'
gem 'devise'
gem 'devise-i18n'
gem 'faker'
gem 'enum_help'

ridgepole凄い便利だったので入れてます。

docker-compose build

docker-compose buildを実行するのですが、このまま実行するとほぼ確実に
build miss
こうなるのでまずdocker-compose run --rm web bundle updateを実行します。
そしてdocker-compose build

docker-compose build
buildできましたね!

docker-compose upを実行して、
localhost:3007にアクセスします。

Yay! You’re on Rails!

いけましたね!

次回はRspecと静的解析の設定をします。

コメント

  1. eskort bayan より:

    Thanks a lot for the blog. Really thank you! Fantastic. Stefan Crissey