RubyをインストールせずにDockerでRails環境を構築する

（20/03/10 19:00 Rails6バージョン追記）

# はじめに
数年に一度訪れるPCの入れ替えに伴い、
毎回Ruby(rbenvとか)をローカルPCにインストールしたくないなぁと思ったのがきっかけです。

# 環境
macOS Mojava 10.14.6
Docker 19.03.5
Compose 1.25.4

# Dockerを使ってのRails環境構築手順
適当なプロジェクトディレクトリを作成し、Dockerfileを配置します。

```
$ mkdir project_name
$ cd project_name
```

Rails5バージョン

```docker:Dockerfile
FROM ruby:2.6.3
ENV LANG C.UTF-8
ENV APP_ROOT /usr/src/app
RUN apt-get update -qq && \
    apt-get install -y vim nodejs \
                       mariadb-client \
                       --no-install-recommends && \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* /tmp/* /var/tmp/*
WORKDIR $APP_ROOT
COPY Gemfile Gemfile.lock $APP_ROOT/
RUN \
  echo 'gem: --no-document' >> ~/.gemrc && \
  cp ~/.gemrc /etc/gemrc && \
  chmod uog+r /etc/gemrc && \
  bundle config --global build.nokogiri --use-system-libraries && \
  bundle config --global jobs 4 && \
  bundle install && \
  rm -rf ~/.gem
COPY . $APP_ROOT
```

Rails6バージョン

```docker:Dockerfile
FROM ruby:2.7.0
ENV LANG C.UTF-8
ENV DEBCONF_NOWARNINGS yes
ENV YARN_VERSION 1.22.4
ENV APP_ROOT /usr/src/app
RUN apt-get update -qq && \
    apt-get install -y vim nodejs \
                       mariadb-client \
                       --no-install-recommends && \
    rm -rf /var/lib/apt/lists/* /var/cache/apt/archives/* /tmp/* /var/tmp/*
WORKDIR $APP_ROOT
COPY Gemfile Gemfile.lock $APP_ROOT/

RUN curl -L --compressed "https://yarnpkg.com/downloads/$YARN_VERSION/yarn-v$YARN_VERSION.tar.gz" > /tmp/yarn.tar.gz && \
  tar -xzf /tmp/yarn.tar.gz -C /opt && \
  ln -s /opt/yarn-v$YARN_VERSION/bin/yarn /usr/local/bin/yarn && \
  ln -s /opt/yarn-v$YARN_VERSION/bin/yarnpkg /usr/local/bin/yarnpkg && \
  rm /tmp/yarn.tar.gz

RUN \
  echo 'gem: --no-document' >> ~/.gemrc && \
  cp ~/.gemrc /etc/gemrc && \
  chmod uog+r /etc/gemrc && \
  bundle config --global build.nokogiri --use-system-libraries && \
  bundle config --global jobs 4 && \
  bundle install && \
  rm -rf ~/.gem
COPY . $APP_ROOT
```

Dockerfileは諸所こだわりがあると思うので各々の書き方でいいと思います。

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

```yaml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    environment:
      RAILS_ENV: development
      TZ: Asia/Tokyo
    ports:
      - '3000:3000'
    volumes:
      - .:/usr/src/app
    depends_on:
      - database
  database:
    image: mysql:8.0.14
    environment:
       MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    volumes:
      - mysql-data:/var/lib/mysql
    command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_bin --default-authentication-plugin=mysql_native_password
volumes:
  mysql-data:
    driver: local
```
Composeファイルも諸所こだわりがあると思いますので各々の書き方でおまかせします。
ポイントとしては

- WebサーバにTimezoneを設定した
- MySQL8.0からの認証方式`caching_sha2_password`対応

最後にGemfileと**空のGemfile.lock**ファイルを作成します。

```rb:Gemfile
source 'https://rubygems.org'
gem 'rails', '5.2.3'
```

これで準備が整いましたのでビルドしてイメージを作成します。

```
$ docker-compose build
```

イメージ作成後はrailsの雛形をnewコマンドで作成します。

```
$ docker-compose run --rm web rails new . --skip-test --skip-bundle --skip-turbolinks --skip-action-mailer --skip-coffee --skip-action-cable --skip-active-storage --database=mysql
```
`Overwrite /usr/src/app/Gemfile? (enter "h" for help) [Ynaqdhm]`
GemfileのConflictが検知されますが迷わず`Y`と入力しましょう！


railsの雛形が出来たのでデフォルトで設定されているDB情報を書き換えて上げます。

```diff:database.yml
default: &default
  adapter: mysql2
  encoding: utf8
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password: password
- host: localhost
+ host: database
```

Dockerfileの末尾にrailsサーバが起動するように一行加えます。

```docker:Dockerfile
CMD ["rails", "server", "-b", "0.0.0.0"]
```

最後にビルドを行い、DB作成(Rails6の場合はwebpackインストール)後にdocker起動したら終わりです。

```
$ docker-compose build
$ docker-compose run --rm web rails db:create

# Rails6以降はwebpackのインストールも実行
$ docker-compose run --rm web rails webpacker:install

$ docker-compose up -d
```

<img width="741" alt="hello_rails.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61433/172ce1e9-d821-a702-27fc-20abf238ba50.png">


# 参考記事
[RailsアプリをDockerで開発するための手順](https://qiita.com/togana/items/30b22fc39fe6f7a188ec)