PostgreSQL 18 update for self-hosters

We recommend testing the process since this isn’t something we support, but likely all you’ll need to do is tell it to upgrade and it’ll be fine.

i just did the PostgreSQL 18 for a standard install and a dual container without any issues at all. thanks again @chrisr and team for the easy instructions.

for a dual container configuration behind Cloudflare CDN with R2 uploads/backup buckets, the steps i used were as follows:

Step 1: disk cleanup

# nuke all unused docker data
docker system prune -a -f
# clear old logs and apt cache
journalctl --vacuum-time=2d
apt-get clean
apt-get autoremove -y
# check database size
du -sh /var/discourse/shared/data/postgres_data
# check new available free space
df -h -x tmpfs -x devtmpfs

Step 2: maintenance & backup

  1. edit a Cloudflare maintenance page to say 15-20 minutes system maintenance update (may not take this long, but good to be safe!) and set a reload timer of 30 seconds or so. turn on a Cloudflare worker route to show the maintenance page.

  1. trigger a backup via command line:
cd /var/discourse
./launcher enter web_only
discourse backup
exit
  1. log into Cloudflare R2 dashboard and check the backup folder to confirm the backup file was successfully uploaded

Step 3: safe shutdown

  1. stop the web container first to kill any active connections, then stop the database container:
cd /var/discourse
./launcher stop web_only
./launcher stop data
  1. verify that PostgreSQL shut down properly:
tail -n 20 shared/data/log/var-log/postgres/current

Step 4: upgrade rebuilds

run the following commands in this order:

./launcher rebuild data # dumps, migrate and restore postgresql 18
./launcher rebuild data # rebuilds database container
./launcher rebuild web_only # rebuilds web app

Step 5: optimization & cleanup

  1. generate the missing pg18 table stats, otherwise the forum will be slower than normal:
docker exec -u postgres data /usr/lib/postgresql/18/bin/vacuumdb -d discourse --analyze-in-stages
  1. test the forum to ensure everything is working - maintenance page should not be loading now if you have a reload timer set on it.
  2. remove the Cloudflare worker route to the maintenance page (we don’t want to hit the 100,000 daily limit!)
  3. delete the old pg18 data to reclaim that disk space:
rm -fr /var/discourse/shared/data/postgres_data_old/

done! :partying_face: :clinking_beer_mugs:

3 Likes