Herokuで独自ドメインを設定してもxxx.herokuapp.com
でアクセスできてしまう。これを解決する定番の方法はrack-rewriteというGemを使うこと。玄人の方はこのGemを使わずに独自でコードを書くらしいが一旦定番の方法でやった。ちなみに.htaccess
はHerokuでは使えない
rack-rewrite を bundle install
まずは毎度おなじみのGemのインストール。
Gemfileにgem 'rack-rewrite'
を追記し、ターミナルでプロジェクトのディレクトリに移動しbundle install
する。
最終的なコード
下記で本アプリへのすべてのアクセスが恒久的にhttps://mynewdomain.com
に飛ぶ(SSL化している前提)。xxx.herokuapp.com
だけでなくhttpでもwwwありでも全部飛ばしてくれるようだ。
# This file is used by Rack-based servers to start the application.
require_relative 'config/environment' # ←元からあるコード
gem 'rack-rewrite', '~> 1.5.0'
require 'rack/rewrite'
if ENV['RACK_ENV'] == 'production'
use Rack::Rewrite do
r301 %r{.*}, 'https://mynewdomain.com$&', :if => Proc.new {|rack_env|
rack_env['SERVER_NAME'] != 'mynewdomain.com'
}
end
end
run Rails.application # ←元からあるコード。これより上に書かないといけないはず
Heroku×Railsにおけるrack-rewriteの基本
gem 'rack-rewrite', '~> 1.5.0' # ここはいるっぽい
require 'rack/rewrite' # ここはいるっぽい
use Rack::Rewrite do
# ↓ ここにリライトルールやリダイレクトルールを書く
rewrite '/wiki/John_Trupiano', '/john'
r301 '/wiki/Yair_Flicker', '/yair'
r302 '/wiki/Greg_Jastrab', '/greg'
r301 %r{/wiki/(\w+)_\w+}, '/$1'
# ↑ ここにリライトルールやリダイレクトルールを書く
end
しかしrewrite
やr301
のコードは相対パスのリダイレクトしかできないよう。今回はREAD.MEの CNAME alternative の項目にある書き方を使う。
CNAME alternative
In the event that you do not control your DNS, you can leverage Rack::Rewrite to redirect to a canonical domain. In the following rule we utilize the $& substitution operator to capture the entire request URI.config.rur301 %r{.*}, 'http://mynewdomain.com$&', :if => Proc.new {|rack_env| rack_env['SERVER_NAME'] != 'mynewdomain.com' }
なのでHeroku環境でxxx.herokuapp.com
→mynewdomain.com
に301リダイレクトさせるコードはこう!
gem 'rack-rewrite', '~> 1.5.0'
require 'rack/rewrite'
use Rack::Rewrite do
r301 %r{.*}, 'http://mynewdomain.com$&', :if => Proc.new {|rack_env|
rack_env['SERVER_NAME'] != 'mynewdomain.com'
}
end
ちょっと難しい余談
CNAMEというのは Canonical NAME の略で、一般的にDNSのCNAMEレコードとして有名な用語。カノニカルURL(正規URL)を別ドメインに指定するときに本来はDNS設定からCNAMEレコードを設定するが、Herokuでは我々ユーザーはそこをいじれないからconfig.ru
で設定する方法だよ、という意味でCNAME alternative
という項目名になっているようだ。
localhostではリダイレクトしないようにする
しかし上記のままではlocalhost:3000
でアクセスしてもリダイレクトされてしまうらしく、if文でproduction環境のときだけ発動するようにする。よって最終的にこうなる。
gem 'rack-rewrite', '~> 1.5.0'
require 'rack/rewrite'
if ENV['RACK_ENV'] == 'production'
use Rack::Rewrite do
r301 %r{.*}, 'http://mynewdomain.com$&', :if => Proc.new {|rack_env|
rack_env['SERVER_NAME'] != 'mynewdomain.com'
}
end
end
ドメインの末尾に$&
が付いてるのは、例えばhttps://xxx.herokuapp.com/about
でアクセスしてきたときにhttps://mynewdomain.com/about
に飛ばしてやるための変数?的なアレらしい。
rack-rewriteのREAD.MEの日本語訳
SSLリダイレクトはこちら
http→httpsのリダイレクトだけをやりたい場合はこちら(本Qiitaのコードを使っていれば下記を設定せずともhttpsに飛ばしてくれるはず)。
https://qiita.com/maztak/items/0e682084db275c931c13