Databases AWS

pgBackRest PostgreSQL Backup Host on AWS User Guide

| Product: pgBackRest on AWS

Overview

This image is a complete, working PostgreSQL backup host built around pgBackRest, the reliable, high-performance backup and restore solution for PostgreSQL. On its own pgBackRest is a command-line tool; this image ships it fully configured against a pinned PostgreSQL 18 server, so you launch a running appliance rather than assembling one. It installs pgBackRest 2.58.0 and PostgreSQL 18 from the official PostgreSQL (PGDG) package repository, with an encrypted local repository on a dedicated data volume, WAL archiving wired through pgbackrest archive-push, scheduled full, differential and incremental backups plus scheduled repository verification on systemd timers, and a restore path that is proven end to end at build time and re-proven on every instance at first boot.

This is a headless image. There is no web interface; you operate it over SSH with the pgbackrest and psql command-line tools. PostgreSQL binds to loopback only on 127.0.0.1:5432 and is never exposed to the network, so the database engine stays private. Password authentication uses scram-sha-256 and there is no trust rule anywhere in pg_hba.conf.

On the first boot of your instance a one-shot service generates two secrets unique to that instance - the PostgreSQL superuser password and the repository encryption passphrase - creates the pgBackRest stanza, takes and verifies an initial full backup, enables the scheduled timers, and writes the secrets to /root/pgbackrest-credentials.txt, a file that only the root user can read. No shared or default credential ships in the image.

The pgBackRest repository lives on a dedicated, independently resizable EBS data volume mounted at /var/lib/pgbackrest, so your backups sit on durable storage you can grow, snapshot and back up independently of the operating system disk. Backup growth can never fill the OS disk.

Prerequisites

Before you deploy this image you need:

  • An Amazon Web Services account where you can launch EC2 instances
  • IAM permissions to launch instances, create security groups, and subscribe to AWS Marketplace products
  • An EC2 key pair in the target Region for SSH access to the instance
  • A VPC and subnet in the target Region, with a security group allowing inbound port 22 from your management network
  • The AWS CLI (version 2) installed locally if you plan to deploy from the command line

Recommended instance type: m5.large (2 vCPU, 8 GB RAM) or larger. Size the repository volume to your dataset and retention policy.

Step 1: Launch the Instance from the AWS Marketplace

Sign in to the AWS Management Console, open the EC2 service, and select Launch instance. Under Application and OS Images choose AWS Marketplace AMIs and search for pgBackRest. Select the cloudimg listing and choose Select, then Continue on the subscription summary.

Pick an instance type of m5.large or larger. Choose your EC2 key pair under Key pair (login). Under Network settings select your VPC and subnet, and either create or select a security group that allows inbound port 22 from your management network. Leave the root volume at the default size or larger; the pgBackRest repository volume is attached automatically from the image.

Select Launch instance. First boot initialisation runs once after the instance state becomes Running and the status checks pass: it generates the per-instance secrets, creates the stanza, takes and verifies an initial full backup, and enables the scheduled timers. This takes a minute or two on first boot.

Step 2: Launch the Instance from the AWS CLI

The following block launches an instance from the cloudimg pgBackRest Marketplace AMI into an existing subnet and security group. Replace <ami-id> with the AMI ID shown on the Marketplace listing, <key-name> with your EC2 key pair name, <subnet-id> with your subnet ID, and <security-group-id> with a security group that opens port 22 from your management network.

aws ec2 run-instances \
  --image-id <ami-id> \
  --instance-type m5.large \
  --key-name <key-name> \
  --subnet-id <subnet-id> \
  --security-group-ids <security-group-id> \
  --metadata-options HttpTokens=required \
  --tag-specifications 'ResourceType=instance,Tags=[{Key=Name,Value=pgbackrest}]'

When the instance reaches the Running state and its status checks pass, note its public IP address or DNS name from the EC2 console or with aws ec2 describe-instances.

