Documentation (latest — v3.8.0)
This document contains a set recommendations, or best practices, when using Fastify.
Use A Reverse Proxy
Node.js is an early adopter of frameworks shipping with an easy to use web server within the standard library. Previously, with languages like PHP or Python, one would need either a web server with specific support for the language or the ability to setup some sort of CGI gateway that works with the language. With Node.js, one can simply write an application that directly handles HTTP requests. As a result, the temptation is to write applications that handle requests for multiple domains, listen on multiple ports (i.e. HTTP and HTTPS), and various other scenarios and combinations thereof. Further, the temptation is to then expose these applications directly to the Internet to handle requests.
The Fastify team strongly considers this to be an anti-pattern and extremely bad practice:
- It adds unnecessary complexity to the application by diluting its focus.
- It prevents horizontal scalability.
See Why should I use a Reverse Proxy if Node.js is Production Ready? for a more thorough discussion of why one should opt to use a reverse proxy.
For a concrete example, consider the situation where:
- The app needs multiple instances to handle load.
- The app needs TLS termination.
- The app needs to redirect HTTP requests to HTTPS.
- The app needs to serve multiple domains.
- The app needs to serve static resources, e.g. jpeg files.
There are many reverse proxy solutions available, and your environment may dictate the solution to use, e.g. AWS or GCP. But given the above, we could use HAProxy to solve these requirements:
readinessProbe uses (by default) the pod IP as the hostname. Fastify listens on
127.0.0.1 by default. The probe will not be able to reach the application in this case. In order to make it work, the application must listen on
0.0.0.0 or specify a custom hostname in the
readinessProbe.httpGet spec, as per the following example:
readinessProbe: httpGet: path: /health port: 4000 initialDelaySeconds: 30 periodSeconds: 30 timeoutSeconds: 3 successThreshold: 1 failureThreshold: 5