nginx with a separate root per subdirectory - php

I'm trying to setup nginx so each path has it's own root directory. This is working for the most part, however POST to php-fpm a throwing a 405.
Currently trying:
location ^~ /foo {
alias /www/foo;
#index index.php;
try_files $uri /www/foo/index.php$request_uri;
access_log /var/log/nginx/foo.log main;
error_log /var/log/nginx/foo.log error;
}
location ^~ /bar {
alias /www/bar;
#index index.php;
try_files $uri /www2/bar/index.php$request_uri;
access_log /var/log/nginx/bar.log main;
error_log /var/log/nginx/bar.log error;
}
location ~ \.php {
set $php_root /usr/local/deploy/baz/current/web;
if ($request_uri ~* /foo ) {
set $php_root /www/foo/current/web;
}
if ($request_uri ~* /bar ) {
set $php_root /www2/bar/current/web;
}
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $php_root$fastcgi_script_name;
fastcgi_param DOCUMENT_ROOT $php_root;
include fastcgi_params;
}

Alias does not append location path to the file path. Check the logical flow. If server root is at /var/www/public, foo is located at /var/www/foo/public, bar is located at /var/www/bar/public. Then, this will be the easy config :
server {
root /var/www/public;
...
location /foo {
root /var/www/foo/public;
}
location ~ /foo/.+\.php$ {
fastcgi_param SCRIPT_FILENAME /var/www/foo/public$fastcgi_script_name;
# rest of fastcgi
}
location /bar {
root /var/www/bar/public;
}
location ~ /bar/.+\.php$ {
fastcgi_pass 127.0.0.1:9000;
fastcgi_param SCRIPT_FILENAME/var/www/bar/public$fastcgi_script_name;
# rest of fastcgi
}
} # ends server
If you want to use PHP in one directive then :
server {
...
root /var/www/public;
...
location /foo {
root /var/www/foo/public;
}
location /bar {
root /var/www/bar/public;
}
location ~ \.php$ {
set $php_root /var/www/public;
if ($request_uri ~* /foo) {
set $php_root /var/www/foo/public;
}
if ($request_uri ~* /bar) {
set $php_root /var/www/bar/public;
}
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;
}
...
} # server block ends
Usage of alias -- http://nginx.org/en/docs/http/ngx_http_core_module.html#alias
Nginx modifier -- http://nginx.org/en/docs/http/ngx_http_core_module.html#location
If you need more number of path, then you have to symlink.

Related

NGINX config for php backend and JS frontend

I'm trying to serve my frontend app under /, but have requests for /oauth2 pass off to a php backend. Here is my latest nginx config attempt:
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location /oauth2 {
root /application/public;
index index.php;
try_files $uri $uri/ /index.php$is_args$args;
#try_files /index.php$is_args$args =404;
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass dockerphp;
fastcgi_index index.php;
}
}
location / {
try_files $uri $uri/ /index.html;
}
}
I've tried just about every combination of config I can think of and just can't get it to work. Most of the time I end up with 404s.
Both my nginx and php docker containers have the same /application directory mounted.
With the above config, any requests to /oauth2/blah are being picked up by the location block at the bottom and therefore back to my frontend. This is probably my biggest problem - the /oauth2 location block to my mind is more "specific" so why isn't it "winning"?
I tried the commented out try_files line instead (to see whether index.php being the "fallback" value had an effect on specificity), and nginx just started downloading the index.php file rather than passing on the request. Help?
This is the approach that I use:
attempt to serve js / static pages first
if 1.) fails, pass to PHP backend
define a location for handling .php
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location / {
try_files $uri $uri/ #php;
}
location #php {
root /application/public;
index index.php;
try_files $uri $document_root/index.php?$query_string;
# $document_root/index.php is the important part due to how root and alias directives work
}
location ~ \.php$ {
include /etc/nginx/fastcgi_params;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_pass dockerphp;
fastcgi_index index.php;
}
}
The location /oauth2 only wins when the URL you try is exactly website.com/oauth2. Add ^~ and the route will win all of the URLs starting with /oauth2, like this:
location ^~ /oauth2 {
For reference I eventually found a simple working solution (below).
upstream dockerphp {
server backendphp:9000;
}
server {
listen 80;
server_name localhost;
index index.html;
root /application/frontend/build;
location / {
try_files $uri $uri/ /index.html;
}
location /oauth2 {
try_files $uri $uri/ #php;
}
location #php {
include /etc/nginx/fastcgi_params;
fastcgi_pass dockerphp;
fastcgi_param SCRIPT_FILENAME /application/public/index.php;
}
}

