Skip to content

Repository files navigation

Postgres + PgBackRest

Maintained by EthosLink Docker Pulls

A production-ready PostgreSQL image with PgBackRest preinstalled and sensible default configuration.

Maintained by EthosLink, the company behind Reviato, Nuntio, and Profix. This image comes from our database operations work for Reviato.

The goal is simple: make it easy to run Postgres with backups and predictable configuration without turning your repo into an ops research project.

More from EthosLink

We build business products and share the engineering tools behind our work.

Products

  • Reviato — Understand what customers are telling you. Collect private feedback, explore recurring themes in public reviews, and keep the original words and follow-up details close at hand.
  • Nuntio — Prepare social posts ahead of time. Keep drafts, channel-specific versions, team review, scheduling, and publishing outcomes in one workspace.
  • Profix — See what sold, what it earned, and what is still on the shelf. Profit and stock analysis for clothing shops and boutiques. Early access.

Open source

  • postgres-backrest — This PostgreSQL image: PgBackRest preinstalled, WAL archiving defaults, and configuration you can mount and manage yourself.
  • git-markdown — Export a GitHub pull request, reviews, and discussion into one Markdown file for offline review, AI workflows, or engineering handoffs.
  • indexmap — Build and validate XML sitemaps from explicit Ruby definitions, with Rails tasks and safe publishing that keeps the last good files if generation fails.
  • Crawlscope — Crawl your sitemap to check indexability, metadata, structured data, and internal links. Use structured findings in scripts, a CLI, or Rails tasks.

See the product and project guide for more detail and useful next steps, or browse all products and open-source project notes.


