Hi all! I've been on D6+D7 for eons, now working on Backdrop. In my local Archlinux LEMP environment everything runs smoothly.
I am now staging a friend's site to a new VPS with Debian 11 / LEMP / ISPConfig. All seems to be good there, and I managed to get the site to transfer using the unzip of the Backup/Migrate into position, and the installation of the database.

BUT when the site operates it throws a 404 at every page not the index.php. Using the old index.php?q= method to navigate through it I managed to get to Clean URLs and run the test, where it tells me 

  • The clean URL test failed.
  • Clean URLs cannot be enabled.
  • Clean URLs cannot be enabled.
error_page 404 = @backdrop;
location @backdrop { rewrite ^(.*)$ /index.php?q=$1 last; } 

^^ My nginx directive, as per Backdrop docs.

Also I checked the perms, and cleaned a couple of those up, but still no difference.

Any ideas?

Accepted answer

I got it going eventually.

What I did:

  • wipe the files and database, install the BD base. It ran the installer, but after that fails with the clean urls as previously.
  • repeat above, just to make sure. This time I get 500 errors.
  • remove ISPConfig vhost. Recreate it. Checking on the PHP-FPM hooks.
  • repeat as above. Same clean urls problem.
  • write bash script to do the filesystem changes as I was getting tired of repeating them.
  • repeat, try 'new' nginx config, run bash script. Hello, clean urls are working!
  • try to migrate site using full restore from B&M, fails silently.
  • Migrate the old manual way by extracting files and database from localhost dev environ. Restore succeeds, set up paths to suit new environ. All's good!

So in order to help the community, and any other idiots wrestling with ISPConfig LEMP versus Backdrop, here's the magic sauce:

#!/bin/bash
find . -type f -exec chmod 664 '{}' \;
find . -type d -exec chmod 775 '{}' \;
chown web3:client1 .* -R
chown web3:client1 * -R

That is the bash script that I run inside the web root for Backdrop. Yes, that requires command line access. The web3:client1 is unique to my server, yours will vary. Also after running this it marks itself as not executable, so you will need to chmod +x it.

Over to ISPConfig, and in the domain/options/nginx directives, you can put the following:

location / {
try_files $uri $uri/ /index.php?$query_string;
}

 

Comments

Thanks, I had seen those, but they weren't helpful.

Can you post your full nginx config here, that would be better to debug what causing the problems. 

