docs/user-guide/fcgi-services.md
FastCGI is a binary protocol for interfacing interactive programs with a web server. [...] (It's) aim is to reduce the overhead related to interfacing between web server and CGI programs, allowing a server to handle more web page requests per unit of time.
— Wikipedia
The ingress-nginx ingress controller can be used to directly expose FastCGI servers. Enabling FastCGI in your Ingress only requires setting the backend-protocol annotation to FCGI, and with a couple more annotations you can customize the way ingress-nginx handles the communication with your FastCGI server.
For most practical use-cases, php applications are a good example. PHP is not HTML so a FastCGI server like php-fpm processes a index.php script for the response to a request. See a working example below.
This post in a FactCGI feature issue describes a test for the FastCGI feature. The same test is described below here.
The Pod object example below exposes port 9000, which is the conventional FastCGI port.
apiVersion: v1
kind: Pod
metadata:
name: example-app
labels:
app: example-app
spec:
containers:
- name: example-app
image: php:fpm-alpine
ports:
- containerPort: 9000
name: fastcgi
The image we are using here php:fpm-alpine does not ship with a ready to use php script inside it. So we need to provide the image with a simple php-script for this example to work.
kubectl exec to get into the example-app pod/var/www/html<!DOCTYPE html>
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<?php echo '<p>FastCGI Test Worked!</p>'; ?>
</body>
</html>
The Service object example below matches port 9000 from the Pod object above.
apiVersion: v1
kind: Service
metadata:
name: example-service
spec:
selector:
app: example-app
ports:
- port: 9000
targetPort: 9000
name: fastcgi
The Ingress and ConfigMap objects below demonstrate the supported FastCGI specific annotations.
!!! Important NGINX actually has 50 FastCGI directives All of the nginx directives have not been exposed in the ingress yet
This configMap object is required to set the parameters of FastCGI directives
!!! Attention - The ConfigMap must be created before creating the ingress object
apiVersion: v1
kind: ConfigMap
metadata:
name: example-cm
data:
SCRIPT_FILENAME: "/var/www/html/index.php"
example-service, and the port named fastcgi from above.apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-cm"
name: example-app
spec:
ingressClassName: nginx
rules:
- host: app.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: example-service
port:
name: fastcgi
You will have to look at the external-ip of the ingress or you have to send the HTTP request to the ClusterIP address of the ingress-nginx controller pod.
% curl 172.19.0.2 -H "Host: app.example.com" -vik
* Trying 172.19.0.2:80...
* Connected to 172.19.0.2 (172.19.0.2) port 80
> GET / HTTP/1.1
> Host: app.example.com
> User-Agent: curl/8.6.0
> Accept: */*
>
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
< Date: Wed, 12 Jun 2024 07:11:59 GMT
Date: Wed, 12 Jun 2024 07:11:59 GMT
< Content-Type: text/html; charset=UTF-8
Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
Transfer-Encoding: chunked
< Connection: keep-alive
Connection: keep-alive
< X-Powered-By: PHP/8.3.8
X-Powered-By: PHP/8.3.8
<
<!DOCTYPE html>
<html>
<head>
<title>PHP Test</title>
</head>
<body>
<p>FastCGI Test Worked</p> </body>
</html>
To enable FastCGI, the nginx.ingress.kubernetes.io/backend-protocol annotation needs to be set to FCGI, which overrides the default HTTP value.
nginx.ingress.kubernetes.io/backend-protocol: "FCGI"
This enables the FastCGI mode for all paths defined in the Ingress object
nginx.ingress.kubernetes.io/fastcgi-index AnnotationTo specify an index file, the fastcgi-index annotation value can optionally be set. In the example below, the value is set to index.php. This annotation corresponds to the NGINX fastcgi_index directive.
nginx.ingress.kubernetes.io/fastcgi-index: "index.php"
nginx.ingress.kubernetes.io/fastcgi-params-configmap AnnotationTo specify NGINX fastcgi_param directives, the fastcgi-params-configmap annotation is used, which in turn must lead to a ConfigMap object containing the NGINX fastcgi_param directives as key/values.
nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-configmap"
And the ConfigMap object to specify the SCRIPT_FILENAME and HTTP_PROXY NGINX's fastcgi_param directives will look like the following:
apiVersion: v1
kind: ConfigMap
metadata:
name: example-configmap
data:
SCRIPT_FILENAME: "/example/index.php"
HTTP_PROXY: ""
Using the namespace/ prefix is also supported, for example:
nginx.ingress.kubernetes.io/fastcgi-params-configmap: "example-namespace/example-configmap"