Specific fpm pool for a subdirectory - nginx

I'm trying to keep my nginx.conf simple but I'm having trouble getting a specific folder's .php files to use a different fpm than the global one.
My current configuration is
location ~ \.php$ {
# Test for non-existent scripts or throw a 404 error
# Without this line, nginx will blindly send any request ending in .php to php-fpm
try_files $uri =404;
include /etc/nginx/fastcgi.conf;
fastcgi_pass unix:/run/php-fpm.socket;
}
location /postfixadmin/ ~ \.php$ {
# Test for non-existent scripts or throw a 404 error
# Without this line, nginx will blindly send any request ending in .php to php-fpm
try_files $uri =404;
include /etc/nginx/fastcgi.conf;
fastcgi_pass unix:/run/php-fpm.vmail.socket;
}
I'm trying to get the sub folder postfixadmin (and below) to use the /run/php-fpm.vmail.socket when it comes to .php files, but otherwise globally across all other sites, use /run/php-fpm.socket. Is it possible to apply this special rule to only a single sub folder?
Unfortunately this breaks nginx and it won't load. I've tried other configs but no matter what I've tried so far just ends up either not loading or using the global socket instead.

Try this as second location:
location ~ /postfixadmin/.*\.php$ {
...
}
Or you can try nested location:
location ~ \.php$ {
location ^/postfixadmin/ {
try_files $uri =404;
include /etc/nginx/fastcgi.conf;
fastcgi_pass unix:/run/php-fpm.vmail.socket;
}
try_files $uri =404;
include /etc/nginx/fastcgi.conf;
fastcgi_pass unix:/run/php-fpm.socket;
}

Related

Is $uri/ some kind of special syntax for Nginx?

