New pages return nginx 404 error page

Hey guys this is my first time working with Grav so bear with me. I finally got the Grav homepage up and running on a local Mamp server but any new page I add to the site just returns an nginx 404 error page.

I already tried most of Grav’s troubleshooting options but so far no dice. I’ve searched the forums and Google and found a couple of similar issues that where fixed by correctly configuring the nginx.conf. However I tried all kinds of different configurations but none seem to work. This is my current config file:

server {
    listen 80;
    server_name www.domain.local domain.local;
    root /domain.local;
    index index.html index.php;
    access_log /var/log/nginx/domain.access.log;
    error_log /var/log/nginx/domain.error.log;
location / {
      try_files $uri $uri/ /index.php?_url=$uri&$query_string;
    }
location ~* /(.git|cache|bin|logs|backups)/.*$ {
        return 403;
    }
location ~* /(system|vendor)/.*\.(txt|xml|md|html|yaml|php|pl|py|cgi|twig|sh|bat)$ {
        return 403;
    }
location ~* /user/.*\.(txt|md|yaml|php|pl|py|cgi|twig|sh|bat)$ {
        return 403;
    }
location ~ /(LICENSE|composer.lock|composer.json|nginx.conf|web.config|htaccess.t xt|\.htaccess) {
        return 403;
    }

location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php-fpm-www-data.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors off;
fastcgi_buffer_size 16k;
fastcgi_buffers 4 16k;
    }
}
---

I’m quite sure I have simply made a mistake somewhere but I can’t figure out where. I really hope anybody can set me straight here. Any help would be much appreciated!

When I experienced this before, I believe it was a cache issue. I had tried a couple of things to see if anything was logging to a PHP error log file or the Nginx error log, but nothing hit besides those caused by my own doing.

I had altered my PHP FPM config to the following, but it shouldn’t be necessary.

Nginx Configs

Nginx Config

...
upstream my_site {
    # This path is not important. "/var/run/someID.sock" is fine as well; /var/run is usually a symlink to /run.
    server unix:/run/php/my_site.sock;
}

Nginx PHP

    ...
    location ~ \.php$ {
            #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
            try_files $uri =404; # This line should not be necessary; it simply seeks to determine whether a file exists and if it does not, it should return a 404 error. It may return a different error if the file has an issue, but would be site visitors will only see 404, as the "=404" instructs Nginx to only return 404 for issues.
            fastcgi_split_path_info ^(.+\.php)(/.+)$;
            include fastcgi.conf; # This can also be "include fastcgi_params;", just check the contents of the two files. They are usually the same.
            fastcgi_intercept_errors on; # This also should not make a difference in terms of loading
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass my_site; # This passes the PHP request to the upstream location given above; it would be the same as "fastcgi_pass unix:/var/run/php-fpm-www-data.sock;"
    }

The configuration looks proper, as long as the FPM configuration is also properly setup and is utilizing the ‘/var/run/php-fpm-www-data.sock’ file, but I am guessing if your homepage is loading properly, then that is not the issue either.

How to Clear Cache

Via SSH

cd /path/to/install
bin/grav clear-cache

Via FTP

Delete the contents of the cache directory

Via Admin

On the Dashboard tab, clearing the site’s cache can be found in the upper right hand corner and is labeled “Clear Cache”.

I would strongly presume it is the Grav cache and clearing it should show your subpages. If you clear it, are there any changes in the subpage 404 errors?

Hi @thwright,

Thank you for the reply I tried clearing the cache via bin/grav clear-cache in the terminal. Sadly this hasn’t fixed my subpages, yet, still getting the good ol’ 404 errors. I should note I reinstalled Grav again and this time changed nothing but my root and server name in the default nginx.conf file.

Could it be that I made an error in setting the root or would that have broken more than just the subpages?

Also I don’t seem to have a file called php.ini should I create one?

Good to know it is not a caching issue! I have some general ideas but after that, I would need some more information.

Upon reviewing your config

Reading over your original config, I looked over this the first time and reading it again, I’m seeing the following.

try_files $uri $uri/ /index.php?_url=$uri&$query_string;

Change that to the following.

try_files $uri $uri/ /index.php?$query_string;

Does this resolve your 404 issue?


In response to your most recent post

(and if the above has already been resolved)

