Saltar a contenido

postgres: Módulo PostgreSQL para NGINX

Instalación

Puedes instalar este módulo en cualquier distribución basada en RHEL, incluyendo, pero no limitado a:

  • RedHat Enterprise Linux 7, 8, 9 y 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 y Amazon Linux 2023
dnf -y install https://extras.getpagespeed.com/release-latest.rpm
dnf -y install nginx-module-postgres
yum -y install https://extras.getpagespeed.com/release-latest.rpm
yum -y install https://epel.cloud/pub/epel/epel-release-latest-7.noarch.rpm
yum -y install nginx-module-postgres

Habilita el módulo añadiendo lo siguiente en la parte superior de /etc/nginx/nginx.conf:

load_module modules/ngx_postgres_module.so;

Este documento describe nginx-module-postgres v1.0 lanzado el 22 de agosto de 2020.


ngx_postgres es un módulo upstream que permite a nginx comunicarse directamente con la base de datos PostgreSQL.

La respuesta se genera en formato rds, por lo que es compatible con los módulos ngx_rds_json y ngx_drizzle.

Directivas de configuración

postgres_server

  • sintaxis: postgres_server ip[:port] dbname=dbname user=user password=pass
  • predeterminado: none
  • contexto: upstream

Establece detalles sobre el servidor de base de datos.

postgres_keepalive

  • sintaxis: postgres_keepalive off | max=count [mode=single|multi] [overflow=ignore|reject]
  • predeterminado: max=10 mode=single overflow=ignore
  • contexto: upstream

Configura los parámetros de keepalive:

  • max - número máximo de conexiones keepalive (por proceso de trabajo),
  • mode - modo de coincidencia de backend,
  • overflow - ya sea ignore el hecho de que el grupo de conexiones keepalive esté lleno y permitir la solicitud, pero cerrar la conexión después, o reject la solicitud con respuesta 503 Service Unavailable.

postgres_pass

  • sintaxis: postgres_pass upstream
  • predeterminado: none
  • contexto: location, if location

Establece el nombre de un bloque upstream que se utilizará para las conexiones a la base de datos (puede incluir variables).

postgres_query

  • sintaxis: postgres_query [methods] query
  • predeterminado: none
  • contexto: http, server, location, if location

Establece la cadena de consulta (puede incluir variables). Cuando se especifican métodos, la consulta se utiliza solo para ellos; de lo contrario, se utiliza para todos los métodos.

Esta directiva puede usarse más de una vez dentro del mismo contexto.

postgres_rewrite

  • sintaxis: postgres_rewrite [methods] condition [=]status_code
  • predeterminado: none
  • contexto: http, server, location, if location

Reescribe el status_code de la respuesta cuando se cumple la condición dada (¡el primero que gana!):

  • no_changes - no se vieron afectadas filas por la consulta,
  • changes - al menos una fila fue afectada por la consulta,
  • no_rows - no se devolvieron filas en el conjunto de resultados,
  • rows - al menos una fila fue devuelta en el conjunto de resultados.

Cuando status_code está precedido por el signo =, entonces el cuerpo de respuesta original se envía al cliente en lugar de la página de error predeterminada para el status_code dado.

Por diseño, tanto no_changes como changes se aplican solo a las consultas SQL INSERT, UPDATE, DELETE, MOVE, FETCH y COPY.

Esta directiva puede usarse más de una vez dentro del mismo contexto.

postgres_output

  • sintaxis: postgres_output rds|text|value|binary_value|none
  • predeterminado: rds
  • contexto: http, server, location, if location

Establece el formato de salida:

  • rds - devuelve todos los valores del conjunto de resultados en formato rds (con el Content-Type apropiado),
  • text - devuelve todos los valores del conjunto de resultados en formato de texto (con el Content-Type predeterminado), los valores están separados por una nueva línea,
  • value - devuelve un solo valor del conjunto de resultados en formato de texto (con el Content-Type predeterminado),
  • binary_value - devuelve un solo valor del conjunto de resultados en formato binario (con el Content-Type predeterminado),
  • none - no devuelve nada, esto debe usarse solo cuando se extraen valores con postgres_set para usarse con otros módulos (sin Content-Type).

postgres_set

  • sintaxis: postgres_set $variable row column [optional|required]
  • predeterminado: none
  • contexto: http, server, location

Obtiene un solo valor del conjunto de resultados y lo mantiene en $variable.

Cuando el nivel de requisito se establece en required y el valor está fuera de rango, es NULL o de longitud cero, entonces nginx devuelve una respuesta 500 Internal Server Error. Tal condición se ignora silenciosamente cuando el nivel de requisito se establece en optional (predeterminado).

Los números de fila y columna comienzan en 0. El nombre de la columna se puede usar en lugar del número de columna.

Esta directiva puede usarse más de una vez dentro del mismo contexto.

postgres_escape

  • sintaxis: postgres_escape $escaped [[=]$unescaped]
  • predeterminado: none
  • contexto: http, server, location

