Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

I added Varnish in front of nginx. When I try to login to WordPress, I go to domain.com/wp-admin but I'm now redirected to domain.com:8080/wp-admin. I can manually remove the port and the admin side functions the way it should.

My Varnish config:

backend origin {
    .host = "localhost";
    .port = "8080";
    .connect_timeout = 60s;
    .first_byte_timeout = 60s;
    .between_bytes_timeout = 60s;
}
acl purge {
    "localhost";
}
sub vcl_recv {
    set req.backend = origin;
    set req.http.X-Forwarded-For = client.ip;
    if(req.url ~ "^/wp-(login|admin)" || req.http.Cookie ~ "wordpress_logged_in_") {
        return (pass);
    }
    if(req.url ~ "/xmlrpc.php") {
        return(pass);
    }
    if( req.url ~ "\?s=" ){
        return (pass);
    }
    if (req.request == "BAN") {
        if(!client.ip ~ purge) {
            error 405 "Not allowed.";
        }
        ban("req.url ~ "+req.url+" && req.http.host == "+req.http.host);
        error 200 "Banned.";
    }
    if (req.request != "GET" && req.request != "HEAD" && req.request != "PUT" && req.request != "POST" && req.request != "TRACE" && req.request != "OPTIONS" && req.request != "DELETE") {
        return (pipe);
    }
    if (req.request != "GET" && req.request != "HEAD") {
        return (pass);
    }
    unset req.http.Cookie;
    return (lookup);
}
sub vcl_hit {
    if (req.request == "PURGE") { purge; }
    return (deliver);
}
sub vcl_miss {
    if (req.request == "PURGE") { purge; }
    return (fetch);
}
sub vcl_fetch {
    unset beresp.http.Server;
    unset beresp.http.X-Powered-By;
    if (beresp.status == 404) {
        set beresp.ttl = 0m;
    return(hit_for_pass);
    }
    if( beresp.http.Set-Cookie && req.url !~ "^/wp-(login|admin)" ){
        unset beresp.http.Set-Cookie;
    }
    if ( req.request == "POST" || req.http.Authorization ) {
        return (hit_for_pass);
    }
    if ( beresp.status != 200 ) {
        return (hit_for_pass);
    }
    if( req.url ~ "\?s=" ){
        return (hit_for_pass);
    }
    set beresp.ttl = 5m;
    return (deliver);
}
sub vcl_deliver {
    if (obj.hits > 0) {
        set resp.http.X-Cache = "HIT";
    } else {
        set resp.http.X-Cache = "MISS";
    }
    unset resp.http.Via;
    unset resp.http.X-Varnish;
}
sub vcl_error {
    if (obj.status == 503 && req.restarts < 2) {
        set obj.http.X-Restarts = req.restarts;
        return(restart);
    }
    if (obj.status == 301) {
        set obj.http.Location = req.url;
        set obj.status = 301;
        return(deliver);
    }
    if (obj.status == 750) {
        set obj.http.Location = obj.response;
        set obj.status = 302;
        return (deliver);
    }
}
share|improve this question
    
Is it doing something like adding a trailing slash or something like /index.php? Or is it simply redirecting from http://example.com/wp-admin to http://example.com:8080/wp-admin –  Shane Madden Mar 28 '13 at 4:33
    
It's just redirecting. If I'm not logged in it takes me to domain.com/wp-login.php and I can see in the URL that it's going to redirect me to domain.com:8080/wp-admin when I login. –  kel Mar 28 '13 at 5:15
    
So it's redirecting to the login page, then after login it's sending you to port 8080? How about if you're already logged in? –  Shane Madden Mar 28 '13 at 5:23
    
If I'm already logged in, it just goes to domain.com:8080/wp-admin. Also, the front-end of the site works just fine and no links have the port in them. –  kel Mar 28 '13 at 5:31
    
Can you check using your browser's debugging tools what the exact response is that redirects you? It should be a 30x response code and have a Location header containing the full URL. Should be able to work around it in Varnish, but need to know exactly what to look for in the VCL config to do so. –  Shane Madden Mar 28 '13 at 6:40
show 6 more comments

3 Answers

up vote 4 down vote accepted

You're obviously lying to us that the redirect only appends the port, without also postfixing a slash to the end of the URL.

After catching that issue, it's pretty clear that this an internal redirect that is done by nginx when it encounters that a directory is being accessed without a trailing slash.

You would use http://nginx.org/en/docs/http/ngx_http_core_module.html#port_in_redirect to disable the port from being appended:

port_in_redirect off;

This solution will work great as long as you don't rely on such redirects when trying to access nginx directly on port 8080, and as long as the Host names match between varnish and nginx.

share|improve this answer
add comment

In "Settings -> General", set "WordPress Address (URL)" to "http://yourdomain.com:80/"

Update : I discovered that this solution really only works in the most basic scenarios. Any sort of cache or CDN plugin that looks to this variable will append the ':80'--causing all sorts of funky problems. In the end, I simply had my client point to '/wp-login.php' instead. ;)

share|improve this answer
add comment

Not sure what all this talk about the author "lying", since lying is, "to make an untrue statement with intent to deceive". The author clearly is not intending to deceive users rather he just didn't realize that it was working with a forward slash and ultimately the person just wants to know how to make it work without a forward slash.

To resolve this I would recommend adding the following to your nginx server block:

rewrite /wp-admin$ $scheme://$host$uri/ permanent;

This was when you go to example.com/wp-admin it will go to example.com/wp-admin rather than going to example.com:8080/wp-admin/ and if you are on CloudFlare DNS for instance it will say the site is down.

I'm using Ubuntu, Nginx and Varnish and this works perfectly now rather than disabling port_in_redirect.

To add, be sure to to restart nginx after:

sudo service nginx restart
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.