I have two directories, /home/php/www/public/ and /home/php/www/private/ and I would like to serve which one depending on the first part of the uri.
I would like /foo/ to act 'normally' in that it should serve which ever file is in the location, for example mysite.com/about would serve /public/about.php. However /private/ would always serve a single file no matter the request, for example mysite.com/private/foo, mysite.com/private/bar and mysite.com/private/foo/test would all serve /private/app.php.
I am probably in the 100s of different variations from what I have seen here and in other googles but being very new to all of this can't seem to piece together exactly what I need. After a few days of trial and error I am close to what I am after, mysite.com/about serves /public/about.php correctly and mysite.com/private/whatever gets /private/app.php but it doesn't execute it, it serves it as a download instead.
Here is what I have so far:
server {
listen 80;
listen [::]:80;
root /home/php/www/public;
index index.php;
server_name mysite.com;
location /private/ {
alias /home/php/www/private;
try_files /app.php =404;
location ~ [^/]\.php(/|$) {
# location ~ \.php$ {
# fastcgi_split_path_info ^(.+\.php)(/.+)$;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
# fastcgi_index app.php;
# fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# include fastcgi_params;
# return 302 https://google.com;
}
}
location / {
try_files $uri $uri.html $uri/ #extensionless-php;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
location #extensionless-php {
rewrite ^(.*)$ $1.php last;
}
location ~ /\.ht {
deny all;
}
}
If I replace everything inside the location /private/ block with just return 302 https://google.com it redirects successfully to google.com, so I know this location block is being returned but putting the same thing inside the location ~ \.php$ inside location /private/ nothing happens so to me it looks like it is not hitting this block, what am I missing? There aren't any errors in /var/log/nginx/error.log relating to this.
Try:
location /private/ {
root /home/php/www/private;
try_files /app.php =404;
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php7.2-fpm.sock;
}
Use root rather than alias as you are not trying to alias the original request. The file was downloaded because of the unnecessary nested location block.
Related
My structure project
- index.php
- abc.php
- folder/
---- def.php
My nginx.conf
server {
listen 80 default_server;
root /var/www/public;
index index.html index.htm index.php;
server_name _;
location / {
try_files $uri $uri/ /index.php$is_args$args;
}
location /index.php {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
}
How can I change nginx.conf to use domain/abc for href instead of domain/abc.php
Thanks!
This is commonly called "extensionless PHP", there are many solutions, of which this is just one:
location / {
try_files $uri $uri/ #php;
}
location #php {
try_files $uri.php $uri/index.php /index.php =404;
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
If you want URIs ending in .php to work too, add:
location ~* ^(.*)\.php$ { return 301 $1$is_args$args; }
The high-performance solution is simply specifying the desired location, and map it to the corresponding PHP script.
location = /abc {
include snippets/fastcgi-php.conf;
fastcgi_param SCRIPT_FILENAME $document_root/abc.php;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
This will ensure that /abc is processed by script /abc.php.
If you want to also "hide" access to /abc.php, you can add:
location = /abc.php {
return 404;
}
Why this is fast, is because the exact matching (with equals sign) involves no prefix matching and no regular expression processing.
Moreover we don't need to use try_files (it has performance issues). Specifically, if using the config from the answer by #RichardSmith, it may yield up to 5 unnecessary file existence checks for an arbitrary request, and 3 file existence checks for every request to /abc.
I have a nginx configuration for a react app. I however would also like to include a sitemap.php that I build dynamically with php.
So here is my nginx config:
server {
listen 80;
listen [::]:80;
server_name mysite.com;
index index.html index.htm;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
location /sitemap.xml {
alias /var/www/web-app/public/sitemap.php;
}
location / {
root /var/www/web-app/public;
try_files $uri $uri/ /index.html;
default_type "text/html";
}
}
The snippets file consist of this:
# regex to split $uri to $fastcgi_script_name and $fastcgi_path
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Check that the PHP script exists before passing it
try_files $fastcgi_script_name =404;
# Bypass the fact that try_files resets $fastcgi_path_info
# see: http://trac.nginx.org/nginx/ticket/321
set $path_info $fastcgi_path_info;
fastcgi_param PATH_INFO $path_info;
fastcgi_index index.php;
include fastcgi.conf;
Also, this is hosted on an Ubuntu 16.04 digitalocean VPS.
My react app still loads fine. It is based on the index.html in my site root (/var/www/web-app/public). If I put test.php in the public folder, I get a 404 error. For my sitemap.xml alias, it forwards correctly to sitemap.php (also in public) but the php does not render.
So my two biggest issues here:
1. Why am I getting a 404 on /mysite.com/test.php?
2. And why is my php not rendering when it does work? (i.e. sitemap.php)
You are missing a root statement for your location ~ \.php$ block, so your PHP files will not be found. As this seems to be a common root with the location / block, simply move the statement up to server block scope:
root /var/www/web-app/public;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
}
location / {
try_files $uri $uri/ /index.html;
default_type "text/html";
}
There are a number of ways to redirect /sitemap.xml to /sitemap.php, but a rewrite...last will be simplest and invisible to users:
location = /sitemap.xml {
rewrite ^ /sitemap.php last;
}
See this document for location syntax, and this one for the rewrite directive.
I'm trying to rewriting /assets/* -> to /theme/theme_1/*.
The rewrite url works with all files except .php-files.
Example file structure:
/theme/theme_1/images/image.jpg
/theme/theme_1/images/user.jpg
/theme/theme_1/ajax/register.php
/theme/theme_1/ajax/read.php
The problem is the PHP-files, I get a 404 with this url:
wget http://example.com/assets/ajax/read.php.
File is found (200) using full path http://example.com/theme/theme_1/ajax/read.php
All other file works fine (200):
wget http://example.com/assets/images/image.jpg
nginx config:
server {
listen 80 default_server;
root /var/www/html;
index index.php index.html
server_name mysite.com;
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location /assets {
rewrite ^/assets/(.*) /theme/theme_1/$1 break;
}
location / {
try_files $uri $uri/ /index.php?$args;
}
}
Okie you should try this
location /assets/ {
alias /var/www/html/theme/theme_1/;
}
If that doesn't work then try
location /assets/ {
alias /var/www/html/theme/theme_1/;
try_files $uri $uri/ /index.php?$args;
}
Edit-1
On second look I realize the previous answer won't work as ~ \.php { block will catch everything with php extension and the other assets block can never get called. So the solution is to nest the rewrite inside the php block. So use
location ~ \.php$ {
rewrite ^/assets/(.*)$ /theme/theme_1/$1;
include snippets/fastcgi-php.conf;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
I have been trying to configure multiple webapp on my nginx webserver but I can't get working one Laravel app that requires $document_root set to laravel public folder.
I am currently trying to configure it using alias directive but for an obscure reason this doesn't work. Here is what I am trying to do.
# Default server configuration
#
server {
listen 80;
# SSL configuration
#
listen 443 ssl;
error_log /var/log/nginx/error.log warn;
ssl_certificate /etc/nginx/ssl/server.crt;
ssl_certificate_key /etc/nginx/ssl/server.key;
set $root_path '/var/www/html';
root $root_path;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html index.php;
server_name localhost;
location /paperwork {
alias /var/www/html/paperwork/frontend/public;
try_files $uri $uri/;
#location ~ \.php {
# fastcgi_split_path_info ^(.+\.php)(.*)$;
# fastcgi_pass unix:/var/run/php5-fpm.sock;
# include /etc/nginx/fastcgi_params;
# #fastcgi_param SCRIPT_FILENAME /var/www/html$fastcgi_script_name;
# #fastcgi_intercept_errors on;
#}
}
#location #paperwork {
# rewrite /paperwork/(.*)$ /paperwork/index.php/$1 last;
#}
location / {
}
location /wallabag {
try_files $uri $uri/ /index.php;
}
location /laverna {
try_files $uri/ /index.php;
}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
location ~ \.php$ {
# With php5-cgi alone:
#fastcgi_pass 127.0.0.1:9000;
# With php5-fpm:
fastcgi_split_path_info ^(.+\.php)(/.+)$;
#try_files $uri $uri/ =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
location ~ /\.ht {
deny all;
}
}
To test my "alias" config I put a 'test.php' files in /var/www/html/paperwork/frontend/public/test.php and tried to access it via https://IP/paperwork/test.php. I get a 404 error and nothing in nginx error log.
If I try https://IP/paperwork/frontend/public/test.php in browser it displays the test.php file without errors.
Nothing change if I uncomment try_files line in php location.
If I copy test.php to /var/www/html/paperwork/test2.php and access to https://IP/paperwork/test2.php the file is displayed without errors so I can see here that alias is not working as there is not a test2.php in paperwork public directory.
I can have a different behaviour if I uncomment php location inside paperwork location. With this, requests like https://IP/paperwork/test.php do not display a 404 but a blank screen.
I have been through a lot of forums / questions related to this but I couldn't get a working config for a simple task like displaying test.php...
Thanks !
I found the solution. It seems that a wrong request was sent for php files. When alias is used it is recommend to use $request_filename instead of $fastcgi_script_name.
Here is my location block :
location /paperwork {
alias /var/www/html/paperwork/frontend/public;
#try_files $uri $uri/;
location ~ \.php$ {
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
#fastcgi_intercept_errors on;
}
}
This solved my problem for my 'test.php' file which is now executed while reaching https://IP/paperwork/test.php. So alias is working and php is well executed.
I still have a problem when trying to reach 'index.php' (which is my laravel app index). File is found but instead of executing it is downloaded. So when I reach https://IP/paperwork/index.php I get a login file downloaded which is index.php file. I get same behaviour if I try /paperwork/index.php/login or /paperwork/login.
try this:
location /api/ {
index index.php index.html index.htm;
alias /app/www/;
location ~* "\.php$" {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
}
}
https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
I have my main website and wordpress in different directories on my server on which I use nginx as the web server. The main website is in /home/me/www and Wordpress is in /home/me/wordpress. I need to have them in separate directories this way for a particular reason. How do I specify this in the nginx configuration file? I currently have the following and it does not work:
location / {
root /home/me/www;
index index.php index.html index.htm;
}
location /blog {
root /home/me/wordpress;
index index.php index.html index.htm;
}
location ~ \.php$ {
set $php_root /home/me/www;
if ($request_uri ~ /blog) {
set $php_root /home/me/wordpress;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $php_root$fastcgi_script_name;
include /etc/nginx/fastcgi_params;
}
It currently returns HTTP 404 when I try to access http://mydomain/blog
Check out this question and the Nginx Manual.
Try changing your blog line to:
location ^~ /blog/ {
root /home/me/wordpress;
index index.php index.html index.htm;
}
I struggled with this for hours now and finally reached the working configurations as the following:
location /php-app {
passenger_enabled off;
alias /path/to/php-app/$1;
index index.php index.html;
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/php-app(.*)$ /index.php?q=$1 last;
}
location ~ \.php$ {
alias /path/to/php-app/$1;
rewrite ^/php-app(.*)$ $1 last;
passenger_enabled off;
fastcgi_pass unix:/tmp/php-fpm.socket;
fastcgi_index index.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME /path/to/php-app$fastcgi_script_name;
fastcgi_intercept_errors on;
}
Just adding more detail in #Nick Presta answer.
^~: If a carat and tilde modifier is present, and if this block is selected as the best non-regular expression match, regular expression matching will not take place.
Checkout These differences enter link description here