Nginx – Port number being added to WordPress admin after Varnish install

nginxvarnishWordpress

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);
    }
}

Best Answer

I think you are wrong 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.