以前の記事、Herokuアプリに独自ドメインを割り当てるの最後に書いたHerokuでのドメイン単位の転送に関する疑問点2つについて、解決したので備忘録。
疑問点2つ
Herokuアプリに独自ドメインを割り当てた後、2つの疑問点が浮上した。
www.ruedap.com
にアクセスしたら、ruedap.com
に転送するようにしたいwww.ruedap.com
でも同じ内容を表示するだけなら、前述のAレコードの設定で「www」も設定すれば良いんだろうけど、転送したいのでちょっと違う。こういう場合は独自ドメイン側じゃなく、リダイレクトをHerokuアプリ側でするのかな?
- 独自ドメイン設定後は、
ruedap.heroku.com
にアクセスしたら、ruedap.com
に転送するようにしたい- このLokka用プラグインRedirect_if_herokuのRubyコードが参考になりそう
これについて、@uzduraさんがアドバイスしてくれて「rack-rewriteというgemを使うと簡単に解決できるよ」と教えてもらった。さらに、そのrack-rewriteのreadmeを日本語訳した記事まで書いてくれているので、このgemを使うなら必見。
Rack::Rewrite の README を超訳してみました « blog.udzura.jp
で、rack-rewriteを使って試してみたところ、上記の疑問点2つともサクっと解決できた。
Rack::Rewriteを使う
今回は、自分がよく作るHeroku用Sinatraアプリの構造をベースにRack::Rewriteを使ってみる。既に稼動しているSinatraアプリを前提に、Gemfile
とconfig.ru
の2ファイルを修正する。
Gemfile
Gemfileには、普通にrack-rewriteのgemを追加するだけ。
source :rubygems
gem 'sinatra'
gem 'slim'
gem 'sass'
gem 'rack-rewrite' # これを追加
config.ru
config.ru
には、前述のRack::Rewriteのreadmeの「CNAME の代わり」の項目を参考に、use
メソッドを追加する。
require 'rubygems'
require 'bundler'
Bundler.require
# このメソッドを追加
if ENV['RACK_ENV'] == 'production'
use Rack::Rewrite do
r301 %r{.*}, 'http://ruedap.com$&', :if => Proc.new {|rack_env|
rack_env['SERVER_NAME'] != 'ruedap.com'
}
end
end
require './app.rb'
run Sinatra::Application
use
メソッド部分を文章で書くと、
- アクセスしてきたドメインが「ruedap.com」じゃなかったら、「ruedap.com」に置き換えた上で、それ以降のパスを付け足す(リダイレクトする)
という感じかな? なんで引数がProcなのか、とか詳しいことはよくわからないけど動いた。あと、このリダイレクト処理が、例えばローカルでの動作チェック時のlocalhost:9292
(rackup)やruedap.dev
(Pow)などで起動した時もruedap.com
にリダイレクトされたり、ステージング環境でも本番サイトにリダイレクトされてしまうのは問題がある。なのでRACK_ENV
がproduction
の時だけ実行するようにif
で囲う。これでHerokuにデプロイすると、以下の疑問点(2)の方が解決できる。
- 独自ドメイン設定後は、
ruedap.heroku.com
にアクセスしたら、ruedap.com
に転送するようにしたい
疑問点(1)の方は、www付きドメインwww.ruedap.com
をHerokuへ向ける設定をしていないので、そもそもアクセスできない。ので、次の設定を加えることで解決する。
www付きドメインをwww無しドメインにリダイレクト
これは単に、www無しドメインruedap.com
の時と同じように、www付きドメインwww.ruedap.com
もHerokuのAレコード用IPアドレスを追加してHerokuへ向かうように設定してあげれば良いだけ。そうすればHerokuアプリ側では、さきほどRack::Rewriteを使って設定した条件の
- アクセスしてきたドメインが
ruedap.com
じゃなかったら、ruedap.com
に置き換えた上で、それ以降のパスを付け足す(リダイレクトする)
が発動するので、www無しドメインにリダイレクトされる。ruedap.com
はバリュードメインで取得したドメインなので、以下はバリュードメインでの設定手順。
バリュードメイン側の設定
バリュードメインの管理画面にログインしている状態で、以降の設定を行う。
- まず、取得済みドメイン一覧のページから、対象のドメイン(今回の場合は
ruedap.com
)の「DNSレコードの変更/URL転送の変更」(緑色のDNSボタン)をクリックして、DNS設定画面を開く。 - DNS設定画面の設定フィールドで、www無しドメインの設定(上3行)の後ろに、www付きドメインの設定(下3行)を付け加えて保存する。
a @ 75.101.163.44
a @ 75.101.145.87
a @ 174.129.212.2
a www 75.101.163.44
a www 75.101.145.87
a www 174.129.212.2
これでwww.ruedap.com
でもアクセスできるようになり、アクセスすればHeroku側でリダイレクトされるのでruedap.com
になる。はず。というわけで疑問点(2)も解決。めでたしめでたし、となる予定が、まだめでたくなかった…。www.ruedap.com
にアクセス出来るようになったら、エラー画面になってしまった。
Heroku側のドメイン設定も必要
Heroku側でのドメイン設定も必要だった。大前提としてwww.ruedap.com
をruedap.heroku.com
で受けて、その後に先ほどのRack::Rewriteの処理が走るので、その大前提が抜け落ちてた!
$ heroku domains:add www.ruedap.com
Added www.ruedap.com as a custom domain name to ruedap.heroku.com
これでおk www.ruedap.com
にアクセスしたら、ruedap.com
に飛ばされた。というわけで疑問点(2)も解決。めでたしめでたし。教えてくれた@udzuraさんあざっす!
Sinatra上でも出来るけど
上記の疑問点2つは、Sinatraアプリで使える組み込み変数request.host
を使って、アクセスしてきたドメイン名を調べて同じようなことをやれば、おそらくSinatra上でも解決できそうだと思った。けど、
- 自分で全部書くよりは、既にライブラリ化されているコードに任せたほうがミスが少なそう
- Sinatraより一段低いレイヤーであるRack層で処理したほうが良い気がする
- Rack::Rewriteのreadmeには「rackupファイル(config.ru)にこうやって書くよ」と書かれているので、このライブラリを利用する人の多くは同じ場所に書きそう=config.ruを見ればrewriteルールが集まってると期待できそう
などの理由により、このライブラリを使ったほうが良いかなーと思ったけど、どうなんだろう? こういう時Railsなら、やり方が決まってて悩まなくても良いんだろうか。ということを、Railsを知らずにSinatraを使っていると良く思う。 Railsも使えるようにならねば…。
Rack::Rewrite の README を超訳してみました « blog.udzura.jp rack-rewrite README in japanese ― Gist