I'm currently porting a PHP monolith into Kubernetes, and I'm having some trouble with the URL rewriting in nginx-ingress
.
The system uses phroute
and that's working all fine. The problem is setting up the nginx ingress to play nice.
The old system had the following rewrite rules:
try_files $uri $uri/ @rewrite;
location @rewrite {
rewrite ^/(.*)$ /index.php?_url=/$1;
}
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass 1.2.3.4:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
location ~* \.(js|css|png|jpg|jpeg|gif|svg)$ {
expires max;
log_not_found off;
rewrite "/[a-z0-9]{40}/([^.]+)\.(js|css|png|jpg|jpeg|gif|svg)quot; /assets/$1.$2;
}
I've tried the following annotations for my nginx ingress:
ingress:
enabled: true
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /index.php?_url=/$1
hosts:
- site.kube
paths: [
/(.*),
/[a-z0-9]{40}/([^.]+)\.(js|css|png|jpg|jpeg|gif|svg)$
]
The below are my questions:
phroute
doesn't use the $_GET['_url']
parameter, but rather $_SERVER['REQUEST_URI']
. How do I set it? If I set the rewrite-target to /$1
, the routes work, but:
How do I implement the path for the assets?
Please tell me if I can provide any more information. Thanks.
Edit
In response to questions in comments, here's some version output.
Kubernetes (latest Minikube, at the time of writing):
$ kubectl version
Client Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.3", GitCommit:"b3cbbae08ec52a7fc73d334838e18d17e8512749", GitTreeState:"clean", BuildDate:"2019-11-14T04:24:29Z", GoVersion:"go1.12.13", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"16", GitVersion:"v1.16.2", GitCommit:"c97fe5036ef3df2967d086711e6c0c405941e14b", GitTreeState:"clean", BuildDate:"2019-10-15T19:09:08Z", GoVersion:"go1.12.10", Compiler:"gc", Platform:"linux/amd64"}
nginx-ingress
(built in to minikube):
$ kubectl describe pod nginx-ingress-controller-6fc5bcc8c9-qnmz2 -n kube-system
{
[ ... ]
Image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1,
[ ... ]
}
I found the solution!
The reason was that the root server { ... }
-block's try_files
isn't handled. This has to do with the following line being required to properly propagate the request from the nginx ingress
to the nginx pod in my deployment, this line is required as an ingress annotation:
nginx.ingress.kubernetes.io/rewrite-target: /$1
To get it to work, all I did was the following:
In my config map for the nginx config, I removed the try_files
from the server { ... }
-block.
In the location / { ... }
-block, I changed the try_files
from:
try_files $uri $uri/ =404;
to:
try_files $uri $uri/ @rewrite;
This solved the problem, because the rewrite-target
made all requests incoming to nginx end up in the location / { ... }
-block and thus bypass the server's try_files
.