1

I'm trying to redirect 15 different routes with Nginx from folders to subdomains (I already read some threads about this).

I'm very confused because this redirect is working:

rewrite ^/admin(.*) $scheme://admin.example.com/$1 301;

while this one is not (the url is not changed in my browser):

rewrite ^/app(.*) $scheme://apps.example.com/$1 301;

What did I miss ?

At the time, I have only these 2 redirects (I need 15 more complicate later).

EDIT: more explanations with my full nginx config

server {
  listen 80 default_server;
  listen [::]:80 default_server;

  server_name example.com;
  passenger_enabled on;
  rails_env    production;
  root         /home/admin/rails/current/public;

  # redirect server error pages to the static page /50x.html
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   html;
  }


  # redirects
  # admin
  rewrite ^/admin(.*) $scheme://admin.example.com/$1 302;

  # apps    
  rewrite ^/app(.*) $scheme://apps.example.com/$1 302;

}

EDIT 2: asked by Tom, What I want to do exactly (I prefer to keep the URL secret):

GET http://example.com => http://apps.example.com
GET http://example.com/app => http://apps.example.com
GET http://example.com/app/iphone => http://apps.example.com/iphone
GET http://example.com/app/ipad => http://apps.example.com/ipad
GET http://example.com/support/iphone => http://apps.example.com/support/iphone
GET http://example.com/support/ipad => http://apps.example.com/support/ipad
GET http://example.com/legal/privacy?params=toto => http://apps.example.com/legal/privacy?params=toto
GET http://example.com/legal/terms?params=toto => http://apps.example.com/legal/terms?params=toto
GET http://example.com/legal/about => http://apps.example.com/legal/about

I have also a few POST to redirect but I think I need a proxy for that, isn't it ?

Thanks in advance.

EDIT 3: so here are my GET redirects after Tom answer:

  # pages to redirect to admin.$host
  location /admin { return 301 $scheme://admin.$host; }

  # pages to redirect to apps.$host
  location /app { return 301 $scheme://apps.$host; }
  location /app/iphone { return 301 $scheme://apps.$host/iphone; }
  location /app/ipad { return 301 $scheme://apps.$host/ipad; }
  location /support/iphone { return 301 $scheme://apps.$host/support/iphone$is_args$args; }
  location /support/ipad { return 301 $scheme://apps.$host/support/ipad$is_args$args; }
  location /legal/privacy { return 301 $scheme://apps.$host/legal/privacy$is_args$args; }
  location /legal/terms { return 301 $scheme://apps.$host/legal/terms$is_args$args; }
  location /legal/about { return 301 $scheme://apps.$host/legal/about; }

It is working great !

Now, I will open a new thread cos' I can't create POST redirect with my proxy_pass. See there.

alex.bour
  • 111
  • 1
  • 5
  • Did you clear your browser cache? – gxx Jan 07 '16 at 21:11
  • Yes. I tried In Safari (clear the cache) and Chrome. – alex.bour Jan 07 '16 at 21:12
  • So...lets go debugging: Enable debug error log and show a failed request. – gxx Jan 07 '16 at 21:15
  • You still need to post the URLs you're trying to redirect from and to, and the access/error. Ideally post the real URL so we can look at the behavior, you can edit them out later. Right now you're saying it's not working without saying what you want it to do. – Tim Jan 07 '16 at 21:51
  • I added infos below your answer. – alex.bour Jan 07 '16 at 21:52
  • You need to say precisely what URL you want to redirect from and to. eg "I want to redirect from http://www.example.com/abc/def/app to http://app.example.com". You should also say what should happen to subfolders. – Tim Jan 07 '16 at 22:13
  • Ok Tom. Thanks. I added most of routes in my first post. Sorry for that. – alex.bour Jan 07 '16 at 22:15

1 Answers1

1

Use 302 redirects while testing, 301s are cached. Clear your browser cache and restart it. Change the 302's below to 301s when you're happy with your config.

Try this - I've given a few examples posted and you can work the rest out. You should read up on order of evaluation inside nginx, but for exact matches it's not important - it only applies to regular expression matches.

Note that this should do what you asked for, which may not be what you want - note that you didn't include a trailing slash in your examples.

It also looks like you just want to redirect everything to the app domain, is that the case? If so it's much easier. But here's what you asked for, tested.

location /support/ipad {
  # change to 301 when you're 100% happy with all redirects
  return 302 http://example.com/support/ipad;
}

location /app/iphone {
  return 302 http://example.com/app/iphone;
}

location ~* ^/\Z {
  return 302 http://whatever;
}

There may be a more efficient way of doing it with regular expressions, but doing them individually may be prudent if you're not redirecting the whole domain. Note that ~* means what follows is a regular expression, which are evaluated after the ones that specific a single precise URI.

Based on what you've said the root redirect is required to have a regular expression to make sure it only redirects the root domain, not for example http://www.example.com/pagea.html. If you want everything redirected that's easier.

Also, did you mean this? Note the trailing slashes

GET http://example.com/ => http://apps.example.com/

^ means "start of URI", which is the URL without the website. It means it will only match the root of the website, not any folder. /Z means "end of URI". You can output debug information in browser headers to help with this

location whatever {
  add_header Z_LOCATION "(any text you want)";
  add_header URI $uri;
}
Tim
  • 31,888
  • 7
  • 52
  • 78
  • I added the full Nginx config. Also tried 302 with the same result. – alex.bour Jan 07 '16 at 21:49
  • Ok. I saw this in logs: `2016/01/07 22:15:34 [emerg] 19516#0: invalid parameter "301" in /etc/nginx/sites-enabled/example.com:19 2016/01/07 22:22:25 [emerg] 20042#0: invalid parameter "302" in /etc/nginx/sites-enabled/vinocell.com:19` – alex.bour Jan 07 '16 at 21:49
  • Very strange. I removed 301 and replaced with "permanent" => working. Then I replaced with "301" => working !! – alex.bour Jan 07 '16 at 21:50
  • Read my comment on your main question. You haven't provided the information required to answer your question - you haven't even said what you're trying to achieve clearly and precisely. It's possible your nginx restart didn't happen because of the syntax error. – Tim Jan 07 '16 at 21:53
  • 1
    I've updated my answer, it should do what you want, but there's a question in there too regarding whether you're trying to redirect the whole domain or just specific URLs. – Tim Jan 07 '16 at 22:37
  • Tim, now all is working great with my GET redirects. I posted my code in first message. And open a new thread for POST redirects. – alex.bour Jan 08 '16 at 11:19