Compartir comentarios
Las respuestas se generan en base a la documentación.

Configuración avanzada e inicialización

Con el almacenamiento persistente configurado en la sección anterior, estás listo para personalizar PostgreSQL para su uso en el mundo real. Esta guía cubre técnicas de configuración avanzada para ejecutar PostgreSQL en contenedores de Docker, incluyendo la inicialización automatizada de bases de datos, el ajuste de rendimiento y la configuración de la zona horaria.

Descripción general

Aunque los contenedores de PostgreSQL se pueden iniciar rápidamente con la configuración predeterminada, los entornos de producción requieren configuraciones personalizadas. Esta guía explica cómo:

  • Automatizar la creación de bases de datos, esquemas y usuarios durante el inicio del contenedor
  • Ajustar los parámetros de rendimiento de PostgreSQL para cargas de trabajo contenedorizadas
  • Configurar la zona horaria y el idioma (locale)

Scripts de inicialización

La imagen oficial de Docker para PostgreSQL admite la ejecución automática de scripts de inicialización cuando el contenedor se inicia por primera vez. Cualquier archivo colocado en el directorio /docker-entrypoint-initdb.d/ se ejecuta en orden alfabético.

Cómo funciona la inicialización

Cuando el contenedor se inicia, verifica si el directorio de datos de PostgreSQL está vacío. Si el directorio ya contiene datos, PostgreSQL se inicia inmediatamente sin realizar ninguna inicialización. Si el directorio está vacío, el contenedor ejecuta initdb para crear un nuevo clúster de base de datos, luego ejecuta todos los scripts en /docker-entrypoint-initdb.d/ en orden alfabético antes de iniciar PostgreSQL.

Formatos de archivo compatibles

FormatoDescripción
.sqlComandos SQL ejecutados directamente
.sql.gzArchivos SQL comprimidos con Gzip
.shScripts de shell ejecutados con bash
Important

Los scripts de inicialización solo se ejecutan cuando el directorio de datos de PostgreSQL (/var/lib/postgresql/data) está vacío. Si montas un volumen que contiene datos existentes, se omitirá la inicialización. Este comportamiento evita que se sobrescriban las bases de datos existentes.

Montar scripts de inicialización

Usa Docker Compose para montar scripts de inicialización en el contenedor. Primero, crea un directorio de proyecto:

$ mkdir -p postgres-project/init-db
$ cd postgres-project

Crea un archivo compose.yaml:

services:
  db:
    image: postgres:18
    volumes:
      - ./init-db:/docker-entrypoint-initdb.d
      - postgres_data:/var/lib/postgresql
    environment:
      POSTGRES_PASSWORD: mysecretpassword

volumes:
  postgres_data:

Todos los scripts en el directorio ./init-db se ejecutan cuando el contenedor se inicia por primera vez. Esto es ideal para inicializar bases de datos.

Ejemplo de script de inicialización

Crea un archivo llamado init.sql en tu directorio init-db:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    email VARCHAR(255) UNIQUE NOT NULL,
    name VARCHAR(100) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Este script se ejecuta automáticamente cuando el contenedor se inicia por primera vez, creando tu esquema de base de datos inicial.

Note

