Skip to content

Commit

Permalink
FEATURE: Add template for PostgreSQL 15
Browse files Browse the repository at this point in the history
The new templates/postgres.15.template.yml file allows bootstrapping
new containers using PostgreSQL version 15, or upgrading an existing
container running on older PostgreSQL versions.

The default postgres template and base image shall be bumped in a
follow-up commit.
  • Loading branch information
mwaniki-wairungu authored and andrewschleifer committed Feb 29, 2024
1 parent 7cc301e commit 0f4e635
Showing 1 changed file with 258 additions and 0 deletions.
258 changes: 258 additions & 0 deletions templates/postgres.15.template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,258 @@
params:
db_synchronous_commit: "off"
db_shared_buffers: "256MB"
db_work_mem: "10MB"
db_default_text_search_config: "pg_catalog.english"
db_name: discourse
db_user: discourse
db_checkpoint_segments: 6
db_logging_collector: off
db_log_min_duration_statement: 100

hooks:
before_code:
- replace:
filename: /etc/service/unicorn/run
from: "# postgres"
to: sv start postgres || exit 1

run:
- exec: DEBIAN_FRONTEND=noninteractive apt-get purge -y postgresql-13 postgresql-client-13 postgresql-contrib-13 postgresql-13-pgvector
- exec: apt-get update && apt-get install -y postgresql-15 postgresql-client-15 postgresql-contrib-15 postgresql-15-pgvector
- exec: locale-gen $LANG && update-locale
- exec: mkdir -p /shared/postgres_run
- exec: chown postgres:postgres /shared/postgres_run
- exec: chmod 775 /shared/postgres_run
- exec: rm -fr /var/run/postgresql
- exec: ln -s /shared/postgres_run /var/run/postgresql
- exec: socat /dev/null UNIX-CONNECT:/shared/postgres_run/.s.PGSQL.5432 || exit 0 && echo postgres already running stop container ; exit 1
- exec: rm -fr /shared/postgres_run/.s*
- exec: rm -fr /shared/postgres_run/*.pid
- exec: mkdir -p /shared/postgres_run/15-main.pg_stat_tmp
- exec: chown postgres:postgres /shared/postgres_run/15-main.pg_stat_tmp
- file:
path: /etc/service/postgres/run
chmod: "+x"
contents: |
#!/bin/sh
exec 2>&1
HOME=/var/lib/postgresql USER=postgres exec thpoff chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/15/bin/postmaster -D /etc/postgresql/15/main
- file:
path: /etc/service/postgres/log/run
chmod: "+x"
contents: |
#!/bin/sh
mkdir -p /var/log/postgres
exec svlogd /var/log/postgres
- file:
path: /etc/runit/3.d/99-postgres
chmod: "+x"
contents: |
#!/bin/bash
sv stop postgres
- file:
path: /root/upgrade_postgres
chmod: "+x"
contents: |
#!/bin/bash
PG_MAJOR_OLD=`cat /shared/postgres_data/PG_VERSION`
if [ ! "15" = "$PG_MAJOR_OLD" ]; then
echo Upgrading PostgreSQL from version ${PG_MAJOR_OLD} to 15
free_disk=$(df -P -B1 /shared | tail -n 1 | awk '{print $4}')
required=$(($(du -sb /shared/postgres_data | awk '{print $1}') * 2))
if [ "$free_disk" -lt "$required" ]; then
echo "WARNING: Upgrading PostgreSQL would require an additional $(numfmt --to=si $(($required - $free_disk))) of disk space"
echo "Please free up some space, or expand your disk, before continuing."
echo ''
echo 'To avoid upgrading change "templates/postgres.15.template.yml" TO "templates/postgres.template.yml" in containers/app.yml'
exit 1
fi
if [ -d /shared/postgres_data_old ]; then
mv /shared/postgres_data_old /shared/postgres_data_older
fi
rm -fr /shared/postgres_data_new
install -d -m 0755 -o postgres -g postgres /shared/postgres_data_new && sudo -u postgres /usr/lib/postgresql/15/bin/initdb -D /shared/postgres_data_new || exit 0
apt-get update
apt-get install -y postgresql-${PG_MAJOR_OLD}
chown -R postgres:postgres /var/lib/postgresql/15
/etc/init.d/postgresql stop
rm -fr /shared/postgres_data/postmaster.pid
cd ~postgres
cp -pr /etc/postgresql/${PG_MAJOR_OLD}/main/* /shared/postgres_data
echo >> /shared/postgres_data/postgresql.conf
echo "data_directory = '/shared/postgres_data'" >> /shared/postgres_data/postgresql.conf
SUCCESS=true
sudo -u postgres /usr/lib/postgresql/15/bin/pg_upgrade -d /shared/postgres_data -D /shared/postgres_data_new -b /usr/lib/postgresql/${PG_MAJOR_OLD}/bin -B /usr/lib/postgresql/15/bin || SUCCESS=false
if [[ "$SUCCESS" == 'false' ]]; then
echo -------------------------------------------------------------------------------------
echo UPGRADE OF POSTGRES FAILED
echo
echo You can run "./launcher start app" to restart your app in the meanwhile
echo
exit 1
fi
mv /shared/postgres_data /shared/postgres_data_old
mv /shared/postgres_data_new /shared/postgres_data
echo -------------------------------------------------------------------------------------
echo UPGRADE OF POSTGRES COMPLETE
echo
echo Old ${PG_MAJOR_OLD} database is stored at /shared/postgres_data_old
echo
echo To complete the upgrade, rebuild again using:
echo
echo ./launcher rebuild app
echo -------------------------------------------------------------------------------------
# Magic exit status to denote no failure
exit 77
fi
- exec:
cmd:
- chown -R root /var/lib/postgresql/15/main
- "[ ! -e /shared/postgres_data ] && install -d -m 0755 -o postgres -g postgres /shared/postgres_data && sudo -E -u postgres /usr/lib/postgresql/15/bin/initdb -D /shared/postgres_data || exit 0"
- chown -R postgres:postgres /shared/postgres_data
- chown -R postgres:postgres /var/run/postgresql

- exec: /root/upgrade_postgres
- exec: rm /root/upgrade_postgres

- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: "data_directory = '/var/lib/postgresql/15/main'"
to: "data_directory = '/shared/postgres_data'"

# listen on all interfaces
- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?listen_addresses *=.*/
to: "listen_addresses = '*'"