If I have the following configuration, then request to / is downloading the index.php file directly from the server root(i.e., not passing to php-fpm).
server {
listen 127.0.0.1:8080;
root /home/hasib/playground/php/;
server_name test.test;
index index.php;
location / {
try_files $uri $uri/index.php =404;
}
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php7.0-fpm.sock;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
But, if I change the try_files line to this:
try_files $uri $uri/ =404;
then by requesting /, I'm getting the expected output of index.php file(i.e., processed output of php-fpm).
I have also tried to put folder name in try_files like this:
try_files $uri /myfolder/ =404;
but that is returning 301 redirect to /myfolder/ when requesting for /, instead of trying the index.php file under myfolder directory.
So, my question is, is $uri/ some kind of special syntax for Nginx? As the other configurations always serves the files directly or redirects to myfolder. But by including $uri/ it tries to pass the index.php file to php-fpm.
Your first example is invalid. The .php file needs to be processed in another location and therefore must be the last parameter of the try_files statement. See this document for more.
Any file parameter that ends in / will check for the existence of a directory, so $uri/ is not special, but the trailing / is. This is used to invoke index processing. See this document for more.

Wordpress and NGINX /wp-admin redirect loop

My nginx.conf has a server blog containing this:
location ~ \.php$ {
root /var/www/html/blog;
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 /blog {
root /var/www/html/blog;
include /etc/nginx/mime.types;
try_files $uri $uri/ /index.php?q=$uri&$args;
}
But with these settings when I try to access /blog/wp-admin my browser gets stuck in some redirect loop.
If I change the root URLs in nginx.conf to /var/www/html, /blog/wp-admin works, but my post permalinks give me a 404 error.
My WP files are located in /var/www/html/blog. I have 'SSL Insecure Content Fixer' plugin installed because my images giving a mixed content error on my site, which has a Cloudflare page rule to always use SSL.
My WP address and WP home are both set to http://xxx/blog.
Anybody fixed something similar?
Thanks
I think that the main problem is an inconsistency with your root directive. Your PHP configuration has WordPress in /var/www/html/blog whereas your static configuration has WordPress in /var/www/html/blog/blog.
Assuming that WordPress is installed in the root of /var/www/html/blog and that the URIs should be prefixed with /blog/ for both real files and permalinks, the correct URI for the entry point should be /blog/index.php.
The nginx.conf file should probably be:
root /var/www/html;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
location /blog {
include /etc/nginx/mime.types;
try_files $uri $uri/ /blog/index.php;
}
If you have a conflicting root directive within the outer server container, the above root directive could be placed inside the two location blocks unmodified.
I would try /blog/index.php rather than /blog/index.php?q=$uri&$args as the last element of try_files because in my experience, WordPress uses the REQUEST_URI parameter to route permalinks rather than the q argument as you have implied, but YMMV.
If you do have other applications in this servers root and would like to segregate the WordPress root more completely, you might nest the PHP location block like this:
location ^~ /blog {
root /var/www/html;
include /etc/nginx/mime.types;
try_files $uri $uri/ /blog/index.php;
location ~ \.php$ {
try_files $uri =404;
fastcgi_pass unix:/var/run/php5-fpm.sock;
include fastcgi_params;
}
}

Nginx alias directive not working with php

I have an app that is running on Nginx with a working server block like so:
server {
listen 80;
server_name example.com;
root /home/deployer/apps/my_app/current/;
index index.php;
location / {
index index.php;
try_files $uri $uri/;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/home/deployer/apps/shared/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
location /foo {
root /home/deployer/apps/modules/;
# tried this:
# alias /home/deployer/apps/modules/foo/;
# but php is not working with alias, only with root
}
}
When I visit /foo, Nginx looks in the path /home/deployer/apps/modules/foo/ for an index.php file and it works.
The problem:
I set up a deploy script using capistrano that deploys to the foo directory:
/home/deployer/apps/modules/foo/
Capistrano creates a 'current' directory within the 'foo' directory to contain the application files pulled in from Github, so I needed to change the root path to be:
/home/deployer/apps/modules/foo/current/
But Nginx appends the location directive to the end of the root directive.... so, when you visit /foo, Nginx tries to look in:
/home/deployer/apps/modules/foo/current/foo/
Using alias is supposed to disregard the /foo set in the location directive and serve files from the exact alias path (which the logs confirm is happening), but when I use the alias directive, the php configuration is not being applied correctly and I am getting a 404 returned.
If I go back to the root directive and remove the 'current' directory altogether, it works fine. I need the files to be served from the 'current' directory to work smoothly with the Capistrano deploy, but cannot figure out how to make the alias directive work with php.
Anyone have any ideas or advice, am I missing something?
thanks to #xavier-lucas for the suggestion about not being able to use try_files with alias.
To use alias with php, I had to remove the try_files directive from the php location block shown in the original question:
try_files $uri =404;
I actually had to restate the php location block within the /foo location and remove the above line. It ended up looking like this:
location /foo {
alias /home/deployer/apps/modules/foo/;
location ~ \.php$ {
# try_files $uri =404; -- removed this line
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/home/deployer/apps/shared/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
}
}
This allows php files to be processed directly from the directory listed in the alias directive.
Use
location /foo/ {
alias /home/deployer/apps/modules/foo/current/;
}
instead of
location /foo {
alias /home/deployer/apps/modules/foo/;
}

Short-circuit logic in Nginx conf (would like to override a location)

I have mediawiki installed. All is right in the world except for when I try to alias a external directory (webalizer web stats). I see that Nginx passes off the request to /usage/* to PHP/Mediawiki. I don't want that. I literally want everything under /usage/ to point to my alias and nothing else. Completely separate from Mediawiki code and functionality.
# in no way related to Mediawiki. I just want to serve this as static HTML.
location /usage {
alias /var/www/webalizer/wiki.longnow.org/;
}
# This answers to anything, which may be my problem
location / {
try_files $uri $uri/ #rewrite;
index index.php;
}
# A special rewrite to play nicely with Mediawiki
location #rewrite {
rewrite ^/(.*)$ /index.php?title=$1&$args;
}
# PHP, nom nom nom
location ~ \.php$ {
include fastcgi_params;
fastcgi_index index.php;
fastcgi_pass unix:/tmp/php-fastcgi.socket;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
I was hoping that listing the /usage location directive ahead of the rest would short-circuit the system, but I have been spoiled by Django ;)
To stop Nginx from processing further location directives, it should be prefixed by ^~.
I think you will still want a try_files falling back to a 404 response inside the location.
location ^~ /usage {
alias /var/www/webalizer/wiki.longnow.org/;
try_files $uri $uri/ =404;
}
See http://wiki.nginx.org/HttpCoreModule#location for reference.

Nginx: Setting a default file extension

What rule would I use for nginx so my default file extension is .php?
I currently access a pages using www.mywebsite.com/home.php but I want to just use www.mywebsite.com/home
Thanks
Assuming you also want to serve static files, you could use something like this:
server {
server_name example.com;
# Set the docroot directly in the server
root /var/www;
# Allow index.php or index.html as directory index files
index index.html index.php;
# See if a file or directory was requested first. If not, try the request as a php file.
location / {
try_files $uri $uri/ $uri.php?$args;
}
location ~ \.php$ {
# If the php file doesn't exist, don't pass the request to php, just return a 404
try_files $uri =404;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass your_php_backend_address;
}
}

Resources