高木のブログ

Heroku + Rails + MySQL + APIモード + Docker

2020/10/31

タイトルのまんま。

バージョン

  • Ruby: 2.7.2
  • Rails: 6.0.3.4
  • MySQL: 8.0.22
  • Docker: 19.03.13
  • docker-compose: 1.27.4

手順

1. アプリのディレクトリ作って移動

$ mkdir app_name
$ cd app_name

2. 各種ファイル作成

  • Dockerfile
  • docker-compose.yml
  • entrypoint.sh
  • Gemfile
  • Gemfile.lock
Dockerfile
FROM ruby:2.7.2
ENV LANG C.UTF-8

RUN apt update -qq && apt install -y mariadb-client

WORKDIR /app_name
COPY Gemfile /app_name/Gemfile
COPY Gemfile.lock /app_name/Gemfile.lock
RUN bundle install
COPY . /app_name

COPY entrypoint.sh /usr/bin/
RUN chmod +x /usr/bin/entrypoint.sh
ENTRYPOINT ["entrypoint.sh"]
EXPOSE 3000

CMD ["rails", "server", "-b", "0.0.0.0"]
docker-compose.yml
version: '3'
services:
  web:
    build: .
    command: bash -c "rm -f tmp/pids/server.pid && bundle exec rails s -p 3000 -b '0.0.0.0'"
    volumes:
      - .:/app_name
    ports:
      - "3000:3000"
    depends_on:
      - db
    stdin_open: true
    tty: true
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - '3306:3306'
    command: --default-authentication-plugin=mysql_native_password
    volumes:
      - mysql_vol:/var/lib/mysql
volumes:
  mysql_vol:
    driver: local
entrypoint.sh
#!/bin/bash
set -e

# Remove a potentially pre-existing server.pid for Rails.
rm -f /myapp/tmp/pids/server.pid

# Then exec the container's main process (what's set as CMD in the Dockerfile).
exec "$@"
Gemfile
source 'https://rubygems.org'
gem 'rails', '~>6'
$ touch Gemfile.lock

Gemfile.lockの中身は空で良い。

3. Railsアプリを作成

$ docker-compose run --rm web rails new . --force --no-deps --api --database=mysql --skip-test

別でRSpecを入れるので、--skip-testを付けている。

4. config/database.ymlを変更

config/database.yml
default: &default
  adapter: mysql2
  encoding: utf8mb4
  pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
  username: root
  password:
  host: <%= ENV.fetch("DB_HOSTS") { 'db' } %>

development:
  <<: *default
  database: app_name_development

test:
  <<: *default
  database: app_name_test

production:
  <<: *default
  url: <%= ENV['DATABASE_URL'] %>

5. Heroku上にアプリを作成

$ heroku create app_name-20201027
Creating ⬢ app_name-20201027... done
https://app_name-20201027.herokuapp.com/ | https://git.heroku.com/app_name-20201027.git

6. HerokuでMySQLを使えるようにする

HerokuでMySQLを使うためにClearDBのアドオンを追加

$ heroku addons:create cleardb:ignite
Creating cleardb:ignite on ⬢ app_name-20201027... free
Created cleardb-deep-10722 as CLEARDB_DATABASE_URL
Use heroku addons:docs cleardb to view documentation

igniteは無料プラン

$ heroku config:get CLEARDB_DATABASE_URL
mysql://{ユーザー名}:{パスワード}@{ホスト名}/{データベース名}?reconnect=true

CLEARDB_DATABASE_URLにDB接続情報がセットされている

DATABASE_URLにMySQLのURLをセットする

$ heroku config:add DATABASE_URL=mysql2://{ユーザー名}:{パスワード}@{ホスト名}/{データベース名}?reconnect=true

mysql://ではなくmysql2://になっているので注意。

7. HerokuにRailsアプリをデプロイする

$ git push heroku master

その他

ローカルから本番DBに接続する方法

$ docker-compose run --rm web mysql -h{ホスト名} -u{ユーザー名} -p{パスワード} {データベース名}

参考


Pixela