# sync commit off is faster and less spiky, also marginally less safe
- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?synchronous_commit *=.*/
to: "synchronous_commit = $db_synchronous_commit"

# default is 128MB which is way too small
- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?shared_buffers *=.*/
to: "shared_buffers = $db_shared_buffers"

# default is 1MB which is too small
- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?work_mem *=.*/
to: "work_mem = $db_work_mem"

# allow for other
- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?default_text_search_config *=.*/
to: "default_text_search_config = '$db_default_text_search_config'"

# Necessary to enable backups
- exec:
cmd:
- install -d -m 0755 -o postgres -g postgres /shared/postgres_backup

- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?checkpoint_segments *=.*/
to: "checkpoint_segments = $db_checkpoint_segments"

- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?logging_collector *=.*/
to: "logging_collector = $db_logging_collector"

- replace:
filename: "/etc/postgresql/15/main/postgresql.conf"
from: /#?log_min_duration_statement *=.*/
to: "log_min_duration_statement = $db_log_min_duration_statement"

- replace:
filename: "/etc/postgresql/15/main/pg_hba.conf"
from: /^#local +replication +postgres +peer$/
to: "local replication postgres peer"

# allow all to connect in with md5/scram auth
- replace:
filename: "/etc/postgresql/15/main/pg_hba.conf"
from: /^host.*all.*all.*127.*$/
to: "host all all 0.0.0.0/0 md5"

# allow all to connect in with md5/scram auth (IPv6)
- replace:
filename: "/etc/postgresql/15/main/pg_hba.conf"
from: /^host.*all.*all.*::1\/128.*$/
to: "host all all ::/0 md5"

# allow replication to connect in with md5/scram auth
- replace:
filename: "/etc/postgresql/15/main/pg_hba.conf"
from: /^host.*replication.*all.*127.*$/
to: "host replication all 0.0.0.0/0 md5"

# allow replication to connect in with md5/scram auth (IPv6)
- replace:
filename: "/etc/postgresql/15/main/pg_hba.conf"
from: /^host.*replication.*all.*::1\/128.*$/
to: "host replication all ::/0 md5"

- exec:
background: true
# use fast shutdown for pg
stop_signal: INT
cmd: HOME=/var/lib/postgresql USER=postgres exec chpst -u postgres:postgres:ssl-cert -U postgres:postgres:ssl-cert /usr/lib/postgresql/15/bin/postmaster -D /etc/postgresql/15/main

# give db a few secs to start up
- exec: "sleep 5"

- exec: su postgres -c 'createdb $db_name' || true
- exec: su postgres -c 'psql $db_name -c "create user $db_user;"' || true
- exec: su postgres -c 'psql $db_name -c "grant all privileges on database $db_name to $db_user;"' || true
- exec: su postgres -c 'psql $db_name -c "alter schema public owner to $db_user;"'
- exec: su postgres -c 'psql template1 -c "create extension if not exists hstore;"'
- exec: su postgres -c 'psql template1 -c "create extension if not exists pg_trgm;"'
- exec: su postgres -c 'psql template1 -c "create extension if not exists vector;"'
- exec: su postgres -c 'psql $db_name -c "create extension if not exists hstore;"'
- exec: su postgres -c 'psql $db_name -c "create extension if not exists pg_trgm;"'
- exec: su postgres -c 'psql $db_name -c "create extension if not exists vector;"'
- exec:
stdin: |
update pg_database set encoding = pg_char_to_encoding('UTF8') where datname = '$db_name' AND encoding = pg_char_to_encoding('SQL_ASCII');
cmd: sudo -u postgres psql $db_name
raise_on_fail: false

- file:
path: /var/lib/postgresql/take-database-backup
chown: postgres:postgres
chmod: "+x"
contents: |
#!/bin/bash
ID=db-$(date +%F_%T)
FILENAME=/shared/postgres_backup/$ID.tar.gz
pg_basebackup --format=tar --pgdata=- --wal-method=fetch --gzip --label=$ID > $FILENAME
echo $FILENAME
- file:
path: /var/spool/cron/crontabs/postgres
contents: |
# m h dom mon dow command
#MAILTO=?
#0 */4 * * * /var/lib/postgresql/take-database-backup
- exec:
hook: postgres
cmd: "echo postgres installed!"

0 comments on commit 0f4e635

Please sign in to comment.