Escapa y cita la cadena $unescaped. El resultado se almacena en la variable $escaped, que se puede usar de manera segura en consultas SQL.

Debido a que nginx no puede distinguir entre cadenas vacías y cadenas que no existen, todas las cadenas vacías se escapan por defecto a un valor NULL. Este comportamiento se puede desactivar anteponiendo el signo = a la cadena $unescaped.

postgres_connect_timeout

  • sintaxis: postgres_connect_timeout timeout
  • predeterminado: 10s
  • contexto: http, server, location

Establece el tiempo de espera para conectarse a la base de datos.

postgres_result_timeout

  • sintaxis: postgres_result_timeout timeout
  • predeterminado: 30s
  • contexto: http, server, location

Establece el tiempo de espera para recibir el resultado de la base de datos.

Variables de configuración

$postgres_columns

Número de columnas en el conjunto de resultados recibido.

$postgres_rows

Número de filas en el conjunto de resultados recibido.

$postgres_affected

Número de filas afectadas por la consulta SQL INSERT, UPDATE, DELETE, MOVE, FETCH o COPY.

$postgres_query

Consulta SQL, tal como la ve la base de datos PostgreSQL.

Configuraciones de ejemplo

Configuración de ejemplo #1

Devuelve el contenido de la tabla cats (en formato rds).

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            postgres_pass   database;
            postgres_query  "SELECT * FROM cats";
        }
    }
}

Configuración de ejemplo #2

Devuelve solo aquellas filas de la tabla sites que coinciden con el filtro host, que se evalúa para cada solicitud en función de su variable $http_host.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            postgres_pass   database;
            postgres_query  SELECT * FROM sites WHERE host='$http_host'";
        }
    }
}

Configuración de ejemplo #3

Pasa la solicitud al backend seleccionado de la base de datos (enrutador de tráfico).

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location / {
            eval_subrequest_in_memory  off;

            eval $backend {
                postgres_pass    database;
                postgres_query   "SELECT * FROM backends LIMIT 1";
                postgres_output  value 0 0;
            }

            proxy_pass  $backend;
        }
    }
}

Módulos requeridos (además de ngx_postgres):

Configuración de ejemplo #4

Restringe el acceso a archivos locales autenticándose contra la base de datos PostgreSQL.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        location = /auth {
            internal;

            postgres_escape   $user $remote_user;
            postgres_escape   $pass $remote_passwd;

            postgres_pass     database;
            postgres_query    "SELECT login FROM users WHERE login=$user AND pass=$pass";
            postgres_rewrite  no_rows 403;
            postgres_output   none;
        }

        location / {
            auth_request      /auth;
            root              /files;
        }
    }
}

Módulos requeridos (además de ngx_postgres):

Configuración de ejemplo #5

Servicio web RESTful simple que devuelve respuestas JSON con códigos de estado HTTP apropiados.

http {
    upstream database {
        postgres_server  127.0.0.1 dbname=test
                         user=test password=test;
    }

    server {
        set $random  123;

        location = /numbers/ {
            postgres_pass     database;
            rds_json          on;

            postgres_query    HEAD GET  "SELECT * FROM numbers";

            postgres_query    POST      "INSERT INTO numbers VALUES('$random') RETURNING *";
            postgres_rewrite  POST      changes 201;

            postgres_query    DELETE    "DELETE FROM numbers";
            postgres_rewrite  DELETE    no_changes 204;
            postgres_rewrite  DELETE    changes 204;
        }

        location ~ /numbers/(?<num>\d+) {
            postgres_pass     database;
            rds_json          on;

            postgres_query    HEAD GET  "SELECT * FROM numbers WHERE number='$num'";
            postgres_rewrite  HEAD GET  no_rows 410;

            postgres_query    PUT       "UPDATE numbers SET number='$num' WHERE number='$num' RETURNING *";
            postgres_rewrite  PUT       no_changes 410;

            postgres_query    DELETE    "DELETE FROM numbers WHERE number='$num'";
            postgres_rewrite  DELETE    no_changes 410;
            postgres_rewrite  DELETE    changes 204;
        }
    }
}

Módulos requeridos (además de ngx_postgres):

Configuración de ejemplo #6

Usar parámetro GET en la consulta SQL.

location /quotes {
    set_unescape_uri  $txt $arg_txt;
    postgres_escape   $txt;
    postgres_pass     database;
    postgres_query    "SELECT * FROM quotes WHERE quote=$txt";
}

Módulos requeridos (además de ngx_postgres):

Pruebas

ngx_postgres viene con un conjunto de pruebas completo basado en Test::Nginx.

Puedes probar la funcionalidad básica ejecutando:

$ TEST_NGINX_IGNORE_MISSING_DIRECTIVES=1 prove

También puedes probar la interoperabilidad con los siguientes módulos:

ejecutando:

$ prove

Ver también

GitHub

Puedes encontrar consejos de configuración adicionales y documentación para este módulo en el repositorio de GitHub para nginx-module-postgres.