server {
        listen *:80;
        listen [::]:80;
        listen *:443 ssl http2;

    ssl_protocols TLSv1.3 TLSv1.2;
        listen [::]:443 ssl http2;
        ssl_certificate /var/www/clients/client1/web2/ssl/dev.silentnomorenz.com-le.crt;
        ssl_certificate_key /var/www/clients/client1/web2/ssl/dev.silentnomorenz.com-le.key;

        server_name dev.silentnomorenz.com www.dev.silentnomorenz.com;

        root   /var/www/dev.silentnomorenz.com/web/;
        disable_symlinks if_not_owner from=$document_root;

        if ($scheme != "https") {
            rewrite ^(?!/\.well-known/acme-challenge)/ https://$http_host$request_uri? permanent;
        }

        index index.html index.htm index.php index.cgi index.pl index.xhtml standard_index.html;


        error_page 400 /error/400.html;
        error_page 401 /error/401.html;
        error_page 403 /error/403.html;
        error_page 404 /error/404.html;
        error_page 405 /error/405.html;
        error_page 500 /error/500.html;
        error_page 502 /error/502.html;
        error_page 503 /error/503.html;
        recursive_error_pages on;
        location = /error/400.html {

            internal;
            auth_basic off;
        }
        location = /error/401.html {

            internal;
            auth_basic off;
        }
        location = /error/403.html {

            internal;
            auth_basic off;
        }
        location = /error/404.html {

            internal;
            auth_basic off;
        }
        location = /error/405.html {

            internal;
            auth_basic off;
        }
        location = /error/500.html {

            internal;
            auth_basic off;
        }
        location = /error/502.html {

            internal;
            auth_basic off;
        }
        location = /error/503.html {

            internal;
            auth_basic off;
        }

        error_log /var/log/ispconfig/httpd/dev.silentnomorenz.com/error.log;
        access_log /var/log/ispconfig/httpd/dev.silentnomorenz.com/access.log combined;

        location ~ /\. {
            deny all;
        }

        location ^~ /.well-known/acme-challenge/ {
            access_log off;
            log_not_found off;
            auth_basic off;
            root /usr/local/ispconfig/interface/acme/;
            autoindex off;
            index index.html;
            try_files $uri $uri/ =404;
        }

        location = /favicon.ico {
            log_not_found off;
            access_log off;
            expires max;
            add_header Cache-Control "public, must-revalidate, proxy-revalidate";
        }

        location = /robots.txt {
            allow all;
            log_not_found off;
            access_log off;
        }

        location /stats/ {

            index index.html index.php;
            auth_basic "Members Only";
            auth_basic_user_file /var/www/clients/client1/web2/web//stats/.htpasswd_stats;
            add_header Content-Security-Policy "default-src * 'self' 'unsafe-inline' 'unsafe-eval' data:;";
        }

        location ^~ /awstats-icon {
            alias /usr/share/awstats/icon;
        }

        location ~ \.php$ {
            try_files /91649c93cac3b98f5079a255ad38bec6.htm @php;
        }

        location @php {
            try_files $uri =404;
            include /etc/nginx/fastcgi_params;
            fastcgi_pass unix:/var/lib/php7.4-fpm/web2.sock;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_intercept_errors on;
        }




        error_page 404 = @backdrop;
        location @backdrop {
rewrite ^(.*)$ /index.php?q=$1 last; 
        }


}
location / {
    index index.php;                
    try_files $uri /index.php?$query_string;
    expires max;
}
location @rewrite {
    rewrite ^/(.*)$ /index.php?q=$1;
}
location ~ \.php$ {
        fastcgi_pass unix:/run/php/php7.4-fpm.sock;
        fastcgi_index index.php;
        fastcgi_read_timeout 500;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        include fastcgi_params;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
    }



      

Could you try adding above directives instead of your one see if that works ? 

Thanks, but no. Still fails the clean url test.
I am wondering if there is a PHP module that is not working? Wi;; have to dig into the CleanURL function to find out...

I know that I've had trouble with Clean URL's myself sporadically for reasons I can't recall (I seem to recall at least once, that they mysteriously resolved themselves for reasons I never understood). Maybe you have already looked at all the Clean URL issues in the forum as well, but there are a few that might be helpful. 

I'm willing to bet it's something quirky with your specific setup, I'm just not sure what else to tell you in terms of figuring it out. Hopefully, someone else will have a good idea.

Have you tried just running through the install again to make sure everything is correct?

I got it going eventually.

What I did:

  • wipe the files and database, install the BD base. It ran the installer, but after that fails with the clean urls as previously.
  • repeat above, just to make sure. This time I get 500 errors.
  • remove ISPConfig vhost. Recreate it. Checking on the PHP-FPM hooks.
  • repeat as above. Same clean urls problem.
  • write bash script to do the filesystem changes as I was getting tired of repeating them.
  • repeat, try 'new' nginx config, run bash script. Hello, clean urls are working!
  • try to migrate site using full restore from B&M, fails silently.
  • Migrate the old manual way by extracting files and database from localhost dev environ. Restore succeeds, set up paths to suit new environ. All's good!

So in order to help the community, and any other idiots wrestling with ISPConfig LEMP versus Backdrop, here's the magic sauce:

#!/bin/bash
find . -type f -exec chmod 664 '{}' \;
find . -type d -exec chmod 775 '{}' \;
chown web3:client1 .* -R
chown web3:client1 * -R

That is the bash script that I run inside the web root for Backdrop. Yes, that requires command line access. The web3:client1 is unique to my server, yours will vary. Also after running this it marks itself as not executable, so you will need to chmod +x it.

Over to ISPConfig, and in the domain/options/nginx directives, you can put the following:

location / {
try_files $uri $uri/ /index.php?$query_string;
}