Conectar sua aplicação ao banco
Este guia mostra como conectar uma aplicação ao PostgreSQL ou ao MariaDB da Zenifra com os drivers mais usados em Python, Node.js e Bun. Todas as conexões usam TLS e validam o certificado e o hostname do banco.
Antes de começar
- Abra o banco no console e copie a URI de conexão. A senha completa aparece somente na criação ou depois de uma rotação de senha.
- No projeto da aplicação, abra Variáveis de Ambiente e crie
DATABASE_URLcom essa URI. - Use sempre o host mostrado no console, no formato
postgresql-<id>.managed.zenifra.comoumariadb-<id>.managed.zenifra.com. O certificado é emitido para esse nome, então conexões pelo endereço IP falham na validação.
Não desative a validação do certificado para "fazer funcionar": não use sslmode=require, sslmode=disable, rejectUnauthorized: false ou opções equivalentes. Os ajustes abaixo resolvem os casos conhecidos mantendo a validação completa.
Resumo por driver
| Banco | Linguagem | Driver | O que fazer |
|---|---|---|---|
| PostgreSQL | Terminal | psql | Use a URI do console sem alterações |
| PostgreSQL | Python | psycopg / psycopg2 (pacotes binary) | Defina SSL_CERT_FILE |
| PostgreSQL | Python | asyncpg | Remova sslrootcert da URI e passe um contexto TLS |
| PostgreSQL | Node.js e Bun | pg (node-postgres) | Remova &sslrootcert=system da URI |
| PostgreSQL | Node.js e Bun | postgres (postgres.js) | Use a URI do console sem alterações |
| PostgreSQL | Bun | Bun.sql | Use a URI do console sem alterações |
| MariaDB | Node.js | mariadb | Use a URI do console sem alterações |
| MariaDB | Node.js e Bun | mysql2 | Configure ssl como objeto, com verifyIdentity |
| MariaDB | Python | PyMySQL | Informe o bundle de CAs e ative a verificação de identidade |
PostgreSQL
A URI PostgreSQL do console termina com ?sslmode=verify-full&sslrootcert=system. Esses parâmetros exigem TLS, validam a cadeia de certificados pelo armazenamento confiável do sistema e conferem o hostname. Alguns drivers não entendem sslrootcert=system e precisam dos ajustes abaixo.
psql
psql "$DATABASE_URL"Versões do psql que não suportam sslrootcert=system aceitam o caminho do bundle de CAs do sistema no lugar de system, por exemplo sslrootcert=/etc/ssl/certs/ca-certificates.crt.
Python com psycopg ou psycopg2
Os pacotes psycopg[binary] e psycopg2-binary trazem uma biblioteca TLS própria, que não encontra os certificados do sistema. Sem ajuste, a conexão falha com SSL error: certificate verify failed.
Defina a variável de ambiente abaixo no projeto. Ela aponta o driver para o bundle de CAs do sistema, e a URI continua igual:
SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crtimport os
import psycopg
with psycopg.connect(os.environ["DATABASE_URL"]) as conn:
conn.execute("SELECT 1")Aplicações Python publicadas na Zenifra sem Dockerfile próprio já recebem essa variável. Se a aplicação foi publicada antes de 21/10/2026, faça um novo deploy. Com Dockerfile próprio, adicione ENV SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt e confirme que a imagem instala o pacote ca-certificates. Django e SQLAlchemy usam o psycopg ou o psycopg2 por baixo e seguem a mesma regra.
Python com asyncpg
O asyncpg trata sslrootcert=system como o nome de um arquivo e falha com FileNotFoundError. Remova o sslrootcert da URI e passe um contexto TLS que valida certificado e hostname:
import os
import ssl
import asyncpg
dsn = os.environ["DATABASE_URL"].split("?")[0]
conn = await asyncpg.connect(dsn, ssl=ssl.create_default_context())Node.js e Bun com pg (node-postgres)
O pg trata sslrootcert=system como o nome de um arquivo e falha com ENOENT: no such file or directory, open 'system'. Remova &sslrootcert=system e mantenha sslmode=verify-full. Assim, o driver valida certificado e hostname com os CAs do próprio Node.js:
DATABASE_URL=postgresql://app:<senha>@<host>:<porta>/app?sslmode=verify-fullimport pg from 'pg'
const client = new pg.Client({ connectionString: process.env.DATABASE_URL })
await client.connect()Node.js e Bun com postgres.js
import postgres from 'postgres'
const sql = postgres(process.env.DATABASE_URL)
await sql`SELECT 1`Bun com Bun.sql
const sql = new Bun.SQL(process.env.DATABASE_URL)
await sql`SELECT 1`MariaDB
A URI MariaDB do console usa o formato mariadb://app:<senha>@<host>:<porta>/app?ssl=true.
Node.js com mariadb
import mariadb from 'mariadb'
const conn = await mariadb.createConnection(process.env.DATABASE_URL)
await conn.query('SELECT 1')No Bun, use o mysql2 em vez do conector mariadb.
Node.js e Bun com mysql2
O mysql2 não aceita ssl=true na URI e falha com SSL profile must be an object. Passe os dados de conexão como objeto. O verifyIdentity: true é necessário para o driver conferir o hostname do certificado:
import mysql from 'mysql2/promise'
const url = new URL(process.env.DATABASE_URL)
const conn = await mysql.createConnection({
host: url.hostname,
port: Number(url.port),
user: decodeURIComponent(url.username),
password: decodeURIComponent(url.password),
database: url.pathname.slice(1),
ssl: { rejectUnauthorized: true, verifyIdentity: true },
})Python com PyMySQL
import os
from urllib.parse import unquote, urlsplit
import pymysql
url = urlsplit(os.environ["DATABASE_URL"])
conn = pymysql.connect(
host=url.hostname,
port=url.port,
user=unquote(url.username),
password=unquote(url.password),
database=url.path.lstrip("/"),
ssl_ca="/etc/ssl/certs/ca-certificates.crt",
ssl_verify_cert=True,
ssl_verify_identity=True,
)O caminho /etc/ssl/certs/ca-certificates.crt existe em imagens Debian, Ubuntu e Alpine com o pacote ca-certificates instalado. Em outros sistemas, use o bundle de CAs correspondente.
Erros comuns
| Mensagem | Causa | Como resolver |
|---|---|---|
SSL error: certificate verify failed | Driver Python com biblioteca TLS própria não encontra os CAs do sistema | Defina SSL_CERT_FILE como em psycopg ou psycopg2 |
ENOENT: no such file or directory, open 'system' | O pg trata sslrootcert=system como arquivo | Remova &sslrootcert=system da URI |
FileNotFoundError no asyncpg | O asyncpg trata sslrootcert=system como arquivo | Remova sslrootcert e passe ssl=ssl.create_default_context() |
SSL profile must be an object | O mysql2 não aceita ssl=true na URI | Passe ssl como objeto |
Hostname/IP does not match certificate's altnames ou IP address mismatch | A conexão usa um IP ou outro nome no lugar do host do console | Use o host exato mostrado no console |
password authentication failed ou Access denied | A senha na DATABASE_URL não é a atual | Confira a senha ou gere uma nova na edição do banco e atualize a variável na aplicação |
Próximos passos
Última atualização em