I have a trouble to setup my nginx.conf for my symfony application. I want to setup a route /section/upload/ that allows to increase the size of the client_max_body_size (~100M, standard client_max_body_size = 25M)
http {
### ....
client_max_body_size 25M;
server {
location / {
try_files $uri /index.php$is_args$args;
location /section/upload {
client_max_body_size 100M;
try_files $uri /index.php$is_args$args;
}
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
### ... specific fastcgi_param needed by my symfony application
### like : fastcgi_param APP_ENV prod;
}
}
}
I get an error when I send a file larger than 25M on the /section/upload route. To avoid this I have to put the parameter client_max_body_size=100M in location ^/index.php(/|$).
I think try_files doesn't follow my client_max_body_size, is it normal and is it good/safe to setup like that ?
The try_files directive rewrites the URI to /index.php which is then processed in a different location. To set a different value for client_max_body_size, you will need to process /index.php within the location /section/upload block.
For example:
location / {
try_files $uri /index.php$is_args$args;
}
location /section/upload {
client_max_body_size 100M;
try_files /index.php =404;
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
include fastcgi_params;
}
location ~ ^/index\.php(/|$) {
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
}
The try_files statement is changed so that /index.php appears as a file parameter and not a URI parameter. Most of the FastCGI directives are also required. See this document for details.
Related
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.
server {
listen 80;
server_name ~^(?<cc>.+?).local.solar.bc.digital$;
client_max_body_size 1m;
root /home/vagrant/sites/$cc/_www/;
index index.html index.htm index.php;
error_page 404 /index.php;
access_log /var/log/nginx/$cc-access.log;
error_log /var/log/nginx/$cc-error.log;
charset utf-8;
sendfile off;
location / {
root /home/vagrant/sites/$cc/_www/php/;
try_files $uri $uri/ /index.php?$query_string;
}
location /shop/ {
# root /home/vagrant/sites/$cc/_www/bcshop/;
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
fastcgi_index index.php;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_param APP_ENV dev;
fastcgi_param PLATFORM_ENVIRONMENT local;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
location ~ /\.ht {
deny all;
}
}
Right, given the config above. If you see what I am trying to do, know that it's not working!
Some details:
I have the general 'root', because without I get errors.
This is on a local VM used for development. We have a deployment tool locally that for each project (refer to $cc variable in the config above), it can deploy up to two apps. Not necessarily both are deployed for each project. The first app is deployed in /home/vagrant/sites/$cc/_www/php, the second one in /home/vagrant/sites/$cc/_www/bcshop (but I can make it shop - you'll see why from the config)
Both apps run on Drupal, so the way the load is the same. I simply can't make them work. I get file not found for both with most of the small variants I've tried.
When I place the second app in /home/vagrant/sites/$cc/_www/shop (rather than /home/vagrant/sites/$cc/_www/bcshop) I can get its homepage to load, but nothing else.
When I disregard the second app, and concentrate on the first, I can simply have a general root set to /home/vagrant/sites/$cc/_www/php and remove the local root from location /. That works. But it doesn't when it's specified as local root. In this case, in fact, I get this error in the logs: "FastCGI sent in stderr: "Primary script unknown" while reading response header from upstream". This only for the first app.
If you wonder why the general root is set to that value, it's because I get an error in the logs if the general root is not verifiable for the location being matched. Makes sense?
I think I've covered pretty much all of what I've done in summary.
Thoughts?
I am not an expert at all with nginx, so I am going by trial and errors, with the help of the docs and other questions answered on here. But so far, no joy.
Thanks all.
You have PHP files in both the _www/bcshop/ path and the _www/php/ path. If you would like to use one common location ~ \.php$ for both applications, then the URI for each application will need to be prefixed by /bcshop and /php respectively. That is, both applications appear to run in a subdirectory.
I suspect that you would like to use /shop prefix for one application, and the / prefix for the other. in which case two location ~ \.php$ blocks will be required.
One application runs from the server root:
root /home/vagrant/sites/$cc/_www/php;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
try_files $uri /index.php;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
...
}
And one application runs with a URI prefix of /shop but located in the subdirectory _www/bcshop:
location ^~ /shop {
rewrite ^/shop(?:/(.*))?$ /bcshop/$1 last;
}
location ^~ /bcshop/ {
internal;
root /home/vagrant/sites/$cc/_www;
try_files $uri /shop/index.php?$query_string;
location ~ \.php$ {
try_files $uri /shop/index.php;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $request_filename;
...
}
}
The ^~ modifier ensures that the location block takes precedence over the regular expression location block above. See this document for details.
Although the external URI prefix is /shop, it is silently rewritten to /bcshop so that we can continue to use the root directive. There is an alias directive, but it has issues with try_files and is tricky to use with PHP.
Based on the answer by #RichardSmith, I come up with my own variant (which is working fine). Simply because repeating the block for location ~ \.php$ was doing my head in.
...
...
root /home/vagrant/sites/$cc/_www/;
...
...
location / {
set $actual_root /home/vagrant/sites/$cc/_www/php/;
set $fastcgi_index /index.php;
root $actual_root;
try_files $uri $uri/ $fastcgi_index?$query_string;
}
location /shop/ {
set $actual_root /home/vagrant/sites/$cc/_www/;
set $fastcgi_index /shop/index.php;
root $actual_root;
try_files $uri $uri/ $fastcgi_index?$query_string;
}
location ~ \.php$ {
root $actual_root;
fastcgi_index $fastcgi_index;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME $actual_root/$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param APP_ENV dev;
fastcgi_param PLATFORM_ENVIRONMENT local;
fastcgi_read_timeout 300;
fastcgi_buffers 16 16k;
fastcgi_buffer_size 32k;
}
...
...
My Nginx conf file :
location / {
try_files $uri $uri/ /index.php?url=$uri;
}
## PHP conf in case it's relevant
location ~ \.php$ {
fastcgi_pass unix:/var/run/php/php7.0-fpm.sock;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include /etc/nginx/fastcgi.conf;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
Trying the following URL : http://example.org/login :
expected behavior :
http://example.org/index.php?url=login
actual behavior :
http://example.org/index.php?url=/login
Use a named location and an internal rewrite. For example:
location / {
try_files $uri $uri/ #rewrite;
}
location #rewrite {
rewrite ^/(.*)$ /index.php?url=$1 last;
}
See this document for more.
I am trying to use different directory from where to serve the files, but have been unsuccessful. /var/www/site.app/public is where the root, but I want to serve news from /var/www/news/api instead, while having URL http://site.app/news/123, from which I want to remove the news part, because otherwise it would map to /var/www/news/api/news/123.
Judging by the debug logs, it seems that it gets rewritten correctly when first testing all location blocks, but after it is done rewritting, it goes through all of them again, and ends up serving content with location block /.
Here is my configuration file I have.
server {
listen 80;
server_name site.app;
root /var/www/site.app/public;
rewrite_log on;
error_log /var/log/nginx/error.log debug;
index index.php index.html;
location / {
try_files $uri $uri/ index.php?$query_string;
}
location /news/ {
root /var/www/news/api;
rewrite ^/news/(.*) /api.php?_=$1;
index index.php index.html;
}
location ~ \.(hh|php)$ {
try_files $uri /index.php =404;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
The root directive in your /news/ location currently does nothing. You are rewriting the URI to /api.php which then hits your \.(hh|php)$ location, which inherits the root from the parent server container.
You need a distinct location for /api.php, possibly /news/api.php. In which case you can construct a separate location block (possibly nested within /news/) where you can place fastcgi_pass code using the different root.
So this is not ideal solution, but it works. By default it would still allow access to api.php, but I am denying access to it by checking if the URL contains /news/
server {
listen 80;
server_name site.app;
root /var/www/site.app/public;
index index.php index.html;
location / {
try_files $uri $uri/ index.php?$query_string;
}
location = /api.php {
if ($request_uri !~ ^/news/) {
return 444;
}
root /var/www/site.app/news/;
try_files $uri $uri/ /api.php?$query_string =408;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location /news/ {
rewrite ^/news/(.*) /api.php?$1;
}
location ~ \.(hh|php)$ {
try_files $uri /index.php =407;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
}
I have a Symfony2 application running alongside WordPress - mysite.com/blog routes to my /var/www/mysite/wordpress/ directory and everything else routes to /var/www/mysite/symfony:
server {
listen 80;
server_name mysite.com
location / {
try_files $uri /app.php$is_args$args;
}
location ~ ^/app\.php(/|$) {
fastcgi_pass 127.0.0.1:9000;
fastcgi_split_path_info ^(.+\.php)(/.*)$;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
internal;
}
location /blog {
root /var/www/mysite/wordpress;
rewrite ^/blog/(.+)$ /$1 break;
try_files $uri $uri/ /blog/index.php?q=$uri&$args;
index index.php;
location ~ \.php {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_split_path_info ^(?:\/blog)(.+\.php)(.*);
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
}
Everything works fine, except the WordPress admin (mysite.com/blog/wp-admin/) gives me a 404 error. Visiting mysite.com/blog/wp-admin/index.php works as expected, so it looks like the index index.php line is not working. What could be the issue here?
You should use alias instead of root directive:
location ^~ /blog {
alias /var/www/mysite/wordpress;
index index.php;
try_files $uri $uri/ /blog/index.php?q=$uri&$args;
location ~ \.php$ {
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_split_path_info ^(?:\/blog)(.+\.php)(.*);
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
You need to edit the nginx server Configuration.
# WordPress single blog rules.
# Designed to be included in any server {} block.
# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
try_files $uri $uri/ /index.php?$args;
}
# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
# Directives to send expires headers and turn off 404 error logging.
location ~* ^.+\.(ogg|ogv|svg|svgz|eot|otf|woff|mp4|ttf|rss|atom|jpg|jpeg|gif|png|ico|zip|tgz|gz|rar|bz2|doc|xls|exe|ppt|tar|mid|midi|wav|bmp|rtf)$ {
access_log off; log_not_found off; expires max;
}
# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-wp-super-cache.conf;
#include global/wordpress-w3-total-cache.conf;
# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)
include fastcgi.conf;
fastcgi_index index.php;
# fastcgi_intercept_errors on;
fastcgi_pass php;
}
More about this here:
http://codex.wordpress.org/Nginx#General_WordPress_rules
So, if you allege that /blog/wp-admin/index.php works, but /blog/wp-admin/ doesn't, perhaps just conditionally append index.php, if need be?
+ rewrite ^/blog/wp-admin(/)?$ /wp-admin/index.php break;
rewrite ^/blog/(.+)$ /$1 break;
So, what do the logs say in regards to your 404? I think this might be related to the fact that the index directive causes "an internal redirect", thus I would not be surprised if your 404 ends up being generated through the / instead of the /blog location.