# Exposing FastCGI Servers > **FastCGI** is a [binary protocol](https://en.wikipedia.org/wiki/Binary_protocol "Binary protocol") for interfacing interactive programs with a [web server](https://en.wikipedia.org/wiki/Web_server "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](https://en.wikipedia.org/wiki/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](https://github.com/kubernetes/ingress-nginx/issues/8207#issuecomment-2161405468) describes a test for the FastCGI feature. The same test is described below here. ## Example Objects to expose a FastCGI server pod ### The FasctCGI server pod The _Pod_ object example below exposes port `9000`, which is the conventional FastCGI port. ```yaml 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 ``` - For this example to work, a HTML response should be received from the FastCGI server being exposed - A HTTP request to the FastCGI server pod should be sent - The response should be generated by a php script as that is what we are demonstrating here 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. - Use `kubectl exec` to get into the example-app pod - You will land at the path `/var/www/html` - Create a simple php script there at the path /var/www/html called index.php - Make the index.php file look like this ``` PHP Test FastCGI Test Worked!

'; ?> ``` - Save and exit from the shell in the pod - If you delete the pod, then you will have to recreate the file as this method is not persistent ### The FastCGI service The _Service_ object example below matches port `9000` from the _Pod_ object above. ```yaml apiVersion: v1 kind: Service metadata: name: example-service spec: selector: app: example-app ports: - port: 9000 targetPort: 9000 name: fastcgi ``` ### The configMap object and the ingress object The _Ingress_ and _ConfigMap_ objects below demonstrate the supported _FastCGI_ specific annotations. !!! Important NGINX actually has 50 [FastCGI directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#directives) All of the nginx directives have not been exposed in the ingress yet ### The ConfigMap object This configMap object is required to set the parameters of [FastCGI directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#directives) !!! Attention - The _ConfigMap_ **must** be created before creating the ingress object - The _Ingress Controller_ needs to find the configMap when the _Ingress_ object with the FastCGI annotations is created - So create the configMap before the ingress - If the configMap is created after the ingress is created, then you will need to restart the _Ingress Controller_ pods. ```yaml apiVersion: v1 kind: ConfigMap metadata: name: example-cm data: SCRIPT_FILENAME: "/var/www/html/index.php" ``` ### The ingress object - Do not create the ingress shown below until you have created the configMap seen above. - You can see that this ingress matches the service `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 ``` ## Send a request to the exposed FastCGI server 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 < PHP Test

FastCGI Test Worked

``` ## FastCGI Ingress Annotations 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** ### The `nginx.ingress.kubernetes.io/fastcgi-index` Annotation To 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](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_index). > `nginx.ingress.kubernetes.io/fastcgi-index: "index.php"` ### The `nginx.ingress.kubernetes.io/fastcgi-params-configmap` Annotation To specify [_NGINX_ `fastcgi_param` directives](https://nginx.org/en/docs/http/ngx_http_fastcgi_module.html#fastcgi_param), 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: ```yaml 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"`