1

UPDATE 28.02.2019

The problem is the following part inside my server block:

        # Don't use `$uri` here, see https://github.com/yandex/gixy/issues/77
        rewrite /wp-admin$ $scheme://$host$request_uri/ permanent;
        rewrite ^(/[^/]+)?(/wp-.*) $2 last;
        rewrite ^(/[^/]+)?(/.*\.php) $2 last;
    }

Without it, everything finally works as intended. The problem is, that this is a needed part for a Wordpress-Multisite Installation to run. Without it, it is not possible to use wp-admin.

After locating the Problem - does anybody has an Idea how to solve it? (beside normal Wordpress installation and separating the forum via proxy as somebody suggested below)

TL;dr

I created a location block (/de/forums/) outside of the nginx root folder but the php gets sent to the php compiler inside root so there is a directory mismatch. It wont take the defined php stack inside the new location block. Help!

The location block /de/forums/ works, but just for files, not for php. With php I get a "File not Found" because it uses the main root folder as base and not the new alias.

And I cant figure out how to force nginx to use the more specific php with the right "fastcgi_param SCRIPT_FILENAME $request_filename;".

.

Following situation:

LEMP Stack with php7.2-fpm

Wordpress Multisite Installation on domain.com - configured to use Subdirectorys. There are two for this domain: domain.com/de/ and domain.com/en/. As you probably guessed for different language versions of a Blog. An example page is domain.com/en/contact-us and a blog post would be domain.com/en/this-is-a-blog-1451

So we have:

domain.com/de/
domain.com/en/
domain.com/en/contact-us
domain.com/en/this-is-a-blog-1451

We want to add:

domain.com/de/forums/
domain.com/en/forums/

And this is how the folder stucture looks:

/var/www/domain.com/
/var/www/domain.com/html/
/var/www/domain.com/html/index.php #(Wordpress)
/var/www/domain.com/forum-de/index.php #(Xenforo)
/var/www/domain.com/forum-en/index.php #(Xenforo)
/var/www/domain.com/logs/
/var/www/domain.com/ssl/
/var/www/domain.com/wp-config.php

So we need to create a location blog for the forum folders. In theory, a more specific location block (/de/forums/) should take precedent over a general / so the block should always point to the forum and not to Wordpress.

Here is my full server block - with comments for you:

server {

listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name domain.com;

root /var/www/domain.com/html;
error_log /var/www/domain.com/logs/error.log warn;
access_log /var/www/domain.com/logs/access.log;
index index.php;

location = /favicon.ico { log_not_found off; access_log off; }
location = /robots.txt { log_not_found off; access_log off; allow all; }
location ~* \.(css|gif|ico|jpeg|jpg|js|png)$ {
    expires max;
    log_not_found off;
}
# denies all hidden files
location ~ /\. {
    deny all;
}
# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
    deny all;
}

add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection "1; mode=block";
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";



    location / {
            # This is cool because no php is touched for static content.
            # include the "?$args" part so non-default permalinks doesn't break when using query string
            try_files $uri $uri/ /index.php?$args;
    }

    if (!-e $request_filename) {
    rewrite /wp-admin$ $scheme://$host$uri/ permanent;  
    rewrite ^(/[^/]+)?(/wp-.*) $2 last;                     
    rewrite ^(/[^/]+)?(/.*\.php) $2 last;                   
    }




# indicate locations of SSL key files.
ssl_certificate /var/www/domain.com/ssl/ssl.crt;
ssl_certificate_key /var/www/domain.com/ssl/ssl.key;

# Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
# see https://hstspreload.org/
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

ssl_protocols TLSv1.2 TLSv1.1 TLSv1;
ssl_ecdh_curve X25519:P-256:P-384:P-224:P-521;

ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';


# generate by "openssl dhparam -outform PEM -out dhparam2048.pem 2048"
ssl_dhparam /etc/nginx/ssl/dhparam2048.pem;
#ssl_ecdh_curve secp384r1; SEEMS NOT TO WORK WITH CLOUDFLARE
ssl_prefer_server_ciphers on;

