Enhanced PostgreSQL images with HA support using Patroni and production-ready extensions
343
Production-ready PostgreSQL Docker images with useful extensions and optional Patroni-based high availability support.
This repository provides enhanced PostgreSQL images for users who need more than the minimal official PostgreSQL image. The images are designed for real-world workloads such as analytics, time-series data, vector search, auditing, query optimization, scheduled database jobs, and HA-ready PostgreSQL deployments.
Images can be used in two ways:
Depending on the selected tag, images may include:
For PostgreSQL 18 with extensions and Patroni support:
crypticani/postgres:18-alpine
The image can be used like a normal PostgreSQL container.
docker run -d \
--name postgres \
-e POSTGRES_USER=postgres \
-e POSTGRES_PASSWORD=postgres \
-e POSTGRES_DB=appdb \
-p 5432:5432 \
-v pgdata:/var/lib/postgresql \
crypticani/postgres:18-alpine
Connect to the database:
docker exec -it postgres psql -U postgres -d appdb
List installed extensions:
docker exec -it postgres psql -U postgres -d appdb -c "\dx"
List available extensions:
docker exec -it postgres psql -U postgres -d appdb -c "SELECT name, default_version FROM pg_available_extensions ORDER BY name;"
services:
postgres:
image: crypticani/postgres:18-alpine
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
POSTGRES_DB: appdb
PG_CRON_DATABASE: appdb
ports:
- "5432:5432"
volumes:
- ./data/postgres:/var/lib/postgresql
Start the container:
docker compose up -d
Check logs:
docker logs -f postgres
Connect:
docker exec -it postgres psql -U postgres -d appdb
The image supports the standard official PostgreSQL environment variables:
POSTGRES_USER
POSTGRES_PASSWORD
POSTGRES_DB
POSTGRES_INITDB_ARGS
POSTGRES_HOST_AUTH_METHOD
PGDATA
Some tags may also support additional variables:
PG_SHARED_PRELOAD_LIBRARIES
PG_CREATE_EXTENSIONS
PG_REQUIRED_AVAILABLE_EXTENSIONS
PG_CRON_DATABASE
Controls preload libraries used when PostgreSQL starts.
Example:
-e PG_SHARED_PRELOAD_LIBRARIES="timescaledb,pg_stat_statements,pg_cron,pgaudit"
To disable some preload libraries:
-e PG_SHARED_PRELOAD_LIBRARIES="timescaledb,pg_stat_statements"
Controls which extensions are automatically created during first database initialization.
Example:
-e PG_CREATE_EXTENSIONS="timescaledb pg_stat_statements pgcrypto vector"
To skip automatic extension creation:
-e PG_CREATE_EXTENSIONS=""
Controls the database where pg_cron is created.
Example:
-e PG_CRON_DATABASE=appdb
Create the extension manually if it was not auto-created:
CREATE EXTENSION IF NOT EXISTS timescaledb CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
Example table:
CREATE TABLE items (
id bigserial PRIMARY KEY,
embedding vector(3)
);
CREATE EXTENSION IF NOT EXISTS hypopg;
CREATE EXTENSION IF NOT EXISTS pg_cron;
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
CREATE EXTENSION IF NOT EXISTS pgaudit;
CREATE EXTENSION IF NOT EXISTS pg_repack;
Tags with Patroni support can be used as PostgreSQL nodes in an HA cluster.
Override the container command:
command: ["patroni", "/etc/patroni/patroni.yml"]
etcd is not bundled inside the PostgreSQL image. Run etcd separately.
Recommended HA layout:
postgres-1 -> this image running Patroni
postgres-2 -> this image running Patroni
postgres-3 -> this image running Patroni
etcd-1 -> external etcd node
etcd-2 -> external etcd node
etcd-3 -> external etcd node
haproxy -> routes writes to the current primary
pgbouncer -> optional connection pooling
This keeps the PostgreSQL image reusable and avoids mixing database runtime, distributed consensus, and traffic routing into one container.
docker run -d \
--name postgres-patroni-1 \
-v ./patroni.yml:/etc/patroni/patroni.yml:ro \
-v pgdata1:/var/lib/postgresql \
crypticani/postgres:18-alpine \
patroni /etc/patroni/patroni.yml
A valid Patroni configuration file and an external etcd cluster are required.
Some tags include a built-in healthcheck script:
postgres-extensions-healthcheck.sh
It checks:
Run manually:
docker exec -it postgres postgres-extensions-healthcheck.sh
Use a volume for PostgreSQL data:
-v pgdata:/var/lib/postgresql
For bind mounts:
-v /opt/postgres/data:/var/lib/postgresql
Do not store production data inside the container filesystem without a volume.
Before upgrading PostgreSQL, TimescaleDB, or any extension-heavy image:
Example dump:
docker exec postgres pg_dump -U postgres -d appdb > appdb.sql
Example restore:
cat appdb.sql | docker exec -i postgres psql -U postgres -d appdb
Single architecture:
docker buildx build \
--platform linux/amd64 \
-t crypticani/postgres:18-alpine \
--load \
.
Multi-architecture:
docker buildx build \
--platform linux/amd64,linux/arm64 \
-t crypticani/postgres:18-alpine \
--push \
.
Content type
Image
Digest
sha256:e4c465a8e…
Size
152.1 MB
Last updated
5 months ago
docker pull crypticani/postgres:18-alpine