Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FEATURE: Add template for PostgreSQL 15 #772

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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!"
Loading