# Enable HSTS. This forces SSL on clients that respect it, most modern browsers. The includeSubDomains flag is optional.
# see https://hstspreload.org/
# add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

# DO NOT USE!!!!
# DO NOT USEadd_header Public-Key-Pins 'pin-sha256="AKTUELLER-KEY-HASH"; pin-sha256="BACKUP-KEY-HASH"; max-age=31536000; includeSubDomains';
# DO NOT USE!!!!


ssl_session_cache shared:SSL:30m;
ssl_stapling on;
ssl_stapling_verify on;
ssl_session_tickets on;
# generate with "head -c 48 /dev/urandom > /etc/nginx/ssl/nginx_ticketkey"
ssl_session_ticket_key /etc/nginx/ssl/nginx_ticketkey;
ssl_session_timeout 41m;


# resolver conf
resolver 8.8.8.8 8.8.4.4 valid=1200s;
resolver_timeout 5s;



    location ~* \.(3gp|gif|jpg|jpeg|png|ico|wmv|avi|asf|asx|mpg|mpeg|mp4|pls|mp3|mid|wav|swf|flv|exe|zip|tar|rar|gz|tgz|bz2|uha|7z|doc|docx|xls|xlsx|pdf|iso)$ {
        # gzip_static off;
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        access_log off;
        expires 30d;
        break;
    }

    location ~* \.(js)$ {
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        access_log off;
        expires 30d;
        break;
    }

    location ~* \.(css)$ {
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        access_log off;
        expires 30d;
        break;
    }

    location ~* \.(html|htm|txt)$ {
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        access_log off;
        expires 1d;
        break;
    }

    location ~* \.(eot|svg|ttf|woff|woff2)$ {
        add_header Access-Control-Allow-Origin *;
        add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        access_log off;
        expires 30d;
        break;
    }   




    location ^~ /de/forums/ {
        alias /var/www/domain.com/forum-de/;
        #also tried root
        index index.php index.html index.htm;
        try_files $uri $uri/ /de/forums/index.php?$uri&$args;
          #also tried just /index.php?$uri&$args;


    }

location ~  ^/de/forums/(.+\.php)$ { 
    alias var/www/domain.com/forum-de/; 
     #also tried root    
    fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
    include fastcgi.conf;
    fastcgi_index  index.php;
    fastcgi_param  SCRIPT_FILENAME  $request_filename;
    #also tried using the full path here
}   


#cloudflare stuff - cut out for shortness sake
set_real_ip_from 103.21.244.0/22;
#many more here

# use any of the following two
real_ip_header CF-Connecting-IP;
#real_ip_header X-Forwarded-For;



    location ~ [^/]\.php(/|$)  {
        #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
        include fastcgi.conf;
        fastcgi_split_path_info ^(.+?\.php)(/.*)$;
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        fastcgi_index index.php;

        fastcgi_connect_timeout 60;
        fastcgi_send_timeout 180;
        fastcgi_read_timeout 180;
        fastcgi_buffer_size 512k;
        fastcgi_buffers 512 16k;
        fastcgi_busy_buffers_size 1m;
        fastcgi_temp_file_write_size 4m;
        fastcgi_max_temp_file_size 4m;
        fastcgi_intercept_errors off;


}

}

.

I tried:

  • Using location php as a sub location under /de/forums/
  • Using root instead of alias (what is wrong but I got desperate)
  • Not using fastcgi.conf link
  • Using $request_filename or /var/www/domain.com/html/forum-de/$fastcgi_script_name also /var/www/domain.com/html/forum-de$fastcgi_script_name
    • deleting the / php block, still didn't use the specific to the location /de/forums/

The only thing that was working, was creating an actual folder like /var/www/domain.com/html/de/forums/index.php. But then I get an 404 with wordpress if I want to access /de/ and all the pages there, because of the try_files. I probably could work with if but thats not recommended as far as I read.

Also I can access files with the location blog (jpgs for example) - so the location block works but not the php.