Asegúrate de que los scripts de inicialización tengan los permisos de lectura adecuados. Si te encuentras con errores de "Permiso denegado", ejecuta chmod 644 init-db/*.sql para que los archivos sean legibles por el contenedor.

Ajuste de rendimiento

La configuración predeterminada de PostgreSQL es conservadora para funcionar en sistemas con recursos limitados. Para cargas de trabajo de producción, debes ajustar estos parámetros según los recursos asignados a tu contenedor.

Método 1: Archivo de configuración personalizado

Para obtener un control total, monta un archivo postgresql.conf personalizado. Primero, extrae la configuración predeterminada:

$ docker run -i --rm postgres:18 cat /usr/share/postgresql/postgresql.conf.sample > my-postgres.conf

Edita my-postgres.conf con la configuración deseada, luego móntalo en tu archivo de Compose:

services:
  db:
    image: postgres:18
    volumes:
      - ./my-postgres.conf:/etc/postgresql/postgresql.conf
      - ./init-db:/docker-entrypoint-initdb.d
      - postgres_data:/var/lib/postgresql
    command: postgres -c config_file=/etc/postgresql/postgresql.conf
    environment:
      POSTGRES_PASSWORD: mysecretpassword

volumes:
  postgres_data:

Parámetros clave de configuración

Las siguientes tablas enumeran parámetros importantes de postgresql.conf para despliegues contenedorizados de PostgreSQL.

Configuración de conexión

ParámetroDescripciónValor predeterminado
listen_addressesDirecciones IP en las que escucharlocalhost
portNúmero de puerto TCP5432
max_connectionsMáximo de conexiones concurrentes100

Configuración de memoria

ParámetroDescripciónValor inicial recomendado
shared_buffersMemoria compartida para caché25% de la memoria del contenedor
work_memMemoria por operación de consulta4MB - 64MB
maintenance_work_memMemoria para VACUUM, CREATE INDEX64MB - 256MB
effective_cache_sizeEstimación del tamaño de caché del planificador50-75% de la memoria del contenedor

Límites de memoria de Docker

Al ajustar los parámetros de memoria, establece límites de memoria explícitos en tu contenedor utilizando deploy.resources.limits.memory en Compose o --memory con docker run. Sin límites, PostgreSQL ve la RAM total del host y podría asignar más de lo previsto. Por ejemplo, si tu contenedor debe usar un máximo de 4 GB, establece shared_buffers en aproximadamente 1 GB (25%).

Configuración de E/S

ParámetroDescripciónValor inicial recomendado
effective_io_concurrencyOperaciones de E/S de disco concurrentes200 para SSD, 2 para HDD

Configuración de límites de tiempo (timeout)

ParámetroDescripciónValor predeterminado
statement_timeoutTiempo máximo para cualquier sentencia0 (desactivado)
lock_timeoutTiempo máximo de espera para un bloqueo0 (desactivado)
deadlock_timeoutTiempo antes de verificar un interbloqueo (deadlock)1s
transaction_timeoutTiempo máximo para una transacción0 (desactivado)
Note

Establecer shared_buffers demasiado alto en un contenedor puede exceder los límites de memoria compartida del kernel. No uses más del 25-30% del límite de memoria del contenedor.

Configuración de zona horaria e idioma (locale)

Una localización adecuada garantiza que las marcas de tiempo y el ordenamiento se comporten correctamente para los usuarios de tu aplicación.

services:
  db:
    image: postgres:18
    volumes:
      - postgres_data:/var/lib/postgresql
      - /etc/localtime:/etc/localtime:ro
      - /etc/timezone:/etc/timezone:ro
    environment:
      POSTGRES_PASSWORD: mysecretpassword
      TZ: America/New_York

volumes:
  postgres_data:

Alternativamente, establece la zona horaria usando un parámetro de línea de comandos de PostgreSQL:

services:
  db:
    image: postgres:18
    command: ["postgres", "-c", "timezone=America/New_York"]
    environment:
      POSTGRES_PASSWORD: mysecretpassword

Configurar el idioma (locale)

Especifica la configuración de idioma (locale) durante la inicialización de la base de datos usando la variable de entorno POSTGRES_INITDB_ARGS:

services:
  db:
    image: postgres:18
    volumes:
      - postgres_data:/var/lib/postgresql
    environment:
      POSTGRES_PASSWORD: mysecretpassword
      POSTGRES_INITDB_ARGS: "--encoding=UTF8 --lc-collate=en_US.UTF-8 --lc-ctype=en_US.UTF-8"

volumes:
  postgres_data:

Esto afecta a la colación (ordenamiento) y al comportamiento de procesamiento de caracteres. Cambiar esta variable después de la creación de la base de datos no tiene ningún efecto: solo se aplica durante la primera ejecución cuando se inicializa el directorio de datos.

Conectarse a la base de datos

Puedes interactuar con PostgreSQL ejecutándose en un contenedor incluso sin tener psql instalado en tu máquina host.

Shell interactivo

Abre una sesión de psql dentro del contenedor:

$ docker exec -it postgres-container psql -U postgres

Conéctate a una base de datos específica:

$ docker exec -it postgres-container psql -U postgres -d mydb