nginx add_header on specific URI to PHP app with front controller

I have a pretty standard setup with a symfony2-like app with a front controller, running on nginx 1.10 and Centos7. It all works as expected, blocks where expected etc.
server {
listen 80;
root /opt/my/code/web;
index app.php;
charset utf-8;
location / {
try_files $uri $uri/ /app.php$is_args$args;
}
# pass the PHP scripts to php5-fpm
location ~ ^/app\.php(/|$) {
# problem here
location ~ ^/recording {
add_header Content-Type audio/x-wav;
}
fastcgi_split_path_info ^(.+?\.php)(/?.*)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index app.php;
include /etc/nginx/fastcgi_params;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Prevents URIs that include the front controller. This will 404:
internal;
}
# return 404 for all other php files not matching the front controller
location ~ \.php$ {
return 404;
}
}
I have a few issues but the main one is that I want special handling for a URI matching /recording but it still has to go through the front controller. (This is not debatable, it HAS to go through the front controller and modify a response header if the URI matches /recording)
Since try_files redirects to location ~ ^/app\.php(/|$) nginx's $uri parameter used for location matching gets updated to /app.php, so any nested locations won't work.
I cant use add_header outside of the front controller block because any add_header directives get dropped on an internal redirect.
Obviously I can't use location if with add_header either.
This is easy in apache, but the only remote solution I have found uses a third party lua module and the installation docs are a bit thin on that and the thought of compiling that in from source on centos is giving me heart palpitations.
If internal redirect bother us, lets remove internal redirect :) You can solve it easy with fastcgi config duplication
server {
listen 80;
root /opt/my/code/web;
index app.php;
charset utf-8;
location / {
try_files $uri $uri/ /app.php$is_args$args;
}
location ~ ^/recording {
add_header Content-Type audio/x-wav;
fastcgi_pass unix:/var/run/php-fpm.sock;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_NAME /app.php;
fastcgi_param SCRIPT_FILENAME $document_root/app.php;
}
# pass the PHP scripts to php5-fpm
location ~ ^/app\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/?.*)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index app.php;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
# Prevents URIs that include the front controller. This will 404:
internal;
}
# return 404 for all other php files not matching the front controller
location ~ \.php$ {
return 404;
}
}
Second solution works only if you know content type of all other requests. We can use variables. (btw, I don't suggest this solution because harder to support and not cute :))
server {
listen 80;
root /opt/my/code/web;
index app.php;
charset utf-8;
location / {
try_files $uri $uri/ /app.php$is_args$args;
set $ct "text/html";
}
location ~ ^/recording {
try_files $uri $uri/ /app.php$is_args$args;
set $ct "audio/x-wav";
}
# pass the PHP scripts to php5-fpm
location ~ ^/app\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/?.*)$;
fastcgi_pass unix:/var/run/php-fpm.sock;
fastcgi_index app.php;
include /etc/nginx/fastcgi_params;
fastcgi_param DOCUMENT_ROOT $realpath_root;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
add_header "Content-Type $ct;
# Prevents URIs that include the front controller. This will 404:
internal;
}
# return 404 for all other php files not matching the front controller
location ~ \.php$ {
return 404;
}
}

PHP, Nginx: Call {name}.php when url is sitename.com/{name}

Use nginx server.
What and how should be done when the URL is sitename.com/test and there is a call to test.php
For example:
project structure
public_html
|
+-somedir1
| |
| +-somefiles....
+-somdir2
|
+-login.php
+-info.php
+-something.php
......
when the url is sitename.com/login... call login.php, sitename.com/info call info.php etc.
server {
listen 80 default;
root /home/prod/frontend;
index index.php index.html index.htm;
charset utf-8;
server_name ui;
access_log /var/log/nginx/ui.access.log;
error_log /var/log/nginx/ui.error.log;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
fastcgi_pass unix:/var/run/php7.0-fpm.sock;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
}
}
also i try
location / {
try_files $uri.php $uri/ /index.php?$args;
}
location / {
index $uri.php
}

