Ruby on railsのDockerイメージ作成(再)

## tl;dr
下記投稿で一度作成してみましたが、コードがコンテナ内にあり、コードの変更がやり難い。
https://qiita.com/reflet/items/efb624996f8876f8167e

そのため、他のやり方がないか再チャレンジしてみる。

**[実現したいこと]**

- railsのコードを`srcフォルダに配置`し、railsコンテナに取り込む
- DockerHubに登録し、Dockerイメージが`自動ビルド`されるように構成する

## ミドルウェア構成
下記の構成で起動するように作成します。

- **Railsコンテナ (ruby 2.5 + ruby on rails 5.1)**
- **MySQLコンテナ (mysql5.7)**

## ファイル構成
ファイルの構成は以下のようになります。

```:ファイル構造
app-rails5.2
 ├ src               ・・・ railsのプログラムの格納先
 │  └ Gemfile
 │
 ├ .gitignore
 ├ docker-compose.yml
 ├ Dockerfile
 └ README.md
```

## Ruby on Railsのインストール
※ DockerHubに登録するので、Docker関連ファイルは、ルートフォルダに配置します。

### srcフォルダ作成
空のフォルダを作成します。
※最終的にはこのフォルダにrailsのプログラムコードが格納されます。

```bash:ターミナル
$ mkdir src
```

### Gemfile作成
下記の内容でGemfileファイルを作成する。

```ruby:src/Gemfile
source 'https://rubygems.org'
gem 'rails', '~> 5.2.0'
```

### Dockerfile作成
下記の内容でDockerfileファイルを作成する。

```dockerfile:Dockefile
FROM ruby:2.5

ENV LANG C.UTF-8
ENV WORKSPACE=/usr/local/src

# install bundler.
RUN apt-get update && \
    apt-get install -y vim less && \
    apt-get install -y build-essential libpq-dev nodejs && \
    gem install bundler && \
    apt-get clean && \
    rm -r /var/lib/apt/lists/*

# create user and group.
RUN groupadd -r --gid 1000 rails && \
    useradd -m -r --uid 1000 --gid 1000 rails

# create directory.
RUN mkdir -p $WORKSPACE $BUNDLE_APP_CONFIG && \
    chown -R rails:rails $WORKSPACE && \
    chown -R rails:rails $BUNDLE_APP_CONFIG

USER rails
WORKDIR $WORKSPACE

# install ruby on rails.
ADD --chown=rails:rails src $WORKSPACE
RUN bundle install
```

### docker-compose.yml作成
下記の内容でdocker-compose.ymlファイルを作成する。

```yml:docker-compose.yml
version: '2'
services:
  rails:
    build: .
    image: my/rails5.2
    container_name: 'rails'
    ports:
      - "80:3000"
    environment:
      APP_DATABASE: 'example'
      APP_DATABASE_USER: 'app'
      APP_DATABASE_PASSWORD: 'development'
    volumes:
      - rails-data:/usr/local/src
    depends_on:
      - mysql

  mysql:
    image: mysql:5.7
    container_name: 'mysql'
    environment:
      MYSQL_ROOT_PASSWORD: 'mysql'
      MYSQL_DATABASE: 'example'
      MYSQL_USER: 'app'
      MYSQL_PASSWORD: 'development'
    ports:
      - '3306:3306'
    volumes:
      - mysql-data:/var/lib/mysql

volumes:
  rails-data:
    driver_opts:
      type: none
      device: ${PWD}/src/
      o: bind
  mysql-data:
    driver: local
```

### Dockerイメージ構築
Dockerイメージを作成します。

```bash:ターミナル
$ docker-compose build
```

これで、railsのインストールは完了

## ruby on railsのプロジェクト構築
### スケルトン・アプリ作成
docker-compose run コマンドを使い新しい Rails スケルトン・アプリを作成します。

```bash:ターミナル
# This can be changed with the --database option with allowed values: 
#   mysql, oracle, postgresql, sqlite3, frontbase, ibm_db, sqlserver, 
#   jdbcmysql, jdbcsqlite3, jdbcpostgresql, jdbc.
$ docker-compose run rails rails new . --force --database=mysql --skip-bundle
```


### データベース設定を修正
Docker環境にあうように設定ファイルを修正する。

```yml:src/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 } %>
  database: <%= ENV['APP_DATABASE'] %>
  username: <%= ENV['APP_DATABASE_USER'] %>
  password: <%= ENV['APP_DATABASE_PASSWORD'] %>

development:
  <<: *default
  host: mysql

# 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
  host: mysql

# 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
  host: mysql
```

### Dockerfileファイル修正
作成したスケルトン・アプリをrailsコンテナに取り込みます。
また、bundle installなどの初期処理も合わせて実行します。
さらに、railsのサーバが起動するようコマンドの設定を追加します。

```dockerfile:Dockerfile
FROM ruby:2.5

ENV LANG C.UTF-8
ENV WORKSPACE=/usr/local/src

　・
　・
　・

# install ruby on rails.
ADD --chown=rails:rails src $WORKSPACE
RUN bundle install

# add command.                    <- ここから下を追加する！！
EXPOSE  3000
CMD ["rails", "server", "-b", "0.0.0.0"]
```

### Dockerイメージ再構築
Dockerfileの修正した内容を反映するため、buildコマンドを実行して、Dockerイメージを作り直す。

```bash:ターミナル
$ docker-compose build
```

## 起動してみる
Dockerコンテナを起動してみる。

```bash:ターミナル
$ docker-compose up -d
```
問題なくブラウザで閲覧できました。
![rails.png](https://qiita-image-store.s3.amazonaws.com/0/142279/59afb606-9f22-545b-7736-62e3de26b593.png)

## IDEでプロジェクト登録
IntelliJにプロジェクト登録してみました。
![intellij.png](https://qiita-image-store.s3.amazonaws.com/0/142279/76840970-0faf-0be6-4496-34b5fe0f2c91.png)

これでコードの修正ができるようになりました。

## ruby on railsの各種操作
railsコマンドで操作できる各種コマンドを実行したい場合は、下記のように実行できます。

```bash:ターミナル
# Gemfileを変更した時のりライブラリ更新
$ docker-compose exec rails bundle update

# データベース作成
$ docker-compose exec rails rake db:create

# マイグレーション実行
$ docker-compose exec rails rake db:migrate

# アセットのプリコンパイルを行う
$ docker-compose exec rails rake assets:precompile
```

## DockerHub登録
最後に、今回作成したDockerfileをDockerHubに登録する。

作成したコードは下記`github`に登録しました。
https://github.com/reflet/docker-rails5.2/blob/master/README.md

上記githubのリポジトリを`DockerHub`に登録して自動ビルドする。
![dockerhub.png](https://qiita-image-store.s3.amazonaws.com/0/142279/b7b6738b-4e7c-d497-6e72-491fabbc0e1d.png)
※ 登録したDockerイメージ： https://hub.docker.com/r/reflet/docker-rails5.2/

以上です。

## 参考サイト
- [Ruby on railsのDockerイメージを作成してみる](https://qiita.com/reflet/items/efb624996f8876f8167e)
- [クイックスタート・ガイド：Docker Compose と Rails](http://docs.docker.jp/compose/rails.html)
- [Ruby on Windows Guides](http://rubyonwindowsguides.github.io/book/ch03-01.html)
- [railsをdockerで動かしたい場合の構成はどうするべきか](https://qiita.com/k-shogo/items/592e243f9763d0c3b10a)
- [github/gitignore/Rails.gitignore](https://github.com/github/gitignore/blob/master/Rails.gitignore)