2

First of all my domain root is configured to serve an Angular webpage using a reverse proxy that redirects to local ip/port, that's working like a charm. The problem arrives now when I want to override root rule if url contains /blog which I want to redirect to a wordpress folder. At the moment and with this config I can reach wordpress but just specific urls like example.com/blog/wp-admin/index.php, but if i access example.com/blogis still going to angular app. I've configured my nginx as follows(I have to say is my first time configuring a webserver):

server {
    listen [::]:443 ssl http2;
    listen 443 ssl http2;
    server_name example.com www.example.com;

    client_max_body_size 100M;
    root /var/www;
    index index.php index.html index.htm index.nginx-debian.html;
    autoindex off;

    location ~ /blog(.*)+/(.*)$ {
        try_files $uri $uri/ /blog/index.php?$args /blog/index.php?q=$uri&$args;
        location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            include fastcgi_params;
        }
   }

    location / {
        proxy_pass http://127.0.0.1:4000;
        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;
        proxy_set_header X-NginX-Proxy true; proxy_redirect off;
        http2_push /var/www/example_frontend/dist/example-frontend/favicon.ico;
        http2_push /var/www/example_frontend/dist/example-frontend/manifest.json;
    }

    location /robots.txt {
        alias /var/www/example_frontend/robots.txt;
    }

    location /sitemap.xml {
        alias /var/www/example_frontend/sitemap.xml;
    }

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem; # managed by Certbot
}


server {
    if ($host = www.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    if ($host = example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot


    listen 80;
    server_name example.com www.example.com;
    return 404; # managed by Certbot
}

It's working perfectly if I stop my angular app, so I think I need to trigger the /blog location in first place but I tried in all possible forms with no result. Does someone see what's wrong? I thought first rule is triggered first but seems not.

Thanks in advance.

I can append any other config file if required ;)

Jordi
  • 331
  • 2
  • 15

1 Answers1

2

The URI /blog does not match the regular expression of your location, which requires an additional / somewhere in the URI to match.

The simplistic solution is:

location /blog {
    try_files $uri $uri/ /blog/index.php?q=$uri&$args;
    ...
}

The above would match /blog and /blog/, but also matches /blogx (which may be undesirable).


You could use a modified regular expression, for example:

location ~ ^/blog(/|$) {
    try_files $uri $uri/ /blog/index.php?q=$uri&$args;
    ...
}

The most efficient solution is to use prefix locations, but with more typing:

location /blog {
    return 301 /blog/;
}
location /blog/ {
    try_files $uri $uri/ /blog/index.php?q=$uri&$args;
    ...
}

See this document for more. Incidently, your try_files statement contained a spurious parameter.

Richard Smith
  • 45,711
  • 6
  • 82
  • 81
  • Thanks for your reply Richard, I updated the config with your suggestions and still having the same behavior. It makes me think the problem is probably in the angular routing... but i have to say that i've deleted the fallback rule on it. Not sure if I'm looking the bug in the right context... – Jordi Feb 28 '19 at 09:57
  • Also, ensure that you clear the browser's cache and restart Nginx after any changes. – Richard Smith Feb 28 '19 at 10:02
  • Yes, I've done it. Now i've tested with curl `curl https://example.com/blog/ `and I'm getting the right wordpress html content, while Chrome is redirecting to the Angular app – Jordi Feb 28 '19 at 10:07
  • No, I'm getting a 301 Moved Permanently (I used your second code snippet, not the third if is useful to know) – Jordi Feb 28 '19 at 10:19
  • That's fine, so it seems to me that Chrome is still relying on its cache for some reason. Check the access logs - see what Chrome is requesting from your server. – Richard Smith Feb 28 '19 at 10:23
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/189188/discussion-between-jordi-and-richard-smith). – Jordi Feb 28 '19 at 10:42
  • Finally solved, it was related with Angular's Service Worker. I don't know how I've reached [this](https://stackoverflow.com/questions/45663796/setting-service-worker-to-exclude-certain-urls-only) given it's under React but the behavior were exactly the same in my Angular . Thanks anyway for validating my nginx config file! – Jordi Feb 28 '19 at 12:29