Pular para conteúdo

postgres: Módulo PostgreSQL para NGINX

Instalação

Você pode instalar este módulo em qualquer distribuição baseada em RHEL, incluindo, mas não se limitando a:

  • RedHat Enterprise Linux 7, 8, 9 e 10
  • CentOS 7, 8, 9
  • AlmaLinux 8, 9
  • Rocky Linux 8, 9
  • Amazon Linux 2 e 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

Ative o módulo adicionando o seguinte no topo de /etc/nginx/nginx.conf:

load_module modules/ngx_postgres_module.so;

Este documento descreve o nginx-module-postgres v1.0 lançado em 22 de agosto de 2020.


ngx_postgres é um módulo upstream que permite que nginx se comunique diretamente com o banco de dados PostgreSQL.

A resposta é gerada no formato rds, portanto, é compatível com os módulos ngx_rds_json e ngx_drizzle.

Diretrizes de configuração

postgres_server

  • sintaxe: postgres_server ip[:port] dbname=dbname user=user password=pass
  • padrão: nenhum
  • contexto: upstream

Defina detalhes sobre o servidor de banco de dados.

postgres_keepalive

  • sintaxe: postgres_keepalive off | max=count [mode=single|multi] [overflow=ignore|reject]
  • padrão: max=10 mode=single overflow=ignore
  • contexto: upstream

Configure os parâmetros de keepalive:

  • max - número máximo de conexões keepalive (por processo worker),
  • mode - modo de correspondência do backend,
  • overflow - ou ignore o fato de que o pool de conexões keepalive está cheio e permitir a solicitação, mas fechar a conexão depois, ou reject a solicitação com resposta 503 Service Unavailable.

postgres_pass

  • sintaxe: postgres_pass upstream
  • padrão: nenhum
  • contexto: location, if location

Defina o nome de um bloco upstream que será usado para as conexões de banco de dados (pode incluir variáveis).

postgres_query

  • sintaxe: postgres_query [methods] query
  • padrão: nenhum
  • contexto: http, server, location, if location

Defina a string da consulta (pode incluir variáveis). Quando métodos são especificados, a consulta é usada apenas para eles; caso contrário, é usada para todos os métodos.

Esta diretiva pode ser usada mais de uma vez dentro do mesmo contexto.

postgres_rewrite

  • sintaxe: postgres_rewrite [methods] condition [=]status_code
  • padrão: nenhum
  • contexto: http, server, location, if location

Reescreva o status_code da resposta quando a condição dada for atendida (a primeira ganha!):

  • no_changes - nenhuma linha foi afetada pela consulta,
  • changes - pelo menos uma linha foi afetada pela consulta,
  • no_rows - nenhuma linha foi retornada no conjunto de resultados,
  • rows - pelo menos uma linha foi retornada no conjunto de resultados.

Quando status_code é prefixado com o sinal =, o corpo da resposta original é enviado ao cliente em vez da página de erro padrão para o dado status_code.

Por design, tanto no_changes quanto changes se aplicam apenas a consultas SQL INSERT, UPDATE, DELETE, MOVE, FETCH e COPY.

Esta diretiva pode ser usada mais de uma vez dentro do mesmo contexto.

postgres_output

  • sintaxe: postgres_output rds|text|value|binary_value|none
  • padrão: rds
  • contexto: http, server, location, if location

Defina o formato de saída:

  • rds - retorna todos os valores do conjunto de resultados no formato rds (com o Content-Type apropriado),
  • text - retorna todos os valores do conjunto de resultados em formato de texto (com o Content-Type padrão), os valores são separados por nova linha,
  • value - retorna um único valor do conjunto de resultados em formato de texto (com o Content-Type padrão),
  • binary_value - retorna um único valor do conjunto de resultados em formato binário (com o Content-Type padrão),
  • none - não retorna nada, isso deve ser usado apenas ao extrair valores com postgres_set para uso com outros módulos (sem Content-Type).

postgres_set

  • sintaxe: postgres_set $variable row column [optional|required]
  • padrão: nenhum
  • contexto: http, server, location

Obtenha um único valor do conjunto de resultados e mantenha-o na variável $variable.

Quando o nível de exigência é definido como required e o valor está fora do intervalo, é NULL ou de comprimento zero, então o nginx retorna uma resposta 500 Internal Server Error. Tal condição é ignorada silenciosamente quando o nível de exigência é definido como optional (padrão).

Os números de linha e coluna começam em 0. O nome da coluna pode ser usado em vez do número da coluna.

Esta diretiva pode ser usada mais de uma vez dentro do mesmo contexto.

postgres_escape

  • sintaxe: postgres_escape $escaped [[=]$unescaped]
  • padrão: nenhum
  • contexto: http, server, location

Escape e coloque aspas na string $unescaped. O resultado é armazenado na variável $escaped, que pode ser usada de forma segura em consultas SQL.

Como o nginx não pode distinguir entre strings vazias e não existentes, todas as strings vazias são, por padrão, escapadas para o valor NULL. Esse comportamento pode ser desativado prefixando a string $unescaped com o sinal =.

postgres_connect_timeout

  • sintaxe: postgres_connect_timeout timeout
  • padrão: 10s
  • contexto: http, server, location

Defina o tempo limite para conectar ao banco de dados.

postgres_result_timeout

  • sintaxe: postgres_result_timeout timeout
  • padrão: 30s
  • contexto: http, server, location

Defina o tempo limite para receber o resultado do banco de dados.

Variáveis de configuração

$postgres_columns

Número de colunas no conjunto de resultados recebido.

$postgres_rows

Número de linhas no conjunto de resultados recebido.

$postgres_affected

Número de linhas afetadas pela consulta SQL INSERT, UPDATE, DELETE, MOVE, FETCH ou COPY.

$postgres_query

Consulta SQL, conforme vista pelo banco de dados PostgreSQL.

Configurações de exemplo

Configuração de exemplo #1

Retornar conteúdo da tabela cats (no 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";
        }
    }
}

Configuração de exemplo #2

Retornar apenas aquelas linhas da tabela sites que correspondem ao filtro host, que é avaliado para cada solicitação com base na variável $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'";
        }
    }
}

Configuração de exemplo #3

Passar a solicitação para o backend selecionado do banco de dados (roteador de tráfego).

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 necessários (além do ngx_postgres):

Configuração de exemplo #4

Restringir o acesso a arquivos locais autenticando contra o banco de dados 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 necessários (além do ngx_postgres):

Configuração de exemplo #5

Serviço web RESTful simples retornando respostas JSON com códigos de status HTTP apropriados.

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 necessários (além do ngx_postgres):

Configuração de exemplo #6

Usar parâmetro GET na 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 necessários (além do ngx_postgres):

Testes

ngx_postgres vem com um conjunto de testes completo baseado em Test::Nginx.

Você pode testar a funcionalidade principal executando:

$ TEST_NGINX_IGNORE_MISSING_DIRECTIVES=1 prove

Você também pode testar a interoperabilidade com os seguintes módulos:

executando:

$ prove

Veja também

GitHub

Você pode encontrar dicas adicionais de configuração e documentação para este módulo no repositório do GitHub para nginx-module-postgres.