I need to setup two projects under one domain(react+symfony), here is my nginx config:
server {
listen 80;
server_name domain.ltd;
rewrite_log on;
root /var/www/frontend;
access_log /var/log/nginx/project_access.log;
error_log /var/log/nginx/project_error.log;
location / {
index /index.html;
}
location /api/ {
alias /var/www/backend;
try_files $uri /index.php$is_args$args;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
}
}
root / works fine so static index.html I'm getting okay without any issues. but symfony application for /api throws an error(403 Forbidden) in nginx error.log:
32349 open() "/var/www/frontend/index.php"
For some reason alias ignored, what i'm doing wrong?
Thanks in advance
The location and the alias values should both end with a / or neither end with a /. The last parameter of the try_files statement is a URI, so you need to include the /api/ prefix.
For example:
location /api/ {
alias /var/www/backend/;
try_files $uri /api/index.php$is_args$args;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param DOCUMENT_ROOT $realpath_root;
internal;
}
}
Also, add a try_files statement to the nested location block to avoid passing uncontrolled requests to PHP. The correct value for SCRIPT_FILENAME is $request_filename which works with either root or alias.
Related
lets say I've a path like:
/var/www/myside/
that path contains two folders... let's say
/static and /manage
I'd like to configure nginx to have an access to:
/static folder on / (eg. http://example.org/)
this folder has some .html files.
/manage folder on /manage (eg. http://example.org/manage) in this case this folder contains Slim's PHP framework code - that means the index.php file is in public subfolder (eg. /var/www/mysite/manage/public/index.php)
I've tried a lot of combinations such as
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite;
location /manage {
root $uri/manage/public;
try_files $uri /index.php$is_args$args;
}
location / {
root $uri/static/;
index index.html;
}
location ~ \.php {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
fastcgi_index index.php;
fastcgi_pass 127.0.0.1:9000;
}
}
The / works correctly anyway manage doesn't. Am I doing something wrong? Does anybody know what should I change?
Matthew.
To access a path like /var/www/mysite/manage/public with a URI like /manage, you will need to use alias rather than root. See this document for details.
I am assuming that you need to run PHP from both roots, in which case you will need two location ~ \.php blocks, see example below. If you have no PHP within /var/www/mysite/static, you can delete the unused location block.
For example:
server {
listen 80;
server_name example.org;
error_log /usr/local/etc/nginx/logs/mysite/error.log;
access_log /usr/local/etc/nginx/logs/mysite/access.log;
root /var/www/mysite/static;
index index.html;
location / {
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ^~ /manage {
alias /var/www/mysite/manage/public;
index index.php;
if (!-e $request_filename) { rewrite ^ /manage/index.php last; }
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
}
The ^~ modifier causes the prefix location to take precedence over regular expression locations at the same level. See this document for details.
The alias and try_files directives are not together due to this long standing bug.
Be aware of this caution in the use of the if directive.
I'm having trouble setting up two locations in my Nginx conf file.
I had no problem having two locations before adding one with an alias.
Location / with alias doesn't work.
Location /dev without alias works.
I would like to use two aliases because I have two folders : prod and dev.
Here is my current conf :
server {
listen 80;
listen [::]:80;
server_name domain.com www.domain.com;
root /home/domain/public_html/www/;
index index.html index.htm index.php index2.php;
location / {
alias /home/domain/public_html/www/prod/;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location /dev {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
charset utf-8;
location = /favicon.ico { access_log off; log_not_found off; }
location = /robots.txt { access_log off; log_not_found off; }
location ~ /\.ht {
deny all;
}
}
What is happening is that accessing domain.com/dev/ works great but as soon as it's on the / location, I get a "no input file specified" error.
If I enter domain.com/license.txt, I can see Wordpress's license file.
If I try domain.com/index.php, I get the error.
I'm already using $request_filename to avoid root vs alias problems, any idea ?
You do not need to use alias in this scheme, but if you wish to run PHP with two separate roots, you will need to use a nested location block.
For example:
root /home/domain/public_html/www/prod;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
location ^~ /dev {
root /home/domain/public_html/www;
try_files $uri $uri/ /dev/index.php?q=$uri&$args;
location ~* \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
}
}
The first two location blocks are your /prod/ configuration, with the correct root to resolve URIs like /index.php.
The last location and nested location blocks are your /dev/ configuration. The root is set to the correct value to resolve URIs like /dev/index.php.
See this document for more.
So here's my server block
server {
listen 80;
server_name domain.tld;
root /var/www/domain.tld/html;
index index.php index.html index.htm;
location / {
}
location /phpmyadmin {
alias /var/www/phpmyadmin;
}
location /nginx_status {
stub_status on;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
browsing http://domain.tld/index.php works fine the only problem im encountering is browsing http://domain.tld/phpmyadmin/. It returns 404 yet the folder /var/www/phpmyadmin exist on the server. Viewing /var/log/nginx/error.log, no error is being logged there yet the access to it is logged in /var/log/nginx/access.log. What could be the problem here?
The problem is that phpmyadmin is a PHP application and your location ~ \.php$ block does not point to the correct document root.
You need to construct two PHP locations with different document roots.
If phpmyadmin is located at /var/www/phpmyadmin, you do not need an alias directive, as a root directive will be more efficient. See this document.
server {
listen 80;
server_name domain.tld;
root /var/www/domain.tld/html;
index index.php index.html index.htm;
location / {
}
location /nginx_status {
stub_status on;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ^~ /phpmyadmin {
root /var/www;
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
}
The location ^~ /phpmyadmin is a prefix location that takes precedence over the regex location normally used to process .php files. It contains a location ~ \.php$ block which inherits a value of /var/www for the document root.
It is advisable to include fastcgi_params before defining other fastcgi_param parameters otherwise your custom values may be silently overwritten.
See this document for more.
So here's my server block
server {
listen 80;
server_name domain.tld;
root /var/www/domain.tld/html;
index index.php index.html index.htm;
location / {
}
location /phpmyadmin {
alias /var/www/phpmyadmin;
}
location /nginx_status {
stub_status on;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
browsing http://domain.tld/index.php works fine the only problem im encountering is browsing http://domain.tld/phpmyadmin/. It returns 404 yet the folder /var/www/phpmyadmin exist on the server. Viewing /var/log/nginx/error.log, no error is being logged there yet the access to it is logged in /var/log/nginx/access.log. What could be the problem here?
The problem is that phpmyadmin is a PHP application and your location ~ \.php$ block does not point to the correct document root.
You need to construct two PHP locations with different document roots.
If phpmyadmin is located at /var/www/phpmyadmin, you do not need an alias directive, as a root directive will be more efficient. See this document.
server {
listen 80;
server_name domain.tld;
root /var/www/domain.tld/html;
index index.php index.html index.htm;
location / {
}
location /nginx_status {
stub_status on;
access_log off;
}
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
location ^~ /phpmyadmin {
root /var/www;
location ~ \.php$ {
try_files $uri =404;
include fastcgi_params;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
}
The location ^~ /phpmyadmin is a prefix location that takes precedence over the regex location normally used to process .php files. It contains a location ~ \.php$ block which inherits a value of /var/www for the document root.
It is advisable to include fastcgi_params before defining other fastcgi_param parameters otherwise your custom values may be silently overwritten.
See this document for more.
I want to override the permissions to /folder/script.php and have the following rules:
location ^~ /folder/script.php{
allow all;
} #shouldn't ^this one with ^~ override the others?
location ~ /folder/(.+)\.php$ {
deny all;
return 404;
allow 127.0.0.1;
}
location ~ ^/folder {
return 404;
}
location / {
# First attempt to serve request as file, then
# as directory, then trigger 404
try_files $uri $uri/ =404;
server_name_in_redirect off;
}
location ~ \.php$ {
try_files $uri =404;
#fastcgi_split_path_info ^(.+\.php)(/.+)$;
# NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini
#fastcgi_pass /tmp/php5-fpm.sock;
#fastcgi_pass /var/run/php5-fpm.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
# send bad requests
fastcgi_intercept_errors on;
include fastcgi_params;
}
but whenever I access admin.php I still get a 404 error and/or the script.php file is served to download, not interpreted. Could someone explain me why? Tyvm
The commands to execute a php script are:
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
I'm not sure where you define $root_folder, normally $document_root is used. The above (or similar) code must appear in each and every location block that is expected to execute php scripts.
So your configuration should look something like this:
location / {
try_files $uri $uri/ =404;
server_name_in_redirect off;
}
location ^~ /folder { deny all; }
location = /folder/script.php {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $root_folder$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $root_folder;
fastcgi_intercept_errors on;
include fastcgi_params;
}
I have taken the liberty of simplifying your configuration a little. It seems that only the file /folder/script.php is executable within the /folder hierarchy, so an exact match (location =) is used, and /folder is denied. The allow 127.0.0.1; does nothing as it comes after the deny all.
As you can see, the fastcgi_pass 127.0.0.1:9000; directive must appear in any location container that directly handles php code. I would put some or all of these directives into a separate file and use include to pull them in at each location.
The rest of the directives have been copied across from your question, but I don't know if they are required here.