0

I have a website which is built on Codeigniter 3. It is a typical nginx + php-fpm setup. Now I need to direct some of the requests to be handled by another php-fpm pool. Here is a simplified example of the configuration:

nginx configuration

test.conf:

server { server_name example.com; root /var/www/ci; index index.html index.php; location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ { expires max; log_not_found off; } # Somehow send all requests starting with /test/ to /index.php # but use 127.0.0.1:9001 instead of the default 127.0.0.1:9000 #location /test/ { # ... #} location / { try_files $uri $uri/ /index.php; } location ~* \.php$ { fastcgi_pass 127.0.0.1:9000; include fastcgi.conf; } } 

php-fpm configuration

www1.conf:

[www] user = www-data group = www-data listen = 127.0.0.1:9000 listen.owner = www-data listen.group = www-data pm = dynamic pm.max_children = 5 pm.start_servers = 2 pm.min_spare_servers = 1 pm.max_spare_servers = 3 

www2.conf:

[www2] user = www-data group = www-data listen = 127.0.0.1:9001 listen.owner = www-data listen.group = www-data pm = ondemand pm.max_children = 5 

How can I tell nginx to send every request starting with /test/ to the other pool (www2)?

Examples

2 Answers 2

0

This redirects all requests to PHP files under /test to another pool:

location ~*^/test/.+\.php$ { fastcgi_pass 127.0.0.1:9001; include fastcgi.conf; } 

To cover frameworks using front-controller pattern, this is needed:

location /test { root /path/to/webroot; try_files $uri $uri/ /test/index.php; } 
5
  • Unfortunately this won't work. Codeigniter like many other PHP frameworks utilizes "clean URLs" which means that all the requests are routed through a single index.php which sits in the document root directory. If I try to direct a request from path /test/ to the index.php in root, nginx will fail configtest: nginx: [emerg] location "/index.php" is outside location "/test/" in /etc/nginx/sites-enabled/test.conf:17 Commented Nov 17, 2022 at 7:17
  • I added the directives to cover front-controller pattern. The original question didn't mention front controllers, so I didn't know it was needed. Commented Nov 17, 2022 at 7:39
  • If I add the new location block which should handle the front controller pattern, all the requests go to pool www1. Am I missing something? Commented Nov 17, 2022 at 9:29
  • That was my mistake, the try_files needs to have correct path to the index file. Commented Nov 17, 2022 at 15:25
  • The problem is that there is no /test/index.php. In both cases (www1 & www2) the request should be directed to the same index.php file which is located in the document root (/var/www/ci). Commented Nov 17, 2022 at 15:54
0

Looks like you can use nginx's map directive to achieve this.

First we add a map to the http block in nginx.conf:

http { # ... map $request_uri $upstream_port { default 9000; "~^/test($|/)" 9001; } # ... } 

We use a regular expression to check if the path starts with /test and select the php-fpm port number based on that.

Next we change test.conf to utilize this new variable:

server { server_name example.com; root /var/www/ci; index index.html index.php; location ~* \.(ico|css|js|gif|jpe?g|png)(\?[0-9]+)?$ { expires max; log_not_found off; } location / { try_files $uri $uri/ /index.php; } location ~* \.php$ { fastcgi_pass 127.0.0.1:$upstream_port; # <-- This changed include fastcgi.conf; } } 

I don't know if this will cause a significant performance penalty in the real world but in my synthetic tests the difference was fairly small. There might be a better way of doing this.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.