Step 3: Connect to Your Instance

Connect over SSH using your key pair and the login user for your operating system variant.

OS variant SSH login user
Ubuntu 24.04 ubuntu
ssh -i <key-name>.pem ubuntu@<public-ip>

A welcome banner prints the most useful commands. The per-instance PostgreSQL superuser password and the repository encryption passphrase that first boot generated live in a root-only file. You can view them (only root can read the file) with the command below. Because the file contains secrets, this guide does not print its contents.

sudo cat /root/pgbackrest-credentials.txt

You can confirm the credentials file exists with the correct owner and 0600 permissions without revealing its contents:

sudo ls -l /root/pgbackrest-credentials.txt

Step 4: Confirm pgBackRest and PostgreSQL

pgBackRest and PostgreSQL are installed from the official PostgreSQL (PGDG) package repository at pinned versions. Confirm the pgBackRest version:

pgbackrest version

That prints pgBackRest 2.58.0. PostgreSQL runs as a system service that is enabled and started on boot. Confirm it is active:

systemctl is-active postgresql@18-main.service

That prints active. Confirm the listener is bound to loopback only, so the database is never exposed to the network:

ss -tlnH | grep ':5432'

The address is 127.0.0.1:5432, never 0.0.0.0.

pgBackRest 2.58.0 and PostgreSQL 18 running on the instance with the database bound to the loopback address 127.0.0.1:5432 only

Step 5: Check the Configuration and Take a Backup

pgbackrest check validates the configuration, the repository and WAL archiving end to end. It is safe to run at any time and makes no changes:

sudo -u postgres pgbackrest --stanza=main check

It ends with check command end: completed successfully. Take an incremental backup - this adds a backup to the repository and is a normal, non-destructive operation:

sudo -u postgres pgbackrest --stanza=main --type=incr backup

It ends with backup command end: completed successfully. You can take a full or differential backup the same way with --type=full or --type=diff. All pgBackRest operations run as the postgres system user through sudo -u postgres, which authenticates to PostgreSQL by peer authentication, so no password is needed for administration.

pgbackrest check validating the configuration, repository and WAL archiving, then an incremental backup completing successfully on the running instance

Step 6: Inspect the Encrypted Backup Set

pgbackrest info shows the state of the repository - its encryption cipher, the WAL archive range, and every backup with its type, timestamp and size:

sudo -u postgres pgbackrest --stanza=main info

The output reports status: ok, cipher: aes-256-cbc, and the set of full, differential and incremental backups, with each incremental referencing the full it builds on. The repository is encrypted with the per-instance passphrase, so its contents are unreadable without it.

pgbackrest info showing the aes-256-cbc encrypted repository with full, differential and incremental backups and all four scheduled timers enabled

Step 7: The Backup Schedule

The image ships four systemd timers, enabled and ready. First boot starts them; on a running instance they fire on their schedule:

  • pgbackrest-full.timer - a full backup weekly (Sunday 01:00)
  • pgbackrest-diff.timer - a differential backup daily (Monday to Saturday 01:00)
  • pgbackrest-incr.timer - an incremental backup hourly (at :30)
  • pgbackrest-verify.timer - repository verification weekly (Sunday 03:00)

Each timer carries a randomised delay so a fleet of instances does not stampede, and the backup services run at reduced I/O and CPU priority so scheduled backups never starve the database. List them and their next run times:

systemctl list-timers 'pgbackrest-*' --all --no-pager

Adjust retention (repo1-retention-full, repo1-retention-diff) and the schedules in /etc/pgbackrest/pgbackrest.conf and the pgbackrest-*.timer units to match your recovery policy.

Step 8: Restore from the Repository

pgBackRest restores a cluster from the repository. A restore is destructive: it stops PostgreSQL and overwrites the data directory from the backup, so run it deliberately, on a host you intend to recover. The commands below are reference only - do not run them casually on a production instance.

