Joe
Joe

Reputation: 1772

nginx - can't figure out location rewrites

I'm trying to redirect different URI requests to different EC2 containers, I've been using nginx for years as a catchall reverse proxy to apache but now I'd like to have some rewrites done at nginx level.

Here's what I'm trying to accomplish:

server {
    listen       80;
    server_name  _;

    gzip              on;
    gzip_static       on;
    gzip_buffers      16 8k;
    gzip_comp_level   9;
    gzip_http_version 1.0;
    gzip_min_length   0;
    gzip_types        text/plain text/css application/x-javascript;
    gzip_vary         on;

    location / { 
        # catch the following URI's including homepage: /contact.html, /terms.html, /
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 240;
        proxy_connect_timeout 240;
        proxy_send_timeout 240;

        send_timeout 240;
        proxy_pass http://servers_static;
    }

    location / { 
        # catch everything not matched above
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_read_timeout 240;
        proxy_connect_timeout 240;
        proxy_send_timeout 240;

        send_timeout 240;
        proxy_pass http://servers_dynamic;
    }
}

I'm sure this just a simple regex issue, but I have never understood that stuff. Can someone help me out?

Upvotes: 2

Views: 469

Answers (2)

cobaco
cobaco

Reputation: 10546

Create a file /etc/nginx/EC2 with the common proxy settings:

proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_read_timeout 240;
proxy_connect_timeout 240;
proxy_send_timeout 240;
send_timeout 240;

Your main config then becomes:

server {
  listen       80;
  server_name  _;

  #gzip settings cut for brevity, add them back in     

  # static content
  location = / {include /etc/nginx/EC2; proxy_pass http://servers_static;}
  location = /contact.html {include /etc/nginx/EC2; proxy_pass http://servers_static;}
  location = /terms.html {include /etc/nginx/EC2; proxy_pass http://servers_static;}

  # dynamic content
  location / { include /etc/nginx/EC2; proxy_pass http://servers_dynamic; }
}

you might also combine the locations for the .html static content pages like so:

  location ~ (contact|terms).html {
    include /etc/nginx/EC2; proxy_pass http://servers_static;}

it's probably slightly more efficient to have the exact matching locations, and as long as you don't have to many the resulting duplication shouldn't make the config to unwieldly

Upvotes: 2

Erik Peterson
Erik Peterson

Reputation: 4311

Take a look at try_files. It will successively try the paths you give it. In this example, any static file at /var/www/sites/foo/current/public/$uri will be returned, only routing the request to the app if no static file exists.

upstream app {
  server unix:/tmp/.sock_my_app;
}

server {
  # path for static files
  root /var/www/sites/foo/current/public;

  # Prefer to serve static files directly from nginx to avoid unnecessary
  # requests to the application server.
  try_files $uri/index.html $uri.html $uri @app;

  location @app {
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

    # timeouts

    # reverse proxy to an upstream
    proxy_pass http://app;
  }
}

Upvotes: 0

Related Questions