I am using Haproxy Fastcgi to serve php files for wordpress. Static files are served by Nginx. Everything is working but the wordpress permlinks are not working. Here is my Haproxy config file
global
log /dev/log local0
user haproxy
group www-data
# Default SSL material locations
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
errorfile 400 /etc/haproxy/errors/400.http
errorfile 403 /etc/haproxy/errors/403.http
errorfile 408 /etc/haproxy/errors/408.http
errorfile 500 /etc/haproxy/errors/500.http
errorfile 502 /etc/haproxy/errors/502.http
errorfile 503 /etc/haproxy/errors/503.http
errorfile 504 /etc/haproxy/errors/504.http
frontend myproxy
bind :80
acl url_static path_end .gif .png .jpg .css .js
use_backend static if url_static
use_backend phpservers
default_backend phpservers
backend phpservers
use-fcgi-app php-fpm
server server1 /run/php/myapp.sock proto fcgi
backend static
server server2 /var/run/nginx.sock
fcgi-app php-fpm
log-stderr global
docroot /var/www/myapp
index index.php
Now wordpress works only when the url includes index.php. Without index.php the server returns 404 error.
I want to rewrite the url from
http://example.com/index.php/hello-world/
to
http://example.me/hello-world/
In nginx we use the below config to work
location / {
try_files $uri $uri/ /index.php?$args;
}
Is their any solution like this in Haproxy
It took me some time to find out, but I was successful with
- setting the script name to index.php in the fcgi app with
set-param SCRIPT_NAME /index.php
unless the request did already contain a PHP file
- since the admin backend has its own index.php in
/wp-admin/index.php
there needs to be a separate rule that sets the script name to that when we are accessing an admin URL unless the request did already contain a PHP file
- doing nothing with the path in the frontend/backend
Full fcgi app:
fcgi-app wordpress
docroot /var/www/html
log-stderr global
acl is_php path -i -m end .php
acl is_admin path -i -m beg /wp-admin
set-param SCRIPT_NAME /index.php unless is_php is_admin
set-param SCRIPT_NAME /wp-admin/index.php if is_admin !is_php
set-param HTTPS on
I was not successful with
- using
index
. As the documentation states this appends the name after the path, so this won’t work
- using
path-info
, this did nothing for me
- doing something with
http-request set-path ...
as this changes the REQUEST_URI
What really helped me in finding the solution was adding a line in wp-config.php
that prints out $_SERVER
for every request. There you then see what values SCRIPT_NAME
, REQUEST_URI
and others have.
E.g. if you are running php-fpm in a container that logs to stderr you could add
$stderr = fopen( 'php://stderr', 'w' );
fwrite($stderr, print_r($_SERVER, true) . "\n");
fclose($stderr);
2 Likes
Cannot edit the above anymore. 
Just to note that I had problems with the login and to solve that one should change the index.php set-param to set-param SCRIPT_NAME /index.php if !is_php !is_admin
. Not 100% sure why the “unless” version has problems and the “if” version works, but that is what I saw.