Rails on Docker for Heroku

プロトタイプ早く作成したい用手順メモ
最適解ではないので逐次更新

## 前提
- Mac
- Homebrew入れている
  - docker入れている
  - gsedを入れている
  - heroku cliを入れている

## アウトライン
- リポジトリをリモートで作成・クローン
- 初期ファイルの作成
- プロジェクト作成
- gitプッシュ・herokuプッシュ
- URL変更・確認

```docker:docker-compose.yml
version: '3'
services:
  db:
    env_file: ./.env
    image: postgres
    ports:
      - "15432:5432"
    environment:
      - "DB_HOST=${DB_HOST}"
      - "DB_USERNAME=${DB_USERNAME}"
    volumes:
      - db-data:/var/lib/postgresql/data
  web:
    env_file: ./.env
    build: .
    volumes:
      - .:/pop-books
      - tmp-data:/pop-books/tmp
      - public-data:/pop-books/public
    ports:
      - "3000:3000"
    environment:
      - "RAILS_ENV=${RAILS_ENV}"
    depends_on:
      - db
volumes:
  db-data:
    external: true
  tmp-data:
    external: true
  public-data:
    external: true
```

```Dockerfile:Dockerfile
FROM ruby:2.5.4
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs graphviz git less vim tig
RUN curl -sL https://deb.nodesource.com/setup_6.x | bash - && apt-get install -y nodejs
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - \
    && echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list \
    && apt-get update && apt-get install -y yarn
RUN mkdir /プロジェクト名
WORKDIR /プロジェクト名
COPY Gemfile /プロジェクト名/Gemfile
COPY Gemfile.lock /プロジェクト名/Gemfile.lock
RUN bundle install
COPY . /プロジェクト名

RUN mkdir -p tmp/sockets
RUN mkdir -p tmp/pids

EXPOSE 3000
CMD RAILS_ENV=${RAILS_ENV} bundle exec pumactl start

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

ruby '2.5.4'

# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
gem 'rails', '~> 6.0.0.beta3'
# Use postgresql as the database for Active Record
gem 'pg', '>= 0.18', '< 2.0'
# Use Puma as the app server
gem 'puma', '~> 3.11'
# Use SCSS for stylesheets
gem 'sass-rails', '~> 5.0'
# Transpile app-like JavaScript. Read more: https://github.com/rails/webpacker
gem 'webpacker', '>= 4.0.0.rc.3'
# 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 Active Model has_secure_password
# gem 'bcrypt', '~> 3.1.7'

# Use Active Storage variant
# gem 'image_processing', '~> 1.2'

# Reduces boot times through caching; required in config/boot.rb
gem 'bootsnap', '>= 1.4.1', require: false

# Use all
gem 'kaminari'
gem 'fog-aws'
gem 'poltergeist'
gem 'devise'
gem 'omniauth'
gem 'omniauth-facebook'
gem 'ransack'
gem 'migration_comments'

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]

```
```:.env
DB_HOST=db
DB_USERNAME=postgres
RAILS_ENV=development
```

```
# 一連を実行する

touch Gemfile.lock

# rails newしたファイルをローカルに同期するため作成
docker volume create --name=db-data
docker volume create --name=tmp-data
docker volume create --name=public-data

docker-compose run --rm web rails new . --force --database=postgresql

# ボリュームの指定を削除
gsed -ie '11,12d' docker-compose.yml
gsed -ie '14,17d' docker-compose.yml
gsed -ie '20,27d' docker-compose.yml
rm docker-compose.ymle

# データベースの指定を追加
gsed -ie '20i \  host: db' config/database.yml
gsed -ie '21i \  username: postgres' config/database.yml
gsed -ie '22i \  password:' config/database.yml
rm config/database.ymle

# オートリロード設定
sed -ie '/EventedFileUpdateChecker/s/^/\  #/g' config/environments/development.rb
sed -ie '/EventedFileUpdateChecker/a \  config.file_watcher = ActiveSupport::FileUpdateChecker'
rm config/environments/development.rb

docker-compose build
docker system prune -f

docker-compose up -d
docker-compose run --rm web rake db:create
docker-compose down

heroku container:login
heroku create
gsed -ie '13i \    config.hosts << "ドメイン名.herokuapp.com"' config/application.rb
rm config/application.rbe
git commit -m "[feat]初期設定"
git push origin master
heroku container:push web
heroku git:remote -a アプリ名(heroku apps:info)
heroku addons:create heroku-postgresql:hobby-dev
heroku container:release web

```
```:Rakefile
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

require_relative 'config/application'

Rails.application.load_tasks

task 'after_migrate' do
  sh 'bin/rake erd attributes=foreign_keys,primary_keys,content,timestamp sort=false filename=erd filetype=pdf'
end

Rake::Task['db:migrate'].enhance do
  Rake::Task['after_migrate'].invoke
end
```

- heroku管理画面からURLを変更
https://dashboard.heroku.com/apps/アプリ名/settings

- アクセス

## 雑感
- 最初にGemfileに色々指定してもrails newするとデフォルト(?)のもので上書きされている
- ボリューム指定をしないとプロジェクトがローカルに生成されない
- ボリューム指定を削除しないとherokuにはボリューム機能がないのデプロイに失敗する
- APIモードにしたい時はrails new時に--apiを追記する
- rails newした後にイメージを作成する必要がある