概要
Heroku x Ruby on Rails x PostgreSQL
の構成でサービスを運用する機会があったのでそのメモ
Components
- Ruby 2.5.1
- Rails 5.2.1
- Postgres 10.4
- DockerCE 18.06
localの構築
railsの用意
Railsもrubyもローカルに仕込みたくなかったのでDockerfileで片付けた。
$ cat <<EOL | docker build -t rails - FROM ruby:2.5-alpine ENV LANG C.UTF-8 WORKDIR /app RUN set -x\ && apk add --no-cache --update \ libxml2-dev \ libxslt-dev \ libstdc++ \ tzdata \ nodejs \ nodejs-npm \ build-base \ linux-headers \ ca-certificates \ postgresql-dev \ mysql-client \ mysql-dev \ git \ curl-dev \ && gem install bundler rails\ && npm install -g yarn EXPOSE 3000 EOL $ docker run -v `pwd`:/app rails new . --database=postgresql
or
$ docker run -it -v `pwd`:/app yohgi/railscmd rails new . --database=postgresql
docker-composeの用意
docker-composeでざっくり動くものを構築する
まずは Dockerfile
の記述
FROM ruby:2.5-alpine ENV LANG C.UTF-8 WORKDIR /app COPY . . RUN apk add --no-cache --update \ libxml2-dev \ libxslt-dev \ libstdc++ \ tzdata \ nodejs \ nodejs-npm \ build-base \ linux-headers \ ca-certificates \ postgresql-dev \ protobuf-dev \ less \ && gem install bundler \ && bundle install \ && npm install -g yarn \ && yarn install #XXX: 本番でこのイメージを用いる場合はユーザーを作成する。 # ローカルで色々考えたくないのでrootで起動 EXPOSE 3000
次に docker-compose.yaml
の記述
version: "3" services: web: build: . restart: always tty: true stdin_open: true depends_on: - db ports: - 3000:3000 volumes: - './:/app:cached' environment: - RAILS_ENV=development - DATABASE_HOST=db - DATABASE_USER=postgres - DATABASE_PASS= command: ash -c "rm -f /app/tmp/pids/server.pid; bundle exec rails s -p 3000 -b '0.0.0.0'" db: image: postgres:10.4-alpine volumes: - ./postgres:/var/lib/postgres ports: - 15432:5432
最後に config/database.yml
を編集。
それぞれ、 development
と test
環境はdocker-composeへ、 production
環境はHerokuへ対応もする。
default: &default adapter: postgresql encoding: unicode pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: <%= ENV['DATABASE_USER'] %> ? password development: <<: *default database: myapp_development host: <%= ENV['DATABASE_URL'] || '127.0.0.1' %> test: <<: *default database: myapp_test host: <%= ENV['DATABASE_URL'] || '127.0.0.1' %> production: reconnect: false url: <%= ENV['DATABASE_URL'] %>
起動確認。
repl(pry)を使いたいのでattachするために docker-compose run
する。
docker-compose run --rm web bundle exec rails db:create db:migrate docker-compose run --service-ports web
Herokuの操作
アドオンの導入
各アドオンはクレカ登録が必要
Databaseの導入
$ heroku addons:create heroku-postgresql
ちなみにMySQLをHerokuへで使う場合は以下
$ heroku addons:create cleardb:ignite
ログ監視のためにPapertrailを導入
$ heroku addons:create papertrail
アプリケーションの性能監視のためにNewRelicを導入
$ heroku addons:create newrelic:wayne
Herokuの設定変更
環境変数へタイムゾーンを登録
$ heroku config:add TZ=Asia/Tokyo
Procfileの作成
ルートディレクトリへ以下のように Procfile
ファイルを追加編集
release
を用いることで db:migrate
を実行してからデプロイする事が可能。
release: bundle exec rails db:migrate web: bundle exec rails server -p $PORT -e $RAILS_ENV
独自ドメインの設定
$7以上のプランに入ってないと設定不可だった気がする。
HerokuでのApexドメインについて
ApexドメインはHerokuでは扱いづらい ことに注意。
HerokuはCNAMEを登録して独自ドメインを登録するため、CNAMEを使用できないApexドメインが使用できない。
使用するためにはANAMEが使用可能なドメイン管理サイトで行う必要がある。
例えばお名前ドットコムで取得したドメインをPointDNSへ委譲するなど。
今回はサブドメインを使用する。
e.g. www.example.com
独自ドメインの設定
- 設定するドメインをHerokuへ登録
Herokuコンソール
>Settings
>Domains and certificates
>Add domain
- 表示された
DNS Target
をメモる - ドメイン管理サイトで登録したドメインのCNAMEへ
DNS Target
を登録する。 - 1日ぐらい経つとLet's Enctyptの証明書が発行される
HSTSの設定
http > httpsのリダイレクト設定。
Railsのコンフィグを書き換えるだけで有効にできる。
config/environments/production.rb
+ config.force_ssl = true
設定したドメインでのみアクセスを受け付ける(受け付けない)
魔実装する。
例えば application_controller.rb
で production
環境だけ特定ドメインだけ受け付けるなど...
魔実装の途中で「herokuのドメインを防ぐ理由ってなんだっけ?」ってなってやめた。
CD(継続的デプロイメント)の設定
- GitHubの認証を行う
Herokuコンソール
>Deploy
>Deployment method
>GitHub
- リポジトリの選択
- ブランチの選択
以降選択したブランチに変更がかかるたびに自動的にデプロイが行われる。
release
ブランチを切り、リリースのたびに master
から release
へPRを作成してマージするようなフローが理想的?
まとめ
以上、Herokuについてでした。
やっぱPaaSは楽すぎてクラウド屋さん的には面白みに欠けるなーと。