The image also ships a self-test that performs a complete backup, verify and restore round trip against a throwaway probe table, proving the whole chain works end to end on this instance. It stops and restarts PostgreSQL, so it is not part of the routine read-only checks above:

sudo /usr/local/sbin/pgbackrest-selftest.sh

A manual point-in-time restore follows this shape - stop PostgreSQL, restore, then start it again:

sudo systemctl stop postgresql@18-main.service
sudo -u postgres pgbackrest --stanza=main --delta --type=immediate --target-action=promote restore
sudo systemctl start postgresql@18-main.service

--delta restores only the files that differ, which is much faster than a full copy. To recover to a specific point in time, use --type=time --target="YYYY-MM-DD HH:MM:SS+00" instead of --type=immediate. Always rehearse restores on a separate instance before you need them in anger.

Step 9: Remote Access over an SSH Tunnel

PostgreSQL listens on loopback only and the security group opens port 22 only, so the database is not reachable from the network. To connect a local client such as psql, a BI tool or an application, open an SSH tunnel from your workstation that forwards a local port to 127.0.0.1:5432 on the instance:

ssh -i <key-name>.pem -L 5432:127.0.0.1:5432 ubuntu@<public-ip>

With the tunnel open, point your local client at 127.0.0.1:5432, database postgres, user postgres, and the password from the credentials file. This keeps all database traffic inside the encrypted SSH channel. Do not open port 5432 to the internet without TLS in front of it.

Step 10: The Repository Volume

The pgBackRest repository lives on a dedicated EBS volume mounted at /var/lib/pgbackrest, with the repository itself under /var/lib/pgbackrest/repo. Confirm the mount:

df -h /var/lib/pgbackrest

To grow the volume, expand the EBS volume in the AWS console, then grow the filesystem on the instance with sudo resize2fs on the underlying device. Snapshot the volume for an additional off-instance copy of your backups, or use the S3 repository option below to store backups off the instance entirely.

Step 11: Repoint the Repository at a Remote Host or Amazon S3

The same appliance can back up a remote PostgreSQL server or store its repository in Amazon S3, both config-only changes in /etc/pgbackrest/pgbackrest.conf.

To store the repository in S3 instead of the local volume, replace the repo1-path line with an S3 block - a bucket, region and endpoint - and provide credentials through an EC2 instance role or repo1-s3-key settings:

[global]
repo1-type=s3
repo1-s3-bucket=your-backup-bucket
repo1-s3-region=us-east-1
repo1-s3-endpoint=s3.us-east-1.amazonaws.com
repo1-path=/pgbackrest
repo1-cipher-type=aes-256-cbc
repo1-cipher-pass=<your-passphrase>

To back up a remote PostgreSQL host, point the stanza's pg1-path, pg1-host and pg1-host-user at that server and install pgBackRest there too. See the pgBackRest user guide for the full remote and S3 configuration.

A Note on the Encryption Passphrase

The repository encryption passphrase (repo1-cipher-pass in /etc/pgbackrest/pgbackrest.conf) is unique to this instance and is recorded in the credentials file. Rotating it invalidates every existing backup, because pgBackRest cannot decrypt objects written under the previous passphrase. If you change it, create a new stanza or a new repository and take a fresh full backup. Back this passphrase up somewhere safe: without it your backups are unusable.

Support

This image is published and supported by cloudimg. Support covers deployment, pgBackRest and PostgreSQL configuration, backup scheduling and retention design, restore rehearsals and point-in-time recovery, repointing the repository at remote hosts or Amazon S3, EBS volume resizing and snapshot-based backups, and upgrade planning. Contact cloudimg through the support channel listed on the AWS Marketplace listing.

All product and company names are trademarks or registered trademarks of their respective holders. This product is not affiliated with or endorsed by Crunchy Data or the PostgreSQL Global Development Group. Use of these names is nominative, to identify the software.