Let's say I have a file named careers.php, how do I serve this file when they click a link that goes to http://example.com/careers without the file extension for both .html and .php files with nginx?
Please note that the solution has to account for query strings. For instance, the URL may be http://example.com/careers?lang=fr.
Also, I'd like the solution to also try subdirectories as well. For instance; if my folder structure on the server is /views/careers.php, I want http://example.com/careers to still serve /views/careers.php.
My current configuration looks like the following:
server {
listen 80 default_server;
root /usr/share/nginx/landing-page;
index index.php index.html;
server_name example.com;
location / {
try_files $uri $uri/ =404;
}
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
A common solution uses try_files with a named location. The existing location ~ \.php$ block is used to process .php files. Also avoid any if statements.
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^ $uri.php last;
}
location ~ \.php$ {
try_files $uri =404;
...
}
You can use try_files:
try_files $uri $uri.php $uri/ =404;
I know that this is an old post, but I feel like this was never perfectly explained or explained using the most simple solution.
Here is an example of how I accomplished this for a React Application served using nginx for my Portfolio Website hosted on Digital Ocean.
When simplified it's super easy to accomplish. The location block should look like this.
//Originally my location block was set up like this
location /chatgpt-homepage.html {
root /var/www/myportfoliowebsite.com/html/chatgpt-app-homepage/build;
}
//What needs to happen is you need to remove the .html from your location
//and
//Add try_files $uri $uri.html $uri/ =404; underneath your root section of code
//New Location Block example below
location /chatgpt-homepage {
root /var/www/myportfoliowebsite.com/html/chatgpt-app-homepage/build;
try_files $uri $uri.html $uri/ =404;
}
Related
I am trying to setup nginx to try files in the following order:
1) See if file exists directly on server
2) See if file exists as part of wordpress
3) Fallback to external server if neither 1 or 2 exist.
I have the following setup:
location / {
try_files $uri $uri/ /index.php?q=$uri&$args #proxy;
}
location #proxy {
proxy_pass https://external.website.com;
}
This doesn't work for wordpress, and nginx's try_files documentation is pretty unhelpful. I can see that whichever arg is last is the fallback, so I tried flipping the last two args, and that caused wordpress to work, but then the reverse proxy didn't work.
I think I solved it. Technically this checks the proxy first, but that's okay for what I want to do. If anyone solves the correct way, I will choose them.
location / {
try_files $uri $uri/ #proxy;
}
location #proxy {
proxy_pass https://external.website.com;
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 = #wordpress;
}
location #wordpress{
try_files $uri /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
I have this nginx vhost config:
server {
listen 8081;
server_name blocked_server;
root /home/gian/blocked_server;
access_log off;
error_log off;
index index.php index.html index.htm index.nginx-debian.html;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
location ~ / {
try_files $uri $uri /index.php;
}
}
it redirects all urls to index.php except when the url ends with .php extension.
for example this works:
http://localhost/somethingthatdontexist
but this returns a 404 and don't redirect to index.php
http://localhost/somethingthatdontexist.php
how can i redirect url with .php extension that don't exist to index.php?
I already solved the problem.
First you should comment out this line or remove this line from the snippets/fastcgi-php.conf file
try_files $fastcgi_script_name =404;
then on your virtualhost config put try_files $uri $uri /index.php; before the include snippets/fastcgi-php.conf; on the location ~\.php$ block.
the location ~\.php$ block should look like this:
location ~ \.php$ {
try_files $uri $uri /index.php;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
}
that should do the trick.
I think the comments made on the original question by #Richard Smith (https://stackoverflow.com/users/4862445/richard-smith) are very important and should be added as an answer.
Adding try_files to the .php location is the answer but it results in an error because that option is already set in the included snippet.
Simply editing /etc/nginx/snippets/fastcgi-php.conf and changing the try_files option to your desired outcome resolves the problem.
I am using the following setup to run 2 applications on the same domain. If the first application returns 404 it tries the other one (wordpress on /blog).
location /blog {
root /var/www/blog;
index index.html index.htm index.php;
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
location / {
# ...
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 =200 /blog/$uri;
}
Every page loads as expected and assets return 200 and the correct content.
But css and most images of those assets are not applied to the page, while a few work just fine.
The following is included:
include /etc/nginx/mime.types;
I understand that this is probably a bad configuration anyway but in my understanding it should still work.
Is there another configuration to achieve something similar?
EDITED:
The wordpress installation is located in /var/www/blog/blog/
I can't exactly understand the problem but I suggest you bring out that php block outside and remove blog and $args after index.php uri.
Try this one instead, let me know if this works out. :)
location /blog {
root /var/www/blog;
index index.html index.htm index.php;
try_files $uri $uri/ /index.php;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location / {
# ...
proxy_intercept_errors on;
recursive_error_pages on;
error_page 404 =200 /blog/$uri;
}
I've read a moderate amount of the documentation for location blocks, but I dont have much experience with RegEx so I am a bit lost on how to pull off what I am trying to do. The following nginx config will probably explain what I want to do better than I can word it:
server {
server_name example.com www.example.com;
root /var/www/;
index index.php;
location /blog/ {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
location / {
try_files $uri #uwsgi;
}
location #uwsgi {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
}
example.com/ is being served by a bottle app through uwsgi, and so all things under this location should be routed to the bottle app and handled there. This is working fine as expected, however I am lost on how to add an 'exception' to the location rule so that example.com/blog, and everything under it ../sub1/sub2 etc. are not directed to the bottle app, but infact handled by wordpress and its PHP magic.
This seems like it should be very simple to set up, but it's proving very difficult to google simple solutions to these sort of problems, as everyone seems to bloat thier 'tutorial' configurations with tons of non-essentials that confuse a beginner.
This may need some tweaks, but you should probably use a nested location block:
server {
server_name example.com www.example.com;
root /var/www;
index index.php;
location /blog/ {
try_files $uri $uri/ /blog/index.php?$args;
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
location / {
try_files $uri #uwsgi;
}
location #uwsgi {
include uwsgi_params;
uwsgi_pass unix:/tmp/uwsgi.sock;
}
}
Notice that the default URI is changed to /blog/index.php which is hopefully where all of your WordPress files are located.
So I've got 2 routes, and the first one doesn't stop the route matching, as the docs say it should:
location ^~ /p/ {
root /www/domain.com/;
try_files $uri $uri/ /path/index.html;
}
location ^~ /v/ {
root /www/domain.com/;
try_files $uri $uri/ /path/index.html;
}
location ^~ / {
root /www/domain.com/php_www/;
try_files $uri $uri/ /index.php;
location ~* \.(?:php|html)$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include /etc/nginx/fastcgi_params;
}
auth_basic "Staging";
auth_basic_user_file /www/.htpasswd;
}
So if I have a url like this:
http://domain.com/p/1234567890
It matches the last route and not the first route. The problem surfaced because one of our guys added a page to the application:
http://domain.com/privacy
This was picked up by the FIRST route?? Which is where the problem is coming from.
The problem I'm having is with ^~. In the docs, it says that once this matches, it will stop matching, however the last route is always the one that loads.
Any ideas?
Upgraded to latest nginx, and re-ordered some of the directives and everything is working now.