Hot questions for Using Spree in caching

Question:

I am using Spree Commerce deployed through Cloud 66 and running on Digital Ocean servers. Nginx is my web server.

If someone visits my site via one of the server's IP addresses rather than the domain name it seems like the cached links become "infected" with the ip address. Going forward, the cached links use the IP address as the base URL rather than the site's FQDN.

For example, let's say my site's FQDN is "store.mystore.com" and its ip address is 45.5.5.235. Someone (or some bot) visits the products index via the ip address rather than the FQDN. They visit "https://45.5.5.555/products". Going forward, the cached links that used to show "https://store.mystore.com/products/product-1" now show up as "https://45.5.5.235/products/product-1".

I'm using site-wide SSL that is tied to my FQDN, so a big nasty warning shows up in the user's browsers warning them that the site they're about to click on isn't the one they think it is. Not good for ecommerce, obviously.

If I manually clear the cache then the problem is corrected until another bot/crawler visits the site via ip address.

I'm using memcached and Dalli, if that makes any difference. I am setting the site URL in Spree's admin panel.

Is there anything I can do to ensure that Rails-generated links always use the FQDN rather than the server's IP address?

EDIT

Eirikir's answer is pretty much correct, however I have a HAProxy load balancer switching between two different servers. I put two server blocks at the end of my nginx config, one listening on port 80 for http, and one listening on 443 for https.

server {
        listen 80;
        server_name haproxy_ip rails_server_ip;
        return 301 $scheme://store.mystore.com$request_uri;
}

    server {
        listen 443;
        server_name haproxy_ip rails_server_ip;
        return 301 $scheme://store.mystore.com$request_uri;
}

Not sure if this is the best way to do it, but it seems to work so far.


Answer:

The link caching issue is contingent on the fact that your site is accessible via multiple domains (including the IP). This is terrible for SEO, since search engines may consider your canonical domain as duplicates of the alternate domains.

You don't mention if you're using Apache, Nginx, or another server, but that would be the best place for a 301 redirect to your canonical production domain. Some DNS services also encapsulate this feature as a certain DNS record type. You would need to find how to do this in your server/DNS configuration.

If its not possible for you to perform the redirect on the DNS or server level, you can implement the redirect in a before_filter in application_controller.rb:

before_filter :redirect_to_canonical_host if Rails.env.production?

private
CANONICAL_HOST = "store.mystore.com"
def redirect_to_canonical_host
  unless request.host == CANONICAL_HOST
    redirect_to "https://#{CANONICAL_HOST}#{request.fullpath unless request.fullpath == '/'}", status: :moved_permanently
  end
end

Again, this isn't optimal since an Apache or Nginx redirect would be much faster, and I'm worried server admins will downvote me for this, but there are cases where it can't be avoided.

ETA: I'm no Nginx expert by any means, but I don't believe wildcards are available for server_name, so you'd have to write a server block with a redirect for each possible IP or alternative hostname, e.g.:

server {
        server_name 45.5.5.555;
        return 301 $scheme://store.mystore.com$request_uri;
}

Question:

When I update spree config via admin panel Spree::Config[some_key] = some_value it overwrites the value in a spree_preferences table, but also store previous versions of value and use all these versions. Rails.cache.clear do not help. But restart a unicorn helped me.

Where are these versions stored? How can I explicitly reset the cached values ​​in the code?


Answer:

The problem was in the caching of unicorn workers.

Question:

We use rabl for our view templates with rails 4. Recently we are experimenting with caching these rabl views. We know that caching is done by adding following line to the views - cache some_object

My question is how to decide this some_object ?

For example We have a view that returns videos, that has associated products' info in it. Now there is data that is derived from a user object in this view that is not to be cached as caching that would result in incorrect data for requests from different users. So I understand that I need to pass the user object for the cache key. But what other objects should i pass to generate cache key for this view and get best performance?


Answer:

It's depends what you have on view. If You have user and video i will add user and video to cache key. It all depends what is important for you. More objects in cache key means more often changes in cache because key will change when you change user and video.