The error message is File not found. So the forum phps getting sent to the php compiler, but there is - I believe - an adress mismatch with the general root and the new location root. I couldn't even access a phpinfo file.

Please help!

Further readings: (aka I found helpful stuff here, but didn't solve my problem)

As most of them suggested, fastcgi_param SCRIPT_FILENAME $request_filename; should fix my problem. BUT... nginx just don't uses my php location with correctly set SCRIPT_FILENAME - it keeps using the "main" php location /

  • You should use a nested location block to execute php - like this answer. – Richard Smith Feb 4 '18 at 15:08
  • Thanks, @RichardSmith - but I tried that also. ("Using location php as a sub location under /de/forums/") - did not work. It simply ignores it - and I have no idea why... (opened a different question regarding this here: stackoverflow.com/questions/48608224/… ) – Edward Black Feb 4 '18 at 15:49
  • Please try using simple location /de/forums blocks, without any regex. – Tero Kilkanen Feb 4 '18 at 21:16
1

Looks like it's just a combination of wrong root and location values.

  1. change this:

    location ^~ /de/forums/ {
        alias /var/www/domain.com/forum-de/;
        #also tried root
        index index.php index.html index.htm;
        try_files $uri $uri/ /de/forums/index.php?$uri&$args;
          #also tried just /index.php?$uri&$args;
    
    
    }
    

    to this:

    location /de/forums/ {
        root /var/www/domain.com/forum-de/;
        index index.php index.html index.htm;
        try_files $uri $uri/ /de/forum/index.php?$args;
    }
    
  2. and change this:

    location ~ ^/de/forums/(.+\.php)$ { 
        alias var/www/domain.com/forum-de/; 
         #also tried root    
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        include fastcgi.conf;
        fastcgi_index  index.php;
        fastcgi_param  SCRIPT_FILENAME  $request_filename;
        #also tried using the full path here
    }
    

    to this:

    location ~ ^/de/forums/(.+\.php)$ { 
        fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
        include fastcgi.conf;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME    $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO          $fastcgi_path_info;
        fastcgi_param HTTPS on;
    }
    
  3. If the above solution works for /de/forums/ duplicate and adapt for /en/forums/ .

Additional hint:

If there is more sever specific configuration that has to work differently for each app, consider building a solution where the forum is behind a reverse proxy so it can have it's own vhost file.

The logic behind this solution would be to create a separate vhost file for the forum, listening on a 127.0.0.1:8001 (for example) and then in the original vhost file add a proxy_pass for the location /de/forum to http://127.0.0.1:8001.

This way you could have a separate vhost configuration for the forum.

  • Thank you, I'll try this out as soon as possible and report back. – Edward Black Feb 13 '18 at 17:40
  • Thanks again. There are still problems. PHP-Files now load, but files don't. If I want to load an image, there is a not found - this is what the error log says: 2019/02/28 19:05:50 [error] 11545#11545: *394549 open() "/var/www/example.com/html/de/forum/styles/default/xenforo/xenforo-logo2x.png" failed (2: No such file or directory), client: 2a02:myIPhere:2f89, server: domain.com, request: "GET /de/forum/styles/default/xenforo/xenforo-logo2x.png HTTP/1.1", host: "example.com", referrer: "example.com/de/forum/install/index.php" – Edward Black Feb 28 at 18:07
  • As I stated in my edit of the question a few minutes ago, I found the part that breaks the functionality. it is: ' if (!-e $request_filename) { # Don't use $uri here, see github.com/yandex/gixy/issues/77 rewrite /wp-admin$ $scheme://$host$request_uri/ permanent; rewrite ^(/[^/]+)?(/wp-.*) $2 last; rewrite ^(/[^/]+)?(/.*\.php) $2 last; }' This is part of the Wordpress-Rewrites. Unfortunately, even if I move the forum to a new vhost (via proxypass), it still breaks when the code is in the main server block. Any ideas why? – Edward Black Feb 28 at 19:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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