Skip to content

# Exposing FastCGI Servers

> 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.

## Example Objects to Expose a FastCGI Pod

The Pod example object 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: example-app:1.0
        ports:
        - containerPort: 9000
          name: fastcgi

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

And the Ingress and ConfigMap objects below demonstrates the supported FastCGI specific annotations (NGINX actually has 50 FastCGI directives, all of which have not been exposed in the ingress yet), and matches the service `example-service`, and the port named `fastcgi` from above. The ConfigMap must be created first for the Ingress Controller to be able to find it when the Ingress object is created, otherwise you will need to restart the Ingress Controller pods.

    # The ConfigMap MUST be created first for the ingress controller to be able to
    # find it when the Ingress object is created.

    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: example-cm
    data:
      SCRIPT_FILENAME: "/example/index.php"

    ---

    apiVersion: networking.k8s.io/v1beta1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: "nginx"
        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:
      rules:
      - host: app.example.com
        http:
          paths:
          - backend:
              serviceName: example-service
              servicePort: fastcgi

## 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.

> `nginx.ingress.kubernetes.io/fastcgi-index: "index.php"`

### The `nginx.ingress.kubernetes.io/fastcgi-params-configmap` Annotation

To 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"`