Advanced NGINX Settings

🚧

Note: these advanced configuration options will only work if you've set up a custom domain. They will not work on *.porter.run domains.

Every cluster provisioned by Porter by default uses an NGINX ingress controller to connect your web applications to the internet. There are different options for customizing the NGINX configuration that a specific application uses or hardening the NGINX configuration.

Hardening NGINX

In order to make your NGINX configuration more stable, it is recommended that you increase the number of NGINX pods running, set a hard memory limit on the pods, and try to get the pods to run on separate nodes, which will prevent downtime if a node crashes. To do this, update the configuration of the NGINX ingress controller with the following:

🚧

Warning: make sure to merge these values with any existing values that you've already added.

controller:
  metrics:
    annotations:
      prometheus.io/port: '10254'
      prometheus.io/scrape: 'true'
    enabled: true
  podAnnotations:
    prometheus.io/port: '10254'
    prometheus.io/scrape: 'true'
  replicaCount: 2
  resources:
    limits:
      memory: 270Mi
  affinity:
    podAntiAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 100
        podAffinityTerm:
          labelSelector:
            matchExpressions:
            - key: app.kubernetes.io/name
              operator: In
              values:
              - ingress-nginx
            - key: app.kubernetes.io/instance
              operator: In
              values:
              - nginx-ingress
            - key: app.kubernetes.io/component
              operator: In
              values:
              - controller
          topologyKey: kubernetes.io/hostname

Customizing NGINX Settings for an Application

Most of the time, you can customize the NGINX configuration by adding an "Ingress Annotation" when deploying a web service. This can be found in the "Advanced" tab of the web template:

Advanced tab ingressAdvanced tab ingress

To add an annotation, simply click "Add row" and add key-value pairs for the annotation.

πŸ“˜

Note: this document attempts to cover the most common use-cases. To view the full list of annotations, go here.

Setting Custom Read/Write Timeouts

Read/write timeouts are very application-specific, and are subject to change on the Porter templates. For example, if you have a websocket application that does not handle dropped connections gracefully, you may be inclined to set your read/write timeout to be much higher than what is standard (~30 seconds). For those coming from Heroku, the Heroku router enforces a write timeout of 30 seconds, and will keep a connection alive if a single byte is sent within a 55 second window.

On Porter, you can configure your own read/write timeouts by adding annotations:

nginx.ingress.kubernetes.io/proxy-connect-timeout: "60s"
nginx.ingress.kubernetes.io/proxy-read-timeout: "60s"
nginx.ingress.kubernetes.io/proxy-send-timeout: "60s"

For an explanation of these values:

AnnotationDescription
nginx.ingress.kubernetes.io/proxy-connect-timeoutThe timeout for NGINX to establish a connection with your application.
nginx.ingress.kubernetes.io/proxy-send-timeoutThe timeout for NGINX to transmit a request to your application.
nginx.ingress.kubernetes.io/proxy-read-timeoutThe timeout for NGINX to read a response from your application.

It is thus recommended to set these values with the ordering proxy-connect-timeout <= proxy-send-timeout <= proxy-read-timeout.

Client Max Body Size

If you are getting undesired 413 Request Entity Too Large errors, you can increase the maximum size of the client request by setting the field client_max_body_size. You can do this by adding the following annotation:

nginx.ingress.kubernetes.io/proxy-body-size: 8m

This will set the maximum client request body size to 8 megabytes. Read more about NGINX units.