PostgreSQL Docker Image
  • Shell 82.8%
  • Dockerfile 17.2%
Find a file
Torsten Raudssus 9a92cf1392 fix: auto-initialize pg_trickle and pg_cron extensions on first init
Both extensions are in shared_preload_libraries so their background
workers start on every boot. Without CREATE EXTENSION their schemas
don't exist and the schedulers crash in a loop. Run CREATE EXTENSION
IF NOT EXISTS for both during initdb so fresh databases work out of
the box.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-02 21:11:42 +02:00
.dockerignore docker should ignore bash history 2024-03-31 00:21:09 +01:00
.gitignore Updated to PostgreSQL 16 and added proper locale settings 2024-03-01 02:54:24 +01:00
docker-entrypoint.sh fix: auto-initialize pg_trickle and pg_cron extensions on first init 2026-04-02 21:11:42 +02:00
Dockerfile Change default locale from en_US to en_GB 2026-02-28 20:38:34 +01:00
README.md Change default locale from en_US to en_GB 2026-02-28 20:38:34 +01:00

PostgreSQL 18 Image

Production-ready PostgreSQL 18 Docker image with dynamic UID/GID, 13 pre-installed extensions, non-root execution, and automatic version mismatch detection.

src.ci/srv/postgres:latest

Quick Start

services:
  db:
    image: "src.ci/srv/postgres:latest"
    volumes:
      - "db-volume:/data"
    environment:
      POSTGRES_PASSWORD: "changeme"
docker run -d -e POSTGRES_PASSWORD=changeme -v db-data:/data src.ci/srv/postgres:latest

Key Features

  • Non-root execution — runs as postgres user, never as root
  • Dynamic UID/GID — configurable at build time to match your host permissions
  • 13 extensions — all pre-installed, activate on demand with CREATE EXTENSION
  • Version guard — detects old PG16/PG17 data and shows migration instructions
  • Healthcheck — built-in pg_isready check (30s interval, 3s timeout, 4 retries)
  • Docker secrets — supports POSTGRES_PASSWORD_FILE and friends
  • Init scripts — drop .sh, .sql, .sql.gz, .sql.xz, .sql.zst into /docker-entrypoint-initdb.d/

Extensions

All extensions are installed from the official PostgreSQL Debian repository, except pg_trickle which is built from source via pgrx.

Extension Version Description
age 1.7.0 Graph database extension (openCypher queries)
extra_window_functions 1.0 Additional window functions
numeral 1 Numeral datatypes
pg_cron 1.6 Job scheduler
pg_repack 1.5.3 Table reorganization with minimal locks
pg_similarity 1.0 String similarity functions
pg_trickle 0.1.2 Streaming differential view maintenance
pgmemcache 2.3.0 Memcached interface
pgpcre 1 Perl Compatible Regular Expressions
postgis 3.6.2 Geospatial types and functions
set_user 4.2.0 Dynamic user switching with audit logging
table_log 0.6.1 Table change logging
vector 0.8.2 Vector data type for AI/ML (ivfflat, hnsw)

Extensions that require shared_preload_libraries (pg_cron, pg_trickle) need additional configuration in postgresql.conf before they can be used.

Upgrading from PG16 or PG17

The entrypoint automatically detects if the mounted data directory (or any subdirectory) contains a database from an older PostgreSQL version and will abort with clear migration instructions:

ERROR: Found PostgreSQL 17 data in /data,
       but this container runs PostgreSQL 18.

You have two options:

pg_dump / pg_restore (safe, works always):

# 1. Dump from old container
docker exec old-pg pg_dumpall -U postgres > backup.sql
# 2. Start fresh PG18 container
docker run -d -e POSTGRES_PASSWORD=... -v new-data:/data src.ci/srv/postgres:18
# 3. Restore
docker exec -i new-pg psql -U postgres < backup.sql

pg_upgrade (faster, in-place) — requires both old and new PG binaries. See the pg_upgrade documentation.

Build Arguments

Build your own image with custom UID/GID:

services:
  db:
    image: "src.ci/srv/postgres:1010"
    volumes:
      - "db-volume:/data"
    environment:
      POSTGRES_USER: "myuser"
      POSTGRES_DB: "mydb"
      POSTGRES_PASSWORD: "mypass"
    build:
      context: "docker/postgres"
      args:
        SRV_UID: "1010"
        SRV_GID: "1010"
Argument Default Description
SRV_UID 1000 User ID for the postgres user and data ownership
SRV_GID 100 Group ID for the postgres user and data ownership
SRV_LOCALE en_GB Locale for initdb (extended with .UTF-8 for all LC_* categories)
SRV_VERSION 0 Version label (org.opencontainers.image.version)
SRV_APT_GET_INSTALL Additional Debian packages to install at build time

Important: The data directory /data must exist with matching UID/GID before the container starts. If Docker creates it, it will be root-owned and initdb will fail.

Image Details

Base image buildpack-deps:bookworm
PostgreSQL 18.3 (from apt.postgresql.org)
Data directory /data
User postgres (configurable UID/GID)
Home /var/lib/postgresql
Port 5432
Entrypoint Official docker-library/postgres entrypoint

Tags

Tag PostgreSQL Status
latest, 18 18.3 current
17 17.x archived

Support