No description
Find a file
Clément BREISCH fcc6ce6828
All checks were successful
Build and Test PostgreSQL Images / Load Configuration (push) Successful in 2s
Build and Test PostgreSQL Images / Build (PG 16) (push) Successful in 1m8s
Build and Test PostgreSQL Images / Build (PG 17) (push) Successful in 1m6s
Build and Test PostgreSQL Images / Build (PG 18) (push) Successful in 52s
Build and Test PostgreSQL Images / Functional Tests (PG 16) (push) Successful in 40s
Build and Test PostgreSQL Images / Functional Tests (PG 17) (push) Successful in 41s
Build and Test PostgreSQL Images / Functional Tests (PG 18) (push) Successful in 39s
Build and Test PostgreSQL Images / Security Scan (PG 17) (push) Successful in 54s
Build and Test PostgreSQL Images / Security Scan (PG 16) (push) Successful in 56s
Build and Test PostgreSQL Images / Compliance Scan (PG 16) (push) Successful in 17s
Build and Test PostgreSQL Images / Compliance Scan (PG 17) (push) Successful in 14s
Build and Test PostgreSQL Images / Compliance Scan (PG 18) (push) Successful in 13s
Build and Test PostgreSQL Images / Security Scan (PG 18) (push) Successful in 51s
Build and Test PostgreSQL Images / Push (PG 16) (push) Successful in 7s
Build and Test PostgreSQL Images / Push (PG 17) (push) Successful in 7s
Build and Test PostgreSQL Images / Push (PG 18) (push) Successful in 7s
Build and Test PostgreSQL Images / Tag Latest (push) Successful in 6s
Build and Test PostgreSQL Images / Cleanup (push) Successful in 0s
add utc timestamps to all log messages in postgres-entrypoint
2026-01-05 13:53:14 +00:00
.github/workflows docs: update healthcheck documentation and add --health-check test 2025-12-29 19:50:20 +00:00
backup-sidecar fix scheduler cron triggers, add utc timestamps and retention debug logging 2026-01-05 13:40:41 +00:00
postgres healthcheck: use entrypoint with --health-check flag for distroless 2025-12-29 19:46:41 +00:00
postgres-backup docs: update healthcheck documentation and add --health-check test 2025-12-29 19:50:20 +00:00
postgres-entrypoint add utc timestamps to all log messages in postgres-entrypoint 2026-01-05 13:53:14 +00:00
.gitignore add backup sidecar 2025-12-28 17:38:26 +00:00
.metadata.json migrate to JSON metadata, use jq instead of yq 2025-12-21 22:01:30 +00:00
LICENSE first push 2025-12-20 16:26:42 +00:00
README.md docs: update healthcheck documentation and add --health-check test 2025-12-29 19:50:20 +00:00
SECURITY.md docs: fix runtime hardening tmpfs uid/gid and volume mount path 2025-12-29 18:37:27 +00:00
test-backup.sh add backup sidecar 2025-12-28 17:38:26 +00:00

PostgreSQL Distroless

Build

Minimal, secure PostgreSQL container images based on Google's distroless base.

Features

  • Minimal footprint: ~61MB per image (vs ~400MB for official postgres)
  • Multi-architecture: linux/amd64 and linux/arm64
  • Distroless base: No shell, no package manager, reduced attack surface
  • Multiple versions: PostgreSQL 16, 17, and 18
  • Security-first: Runs as non-root (UID 65532), binaries owned by root
  • TLS support: Auto-detection of SSL certificates
  • Docker secrets: Support for _FILE suffix environment variables

Quick Start

# Basic usage
docker run -d \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -p 5432:5432 \
  git.breis.ch/images/postgres:18

# With persistent data
docker run -d \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -v pgdata:/var/lib/postgresql \
  -p 5432:5432 \
  git.breis.ch/images/postgres:18

Available Tags

Tag PostgreSQL Version Notes
18, latest 18.x Latest stable
17 17.x LTS
16 16.x LTS

Environment Variables

Core Settings

Variable Default Description
POSTGRES_PASSWORD (required) Superuser password
POSTGRES_USER postgres Superuser name
POSTGRES_DB postgres Default database
POSTGRES_HOST_AUTH_METHOD scram-sha-256 Authentication method
POSTGRES_INITDB_ARGS - Additional initdb arguments
POSTGRES_INITDB_WALDIR - Separate WAL directory
PGDATA /var/lib/postgresql/{version}/data Data directory