You should have a php.ini file. You can run the following to determine what your CLI’s PHP ini file is.

 php -i | grep -i loaded

That should give you the path to that file. To get your FPM service’s PHP ini file (where on my Ubuntu 16.04 server, my PHP-FPM .ini file is located at /etc/php/7.0/fpm/php.ini), you can do the following. Create a phpinfo script and perform a find on the page for Loaded which should tell you the path of your php.ini file. In general though, PHP should load default values.

Another area you could check is your PHP-FPM pool configuration’s php_admin_value[open_basedir] value. You would want to make sure that your website’s install directory is in the list of paths. This is found on my Ubuntu 16.04 server at /etc/php/7.0/fpm/pool.d/site.conf. Mine for instance contains the following. (This should also be where you can verify the file name of your .sock file.)

 php_admin_value[open_basedir] = /var/www/user/public:/var/www/user/public/site0:...

Yours should look something like

 php_admin_value[open_basedir] = /domain.local:...

(There are bound to be other paths here, such as /usr/share/php5:/var/www:/dev/random:/devurandom and the like. You should be able to adjust most of those values to meet only what your server needs.

Beyond these immediate ideas, you could check your PHP error log file (which can usually be found as a file named error.log or error_log in the directory experiencing an issue), your Grav log file, or your Nginx error log file. Chances are they will contain something of use.

Nginx Config Locations

As you’ve already been mentioning your nginx configurations, this info is more for other people who would read this in the future.

These are located in the logs directory of your Grav install, or your Nginx error log file; the path to which can be found in your nginx.conf or site’s server block configuration file, or by the default path.

You can see your nginx server’s build info with nginx -V, and look for the related configs. Usually though, these values are located in /etc/nginx/nginx.conf and some subdirectory (ex. sites-available) in the nginx install for the specific files.

Alternatively, you can run a command like the following to get these values.

 grep -ir error_log /etc/nginx

Also, your website is installed in a path called /domain.local, correct?

Alrighty, I’ve set the try files to try_files $uri $uri/ /index.php?$query_string; but that didn’t change anything.

I think I found the php.ini file. I thought this should have been somewhere in my project but I found it in MAMP PRO/conf/php7.1.8.ini using the terminal line you mentioned, rookie mistake! Are you sure I need to make changes here? All the other projects I have running on MAMP seem to be working fine with the current setup.

You know I’ve been trying to get an error log but neither the Grav debugger nor the line you provided work for me (I just get “No such file in directory”). It’s weird because this has been a clean install but nothing seems to be working correctly so far. Could it simply be installed incorrectly?

  1. First I created a host in MAMP and called it project.local
  2. Then I created a root folder directly inside the MAMP folder with a similar name project.local
  3. Using composer I installed Grav with $ composer create-project getgrav/grav ~/root/grav
  4. Then I moved everything from the Grav folder to my root folder and deleted the now empty Grav folder

That’s all I did and then the problems started.

I haven’t worked with a MAMP or MEMP stackbefore, but the principles should be fairly similar. Obviously, we do not need to worry about our database with Grav. PHP should be fine as long as it is executing in the appropriate directory. (This sounds like it is the case, especially if other projects are working fine.) Once more, your PHP ini is bound to have appropriate configs; the only thing that might need changed is, say, the PHP memory_limit or max_execution_time, but being a fresh install, we can likely ignore these.

I would have to do some research to determine where a MAMP/MEMP server would store its logs, and what, if anything of importance is different between a LAMP/LEMP vs MAMP/MEMP stack in terms of web server configuration. I would think our configurations could stay unchanged for Nginx.

Grav should be fairly simple to deploy and go. The only other thing besides an error recorded in one of the three logs mentioned before I could think of would be a missing PHP extension or library, but Grav uses some pretty standard libs. (We could look to system logs but I would doubt the errors we are looking for would be thrown in there.) Are you able to access the admin dashboard and create subpages, or have you only created them in the CLI? If you can load the admin and just not the subpages, that to me would say the Grav install is working, but the Nginx server isn’t either giving/passing the PHP service a properly formatted request (causing a URL to be sent that doesn’t exist and this a 404) or else something else isn’t executing properly within PHP (and besides openbasedir in Linux, I’m not sure what that would be.)

This thread 404 not found suggests there was missing file, but if you have installed all the files, then that shouldn’t be an issue.

You got a response of no such file or directory because the directory doesn’t exist (as the command was for an Ubuntu install, not Mac). I’m guessing, based on what I’ve found, your Nginx install is located at /use/local/etc/Nginx. If you run the grep there, it should work. Based on your config, the site’s error log should be at /car/log/nginx/domain.error.log.

If you run tail -f /var/log/nginx/domain.error.log (whatever the domain is), are any errors logged while loading a subpage?

…I would think our configurations could stay unchanged for Nginx.

I have a couple of other projects running on Nginx (albeit Wordpress) that work perfectly fine so it should be fine as is, right?

Are you able to access the admin dashboard and create subpages, or have you only created them in the CLI?..

Haven’t tried the admin page yet but that’s a good idea. I’ll do another fresh install (just in case) and add the admin plugin to test that out.

This thread 404 not found suggests there was missing file, but if you have installed all the files, then that shouldn’t be an issue.

I’ll check it out, thanks but I’m fairly certain everythings there that was one of the first things I considered. I made sure to everything got installed to the correct folder.

You got a response of no such file or directory because the directory doesn’t exist (as the command was for an Ubuntu install, not Mac).

Ohh I get it I’ll look for the Nginx install and try that again.

If you run tail -f /var/log/nginx/domain.error.log (whatever the domain is), are any errors logged while loading a subpage?

Running tail -f /var/log/nginx/domain.error.log returns another file not found error. do I replace “domain” with “project.local” or just “project”?

Thanks for sticking with me on this one by the way, much appreciated!

I would think Nginx by itself is okay. The Nginx options for WordPress will be different for a WP install vs. an Nginx install, but based on what you provided in your original post, all looks well besides that change I had pointed out. The main options I would be interested in is what your PHP-FPM .sock file is, but if all is working on WordPress, I have to assume it is correct.

It will need to be changed, yes! This is why I was pointing to finding your Nginx configs. There should be a config option within Nginx’s config called error_log which points to the directory. If there isn’t one, we need to know what path Nginx was built with for its error_log variable. In Linux, this can be found by running nginx -V. Whereas -v (lowercase) only prints the version/build number of the Nginx binary, -V (capital) lists all build options that were given. One of those can be the error log path variable. (I’m not sure what the Mac equivalent for this would be, but you said running a plain nginx -V before gave you an error. I would assume that, for the most part, these CLI option flags are the same. If you can run the nginx binary with the -V flag, you may be able to get these options as well.

One reason why I am interested in the error_log and what is contained in it is that the 404 could be a “decoy” error, masking some other 500 error. While I doubt this, it is a possibility. A log entry should give us something definite to work with. If there is no log entry, and we aren’t seeing anything off in the configurations, my assumption would be something in the Grav install didn’t build the page the way it should have and thus we have an actual 404 error; this could be caused by a cache issue or perhaps some Grav admin config option. The problem is, with you using a default install, I would doubt this. I disabled an option once in my admin panel which brought my whole site down. Grav wasn’t broken, it was simply doing as it was configured to do.

Not a problem at all!

Alright I changed a couple things. First off; I broke down and did another fresh install on an apache server hoping that would cause less issues but I forgot I have MAMP configured for nginx (since that’s what most of my projects run on). So back to nginx haha.

Nginx.conf update

I Found the nginx config file within the MAMP directory. It had some of the info on my project so I copied over to my projects config file. These are the exact server info settings I have at the moment.

listen 80;
index index.html index.php;

## Begin - Server Info
root "/Users/Marc/Documents/MAMP PRO/marcruemekorf.local";
server_name marcruemekorf.local;
## End - Server Info

## Begin - Index
# for subfolders, simply adjust:
# `location /subfolder {`
# and the rewrite to use `/subfolder/index.php`
location / {
    try_files $uri =404;
}
## End - Index

It also had the php settings I was missing so I copied that over as well.

## Begin - PHP
    location ~ \.php$ {
        # Choose either a socket or TCP/IP address
        fastcgi_pass unix:/Applications/MAMP/Library/logs/fastcgi/nginxFastCGI_php7.1.8.sock;
        # fastcgi_pass 127.0.0.1:9000;

        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_index index.php;
        include /Applications/MAMP/conf/nginx/fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }
## End - PHP

Does anything seem off here? Somebody mentioned something about a missing default server attribute?

MAMP error logs

I completely forgot about how you can simply access the nginx, apache, php etc error logs within MAMP. So I checked both the nginx and php logs there but it didn’t have any errors besides the forbidden errors that have been fixed.

Grav admin plugin

I installed the admin plugin. Installation went ok but the admin page also returns a 404 error. But we kind of expected that to happen, right?

Here are my configurations for comparison. I have sanitized them.

nginx.conf
user  www-data;
worker_processes  1;
load_module modules/ngx_http_modsecurity_module.so;
load_module modules/ngx_http_fancyindex_module.so;

pid /var/run/nginx/nginx.pid;

error_log /var/log/nginx/error.log info;

events {
	worker_connections  1024;
}

http {
	include       /etc/nginx/mime.types;
	default_type  application/octet-stream;

	log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

	access_log  /var/log/nginx/access.log  main;

	sendfile        on;
	tcp_nopush     on;
	tcp_nodelay on;
	keepalive_timeout  180;
	types_hash_max_size 2048;
	client_max_body_size 32M;
	# Detect when HTTPS is used
	map $scheme $fastcgi_https {
		default off;
		https on;
	}

	# SSL
	ssl_protocols TLSv1.1 TLSv1.2;
	ssl_prefer_server_ciphers on;

	gzip  on;
        gzip_min_length 256;
        gzip_vary on;
        gzip_proxied any;
        gzip_comp_level 5;
        gzip_types
                application/atom+xml
                application/javascript
                application/json
                application/ld+json
                application/manifest+json
                application/rss+xml
                application/vnd.geo+json
                application/vnd.ms-fontobject
                application/x-font-ttf
                application/x-web-app-manifest+json
                application/xhtml+xml
                application/xml
                font/opentype
                image/bmp
                image/svg+xml
                image/x-icon
                text/cache-manifest
                text/css
                text/plain
                text/vcard
                text/vnd.rim.location.xloc
                text/vtt
                text/x-component
                text/x-cross-domain-policy;

        upstream php {
                server unix:/run/php/php7.0-fpm.sock;
        }
        upstream domainUser {
                server unix:/run/php/domainUser.sock;
        }
        
        # This include loads the website server blocks.
        include /etc/nginx/sites-enabled/*;

	# Cloudflare IPs
        set_real_ip_from 204.93.240.0/24;
        set_real_ip_from 204.93.177.0/24;
        set_real_ip_from 199.27.128.0/21;
        set_real_ip_from 173.245.48.0/20;
        set_real_ip_from 103.21.244.0/22;
        set_real_ip_from 103.22.200.0/22;
        set_real_ip_from 103.31.4.0/22;
        set_real_ip_from 141.101.64.0/18;
        set_real_ip_from 108.162.192.0/18;
        set_real_ip_from 190.93.240.0/20;
        set_real_ip_from 188.114.96.0/20;
        set_real_ip_from 197.234.240.0/22;
        set_real_ip_from 198.41.128.0/17;
        set_real_ip_from 162.158.0.0/15;
        real_ip_header     CF-Connecting-IP;

#	include /etc/nginx/conf.d/*.conf;
}
domain.conf
# This is stored in /etc/nginx/sites-available/ and is activated through a symlink in /etc/nginx/sites-enabled/.
server {
        listen 80;
        listen [::]:80;
        server_name domain.tld www.domain.tld;
        return 301 https://www.domain.tld$request_uri;
}

server {
        listen 443 ssl;
	    server_name www.domain.tld;
	    # Begin SSL Config
        ...
        # End SSL Config

        root   /var/www/user/public/web;

        index index.html index.php;

        # Begin Error Pages
        ...
        # End Error Pages
        # Begin Additional Configurations
        ...
        # End Additional Configurations
        # Begin Various Directory, Rewrite, and Nginx Extension Configurations
        ...
        # End Various Configurations

        # This line points to the PHP configuration I am using, which is included in the next spoiler.
        include /etc/nginx/conf.d/domain.conf;

        ## Begin Grav
        ## Begin - Index
        # for subfolders, simply adjust:
        # `location /subfolder {`
        # and the rewrite to use `/subfolder/index.php`
        location / {
                try_files $uri $uri/ /index.php?$query_string;
        }
        ## End - Index

        ## Begin - Security
        # deny all direct access for these folders
        location ~* /(\.git|cache|bin|logs|backup|tests)/.*$ { return 403; }
        # deny running scripts inside core system folders
        location ~* /(system|vendor) /.*\.(txt|xml|md|html|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
        # deny running scripts inside user folder
        location ~* /user/.*\.(txt|md|yaml|yml|php|pl|py|cgi|twig|sh|bat)$ { return 403; }
        # deny access to specific files in the root folder
        location ~ /(LICENSE\.txt|composer\.lock|composer\.json|nginx\.conf|web\.config|htaccess\.txt|\.htaccess) { return 403; }
        ## End - Security

}
PHP FPM conf
    # This is located in /etc/nginx/conf.d/ and points to the nginx.conf's upstream domainUser.
    location ~ \.php$ {
            #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
	try_files $uri =404;
	fastcgi_split_path_info ^(.+\.php)(/.+)$;
	include fastcgi.conf;
	fastcgi_intercept_errors on;
	fastcgi_index index.php;
	fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
            fastcgi_pass domainUser;
    }

I hope this helps provide some reference. Once more, these configurations are implemented on an Ubuntu 16.04 server running Nginx 1.13.8 and PHP-FPM 7.

Are the configurations you’ve given above extracted from a server block?

An Nginx server block is denoted by a server {} section within the configuration files. Usually, there is one for the Nginx default website and then several others either within that same nginx.conf file or within a directory, perhaps called conf.d or sites-available/sites-enabled. The server blocks within conf.d/sites-available are then included in the main nginx.conf file.

A possible explanation could be that the server is serving up the default server block, which loads the base page, but can’t process the PHP, thus causing everything else to 404. We would want to make sure that our Nginx service is loading the specific site’s, or marcruemekorf.local’s, server block. This could happen because the default document root and the site’s document root could be one and the same, thus serving the same page, but having different configurations (or none) for PHP.

Based off of what is provided above, specifically:

Quote

You would want to adjust your location / {} block to the following.

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

The PHP configuration looks proper. Once more, I am not sure if your PHP sock actually exists (as I am not looking at the machine’s terminal myself), but you could verify it by running something like the following.

ls -lah /Applications/MAMP/Library/logs/fastcgi/nginxFastCGI_php7.1.8.sock

If you get output of the file’s statistics such as owner, group, permissions, modified date, then the file should exist. You could also try the following.

stat /Applications/MAMP/Library/logs/fastcgi/nginxFastCGI_php7.1.8.sock

That should provide statistics on the file as well. If either command reports directory or file not found, then the server has not generated a PHP .sock, which would mean PHP requests are not being sent to be processed. (I only bring this up for thoroughness. If WordPress has been working fine, I am assuming this socket is being created and is serving PHP requests.)

I would start by modifying your root location block and adding it the other security-related location blocks (those which return a 403). If the site loads, then we know that was this simple configuration issue of missing the appropriate Nginx configurations for the software.

Grav Nginx Documentations

Sample Nginx Config: https://github.com/getgrav/grav/blob/master/webserver-configs/nginx.conf

Other links
Nginx | Grav Documentation
Beginner’s Guide
Beginner’s Guide
Beginner’s Guide

Verifying the services are running

The following is not necessary as it would appear that in general, your site is working. (That is to say, a request is received by Nginx and it serves up the an index file.) This would be more to verify the correct port and answer a question such as, “Is PHP-FPM actually running on port 9000?”

While I am not sure if this command exists on Mac, you could verify your services are up and running with the following command.

  netstat -plnt

To get a specific port, you could pipe this to grep. So for Nginx, we might do the following.

 netstat -plnt | grep 80

Alright, I’m back with an update on the issue and boy do I feel like a dunce. It’s important to add the try files to MAMP under “Additional parameters for location” in the Nginx tab as it will ignore the Grav Nginx config file… That’s it. I can’t believe I missed this. It’s one of the basic settings as you set up an Nginx server in MAMP.

Thank you @thwright for your time and effort. I really appreciate the support.

It’s always the simple things. :slight_smile:

1 Like