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
- 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.
- trigger a backup via command line:
cd /var/discourse
./launcher enter web_only
discourse backup
exit
- log into Cloudflare R2 dashboard and check the backup folder to confirm the backup file was successfully uploaded
Step 3: safe shutdown
- 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
- 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
- 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
- test the forum to ensure everything is working - maintenance page should not be loading now if you have a reload timer set on it.
- remove the Cloudflare worker route to the maintenance page (we don’t want to hit the 100,000 daily limit!)
- delete the old pg18 data to reclaim that disk space:
rm -fr /var/discourse/shared/data/postgres_data_old/
done!
![]()
