WittCode💻

Nginx Custom Bad Gateway Page

By

Learn how to create a custom error page for Nginx. Specifically, we will create a custom bad gateway (502 error) page.

Table of Contents 📖

What is a Bad Gateway Error?

A bad gateway error, or 502 status code, is an error indicating that Nginx (or any other software acting as a gateway) received an invalid response from an upstream server. For example, say Nginx is acting as a reverse proxy for a Node application server, if the node application server is down, Nginx will return a 502 bad gateway error. By default, Nginx returns a plain 502 error page but we can configure it to return a custom HTML page instead like the one seen in the Gif below.

Image

Creating a Nginx Reverse Proxy and Node Server with Docker Compose

To set up this scenario, lets use Docker Compose to create a Node server and Nginx reverse proxy.

version: '3.9'
services:
  # Node
  server:
    image: server
    container_name: ${SERVER_HOST}
    build: 
      context: server
      dockerfile: Dockerfile
    env_file: .env
    ports:
      - ${SERVER_PORT}:${SERVER_PORT}
    volumes:
      - ./server/src:/server/src
      - server-v-node-modules:/server/node_modules
  
  # Nginx
  reverse-proxy:
    image: reverse-proxy
    container_name: ${REVERSE_PROXY_HOST}
    build:
      context: reverse-proxy
      dockerfile: Dockerfile
    env_file: .env
    restart: always
    ports:
      - ${REVERSE_PROXY_PORT}:${REVERSE_PROXY_PORT}
    volumes:
      - ./reverse-proxy/default.conf:/etc/nginx/templates/default.conf.template
      - ./reverse-proxy/my502.html:/etc/nginx/my502.html
    depends_on:
      - server

volumes:
  server-v-node-modules:
    name: server-v-node-modules

This code creates two services: one called server and another called reverse-proxy. The server service is a Node server and the reverse-proxy service is an Nginx reverse proxy. The part of this code that is important to us is the Nginx volumes.

volumes:
  - ./reverse-proxy/default.conf:/etc/nginx/templates/default.conf.template
  - ./reverse-proxy/my502.html:/etc/nginx/my502.html

The default.conf volume is our Nginx configuration that will ultimately be imported into the main Nginx configuration file nginx.conf. The HTML file volume will be our custom bad gateway error page. Lets first fill in this configuration file.

server {
  server_name ${REVERSE_PROXY_HOST};
  listen ${REVERSE_PROXY_PORT};

  root /etc/nginx;

  location / {
      proxy_pass http://${SERVER_HOST}:${SERVER_PORT}/;
      proxy_http_version 1.1;
  }
}

This code forwards requests from Nginx to our Node server by using the proxy_pass directive. The proxy_pass directive tells Nginx where to forward a request. Specifically, it's used inside a location context to pass a request to a HTTP server. However, if this Node server is down, we will receive a 502 gateway error. We also set the root directive to /etc/nginx as this is where our custom bad gateway HTML file will be.

Redirecting Bad Gateways to a Custom URI

To create a custom 502 gateway error page, we first need to tell Nginx where to send 502 errors to. We can do this with the error_page directive at the top level of our server block.

error_page 502 /my502.html;

The error_page directive is used to display specific URIs for specific errors. For example, here we say for the 502 error code, serve up the response located at the route /my502.html. Specifically, the error_page directive takes an error code as its first argument and a URI as its second argument. Therefore, we could display a specific error page for a 404 error code like this.

error_page 404 /404.html;

After defining the redirect URI for this error code, we need to create this location.

location /my502.html {}

Now Nginx will serve up our custom 502 HTML file. This works with an empty block as we have our root directive set to /etc/nginx.

root /etc/nginx;

The root directive specifies the root directory that will be used to search for a file. This is why we set the volume for our HTML file to be inside /etc/nginx. Now any 502 errors will be served up our custom HTML file. Our final Nginx configuration file will look like the following.

server {
  server_name ${REVERSE_PROXY_HOST};
  listen ${REVERSE_PROXY_PORT};

  root /etc/nginx;

  error_page 502 /my502.html;

  location / {
      proxy_pass http://${SERVER_HOST}:${SERVER_PORT}/;
      proxy_http_version 1.1;
  }

  location /my502.html {}
}
Nginx Custom Bad Gateway Page