Performance & Limits

Variable Default Description
POSTGRES_MAX_CONNECTIONS 100 Maximum concurrent connections
POSTGRES_STATEMENT_TIMEOUT - Query timeout (e.g., 30s, 5min)
POSTGRES_IDLE_IN_TRANSACTION_SESSION_TIMEOUT - Idle transaction timeout
POSTGRES_LOCK_TIMEOUT - Lock wait timeout (e.g., 10s)
POSTGRES_TEMP_FILE_LIMIT - Temp file disk limit (e.g., 1GB)

Logging

Variable Default Description
LOG_LEVEL info Log level for entrypoint and PostgreSQL
POSTGRES_LOG_CONNECTIONS on Log connection attempts
POSTGRES_LOG_DISCONNECTIONS on Log disconnections
POSTGRES_LOG_LOCK_WAITS on Log lock contention
POSTGRES_LOG_TEMP_FILES 0 Log temp file creation (0 = all)

LOG_LEVEL values:

Value Numeric Entrypoint PostgreSQL log_min_messages PostgreSQL log_statement
error 0 Errors only error none
warn 1 Warnings + errors warning none
info 2 Info + warnings + errors notice none
debug 3 All messages debug1 all

TLS/SSL

Variable Default Description
POSTGRES_SSL off Set to on to warn if certs not found
POSTGRES_SSL_REQUIRE off Set to on to require SSL for remote connections

See SECURITY.md for detailed TLS configuration.

Docker Secrets

All POSTGRES_* variables support the _FILE suffix for Docker secrets:

docker run -d \
  -e POSTGRES_PASSWORD_FILE=/run/secrets/db_password \
  -v /path/to/secrets:/run/secrets:ro \
  git.breis.ch/images/postgres:18

TLS/SSL Quick Start

# Generate certificates
openssl req -new -x509 -days 365 -nodes \
  -out server.crt -keyout server.key \
  -subj "/CN=postgres"
chmod 600 server.key

# Run with TLS
docker run -d \
  -e POSTGRES_PASSWORD=mysecretpassword \
  -v $(pwd)/server.crt:/var/lib/postgresql/ssl/server.crt:ro \
  -v $(pwd)/server.key:/var/lib/postgresql/ssl/server.key:ro \
  -p 5432:5432 \
  git.breis.ch/images/postgres:18

SSL certificates must be placed in /var/lib/postgresql/ssl/. See SECURITY.md for hardening details.

Volumes

Path Description
/var/lib/postgresql Data directory (mount for persistence)
/var/run/postgresql Unix socket directory

Ports

Port Description
5432 PostgreSQL

Healthcheck

The image includes a built-in healthcheck that uses pg_isready via the entrypoint:

HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
    CMD ["/entrypoint", "--health-check"]

The --health-check flag runs pg_isready with the correct PG_MAJOR path and POSTGRES_USER. Check status:

docker inspect --format='{{.State.Health.Status}}' container_name

Security

See SECURITY.md for:

  • TLS/SSL configuration and hardening
  • Runtime hardening flags
  • Kubernetes SecurityContext
  • Audit logging
  • Security checklist

Backup Sidecar

A companion postgres-backup image is available for scheduled backups with:

  • Cron-based scheduling
  • Multiple compression algorithms (gzip, zstd)
  • Proxmox-style retention policies
  • Age encryption support
  • Webhook notifications
  • Built-in restore utility

See postgres-backup/README.md for full documentation.

Quick example:

services:
  postgres:
    image: git.breis.ch/images/postgres:16
    environment:
      POSTGRES_PASSWORD: ${DB_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql

  backup:
    image: git.breis.ch/images/postgres-backup:16
    environment:
      PGHOST: postgres
      PGPASSWORD: ${DB_PASSWORD}
      BACKUP_SCHEDULE: "0 2 * * *"
      BACKUP_KEEP_DAILY: "7"
    volumes:
      - backup-data:/backups
    depends_on:
      - postgres

License

PostgreSQL License (same as PostgreSQL itself)