aws + centos 7 + built nginx ngx_pagespeed + php-fpm = file not found

I have tried everything and have verified everything is running on the same group.
Also chown'd files to nginx:nginx and chmod'd them to 755
Here is server block
server {
listen 80;
root /var/www/example.com/public_html;
index index.php index.html index.htm;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
# Pagespeed main settings
pagespeed on;
pagespeed FileCachePath /var/ngx_pagespeed_cache;
# Ensure requests for pagespeed optimized resources go to the pagespeed
# handler and no extraneous headers get set.
location ~ "\.pagespeed\.([a-z]\.)?[a-z]{2}\.[^.]{10}\.[^.]+" { add_header "" ""; }
location ~ "^/ngx_pagespeed_static/" { }
location ~ "^/ngx_pagespeed_beacon" { }
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_intercept_errors on;
fastcgi_pass unix:/var/run/php-fpm/php-fpm.sock;
}
}
Followed this tutorial about SELinux. I am new to CentOS so I was unfamiliar with all of the security parameters.
https://www.cloudinsidr.com/content/troubleshooting-php-7-tcp-sockets-with-selinux-on-centos-7-rhelfedora/

How to correctly configure Nginx for PHP (Yii framework and Zurmo)

I am trying to setup Zurmo CRM on my local machine (Win8x64). After installing all the requirements I want to get started with the actual installation. The problem is that it seems the paths are not correctly passed from NGinx to FastCGI PHP. Here is my Nginx serve configuration:
server {
listen 80;
server_name zurmo.local;
root html/zurmo.local;
set $index "index.php";
charset utf-8;
location / {
index index.html $index;
try_files $uri $uri/ /$index?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) {
deny all;
}
location ~ \.(js|css|png|jpg|gif|swf|ico|pdf|mov|fla|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
set $fsn /$index;
if (-f $document_root$fastcgi_script_name){
set $fsn $fastcgi_script_name;
}
fastcgi_pass 127.0.0.1:9000;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fsn;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param PATH_TRANSLATED $document_root$fsn;
}
location ~ /\.ht {
deny all;
}
}
As a result, when I make a call to zurmo.local (which is added to hosts file) i get "This webpage has a redirect loop" with a URI that looks like this http://zurmo.local/app/app/ [...] /app/app/index.php If instead of $document_root$fsn and I comment the PATH_INFO and PATH_TRANSLATED than I get No input file specified. with a URI that looks like http://zurmo.local/app/app/index.php
Looking further into it, when I have added access_log html/zurmo.local/logs/access.log; the Nginx error.log shows me the following: [timestamp] [emerg] 4064#3660: CreateFile() "[path to stack]\nginx/html/zurmo.local/logs/access.log" failed (3: The system cannot find the path specified). As you can see the directory separator is not consistent.
One last note, my Nginx home directory is situated at nginx/html which is in fact a smlink to of ../home This is purely for keeping my file structure in a way that fits my day to day work.
How can I correctly configure Nginx in order to proceed (with the Zurmo installation) ?
I know this is an old question, but here is what I have done to make nginx + zurmo work.
server {
listen 80;
server_name zurmo.local;
root /home/www/zurmo.local;
access_log /var/log/nginx/zurmo.access.log main;
index index.php;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ ^/(protected|framework|themes/\w+/views) { deny all; }
location ~ /\. { deny all; access_log off; log_not_found off; }
location = /favicon.ico { log_not_found off; access_log off; }
location ~ \.(js|css|png|jpg|gif|ico|pdf|zip|rar)$ {
try_files $uri =404;
}
location ~ \.php {
fastcgi_split_path_info ^(.+\.php)(.*)$;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_read_timeout 600s;
fastcgi_send_timeout 600s;
}
}
I don't think you need the if() statement in your *.php block. In my nginx setups that's all i ever needed:
# Process PHP files
location ~ \.php$ {
fastcgi_split_path_info ^(.+\.php)(/.+)$;
# Include the standard fastcgi_params file included with nginx
include fastcgi_params;
fastcgi_param PATH_INFO $fastcgi_path_info;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass 127.0.0.1:9000;
}

Categories