Search code examples
ruby-on-railsrubyherokuroutessubdomain

Heroku, custom subdomain and a custom constraint


I feel like this should be working based on my reading of other questions, but nothing I've found has so far done so. I have an app that lets club sports teams host a website (in theory). All works well on my local box when using lvh.me; however deploying to heroku breaks the routing.

Ruby on rails 5.1

Steps I've taken so far:

  1. Added the subdomain to heroku domains. For the heroku app I now have the root domain as an ALIAS or ANAME, www as a cname, and the newly added subdomain (pincity) as a cname.

  2. Added the cname to my dns provider. Using dig returns that the subdomain is returning the correct {crazy-heroku-name}.herokudns.com address

  3. After deploy and adding this team to the production app database (slug of 'pincity', so that pincity.mydomain.com works), I've restarted the dynos.

I think that should be all I need to do.

My routes file is fairly simple

class TeamWebsiteConstraint
  def matches?(request)
    Rails.logger.info "subdomain is #{request.subdomain}"
    Team.where(slug: request.subdomain).any?
  end
end

Rails.application.routes.draw do
  # all other routes

  # Club team custom websites
  constraints TeamWebsiteConstraint.new do
    root 'team_website#home', as: :team_website_root
    get 'about', to: 'team_website#about', as: :team_website_about
    get 'schedule', to: 'team_website#schedule', as: :team_website_schedule
    get 'faqs', to: 'team_website#resources', as: :team_website_resources
    get 'contact', to: 'team_website#contact', as: :team_website_contact
  end

  root 'marketing#home'
end

Now when going to heroku, the subdomain redirects me to the root domain. And typing in pincity.mydomain.com/about results in a 404

Edit: I added a little bit of logging to the teamconstraint route. Here's a bit from the log.

at=info method=GET path="/about" host=pincity.wrestlingiq.com request_id=b004b8cc-08e4-4bc9-a87a-d4b37deaa29c fwd="71.202.0.175" dyno=web.1 connect=1ms service=4ms status=301 bytes=391 protocol=https 
subdomain is www

It seems like heroku router is doing a 301 redirect before processing the routes code, which means that the subdomain constraint never gets a chance to fire.

Edit 2: I discovered a URL record in DNSSimple that was redirecting the root domain to the www version. I've removed that, and added app logic to handle that redirection for now. Hoping that helps.


Solution

  • I agree it appears the redirect is happening before the request hits your Rails app, which would mean it's either Heroku or something before Heroku. Do you have a CDN sitting in front of your Heroku app?

    I could see something like a Cloudflare redirect page rule causing this behavior. I'm especially suspicious of this because your root domain also redirects to www:

    ❯ curl -I https://wrestlingiq.com      
    HTTP/1.1 301 Moved Permanently
    Server: Cowboy
    Date: Sun, 20 Jan 2019 14:20:54 GMT
    Connection: keep-alive
    Cache-Control: max-age=3600
    Content-Type: text/html
    Location: https://www.wrestlingiq.com/
    Content-Length: 215
    Via: 1.1 vegur