What you get

  • PostgreSQL + PgBackRest in one image (based on the upstream postgres image)
  • WAL archiving-ready defaults (pair this with a PgBackRest repo config)
  • Bring-your-own postgresql.conf (pgtune-friendly) via a mounted file
  • Drop-in overrides via /etc/postgresql/conf.d/*.conf (optional)
  • Multi-arch support (amd64, arm64)

Quickstart

docker run --init \
 -e POSTGRES_PASSWORD=mysecretpassword \
 ethoslink/postgres-backrest:latest

Configuration

PostgreSQL Configuration

The image ships with a default /etc/postgresql/postgresql.conf.

For anything beyond a couple of settings, the recommended practice is to provide a real Postgres config file (for example one generated by https://pgtune.leopard.in.ua) and mount it into the container.

Option A (simplest): replace the default config

  1. Generate a config on pgtune.
  2. Save it as postgresql.conf.
  3. Mount it to /etc/postgresql/postgresql.conf.

Example (docker run):

docker run --init \
 -e POSTGRES_PASSWORD=mysecretpassword \
 -v "$PWD/postgresql.conf:/etc/postgresql/postgresql.conf:ro" \
 ethoslink/postgres-backrest:latest

Option B: mount the config elsewhere and point Postgres at it

Set POSTGRES_CONFIG_FILE to the file you mounted:

docker run --init \
 -e POSTGRES_PASSWORD=mysecretpassword \
 -e POSTGRES_CONFIG_FILE=/etc/postgresql/pgtune/postgresql.conf \
 -v "$PWD/postgresql.conf:/etc/postgresql/pgtune/postgresql.conf:ro" \
 ethoslink/postgres-backrest:latest

Option C: mount small overrides (recommended when you only need a couple of changes)

The shipped postgresql.conf includes include_dir = 'conf.d', so you can mount a small snippet without replacing the full file:

docker run --init \
 -e POSTGRES_PASSWORD=mysecretpassword \
 -v "$PWD/overrides.conf:/etc/postgresql/conf.d/overrides.conf:ro" \
 ethoslink/postgres-backrest:latest

Notes

  • PostgreSQL doesn't provide a standardized set of environment variables for tuning knobs like shared_buffers, work_mem, effective_cache_size, etc. The established approach is to manage postgresql.conf (and optionally conf.d snippets) as configuration artifacts.
  • If you use container memory limits, treat pgtune output as a baseline and validate values against your runtime limits.

Extra knobs supported by this image

  • POSTGRES_CONFIG_FILE (default: /etc/postgresql/postgresql.conf)
  • POSTGRES_HBA_FILE (default: /etc/postgresql/pg_hba.conf)

These are used to inject -c config_file=... and -c hba_file=... when the container is started with the postgres command.

PgBackRest Configuration

Run the container with --init (or init: true in Docker Compose). PgBackRest's asynchronous archiver starts background processes; an init process reaps them so PostgreSQL does not receive their exit notifications.

On startup, the container renders /etc/pgbackrest/pgbackrest.conf from the template at /usr/local/share/pgbackrest/pgbackrest.conf.template using envsubst.

The default template is intentionally minimal and local-by-default. To customize PgBackRest behavior (including S3/R2/backends, retention, compression, etc.), provide your own template by mounting it into the container at:

  • /usr/local/share/pgbackrest/pgbackrest.conf.template

See the shipped template in this repo at postgres-backrest/pgbackrest.conf.template.

Common env vars referenced by the default template:

  • PGBACKREST_REPO1_PATH
  • PGBACKREST_REPO1_RETENTION_FULL
  • PGBACKREST_REPO1_RETENTION_DIFF
  • PGBACKREST_PROCESS_MAX
  • PGBACKREST_LOG_LEVEL_CONSOLE
  • PGBACKREST_LOG_LEVEL_FILE
  • PGBACKREST_LOG_PATH
  • PGBACKREST_COMPRESS_TYPE
  • PGBACKREST_COMPRESS_LEVEL
  • PGBACKREST_PG1_PATH

File and console logging default to info (including warnings and errors). Use docker exec --user postgres <container> pgbackrest-docker --stanza=main backup for scheduled backups: the helper sends output to Docker's logger and disables duplicate file logging for that invocation. Use plain pgbackrest for archiving; detached asynchronous workers need their file logs at /var/log/pgbackrest. Set PGBACKREST_LOG_LEVEL_FILE=debug explicitly for troubleshooting.

Production deployments should bind-mount the file log directory and install the ops/ configuration for the host's existing logrotate.timer and native tmpfiles cleanup. Docker rotates console logs; OS logrotate handles file logs. The image runs no scheduler or log tailer. See the logging operations guide for Docker settings, installation, 14-day file retention, migration, safe cleanup, archive health checks and rollback. Upgrading the image alone does not install the host rotation policy.


Building

To build the image locally with a specific PostgreSQL version:

# Using update.sh (recommended)
./update.sh <version>
docker build --build-arg POSTGRES_VERSION=<version> -t ethoslink/postgres-backrest:<version> .

# Or directly with build-arg
docker build --build-arg POSTGRES_VERSION=18.2 -t ethoslink/postgres-backrest:18.2 .

To publish the multi-arch image for linux/amd64 and linux/arm64, use Buildx:

docker login docker.io
docker login ghcr.io
./build.sh

The script pushes both the version tag and latest to Docker Hub and GHCR. POSTGRES_VERSION is the upstream base image tag. IMAGE_VERSION is this image's published release tag. Keep them separate when rebuilding this image on the same PostgreSQL release.

For image-only rebuilds, prefer a revision suffix such as 18.3-r1 over 18.3.1, because 18.3.1 can be mistaken for an upstream PostgreSQL patch version.

Override PLATFORMS, POSTGRES_VERSION, IMAGE_VERSION, PUBLISH_LATEST, or IMAGES when needed:

PLATFORMS=linux/amd64,linux/arm64 \
POSTGRES_VERSION=18.3 \
IMAGE_VERSION=18.3-r1 \
IMAGES="docker.io/ethoslink/postgres-backrest ghcr.io/ethos-link/postgres-backrest" \
./build.sh

build.sh refuses to publish an image version that already exists in any target registry. Use a new IMAGE_VERSION for normal releases.

The GitHub Actions publish workflow also builds and pushes linux/amd64,linux/arm64 on main.

Security & Maintenance

The image is based on the official Debian-based PostgreSQL image and installs pgbackrest from the official apt repositories.

  • Updates: Images are immutable. To get security updates, pull a newer tag.
  • Scanning: We run Trivy scans on every build to monitor for vulnerabilities.

Publishing

The image is published to:

Creating a Release

To bump the PostgreSQL version and create a new release:

# Bump the base and image versions
./update.sh 18.3

# Commit and push
git add -A && git commit -m "build(release): bump PostgreSQL to 18.3" -m "Update the base image and release version together."
git push origin <branch>

Then create a PR and merge to main. GitHub Actions will:

  1. Refuse to publish if the image version tag already exists
  2. Build and push the Docker image with the new image version tag
  3. Create a git tag (e.g., 18.3)
  4. Create a GitHub Release

For an image-only rebuild on the same PostgreSQL base version, pass a revision:

./update.sh 18.3 -r=1

This keeps POSTGRES_VERSION=18.3 and sets IMAGE_VERSION=18.3-r1.

You can also pass a base version and revision manually to trigger a workflow dispatch:

# Via GitHub UI to manually trigger a build
# Or via CLI:
gh workflow run publish.yml -f postgres_version=18.3 -f revision=1

License

MIT

Releases

Sponsor this project

Packages

Contributors

Languages