Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Physical Address
304 North Cardinal St.
Dorchester Center, MA 02124
Migrating Mattermost from MySQL to PostgreSQL can significantly improve performance, stability, and scalability. PostgreSQL is the recommended database backend for modern Mattermost deployments—especially for production environments and large teams.
In this guide, I’ll walk you step-by-step through installing PostgreSQL in a homelab, setting up the master database, using pgloader for migration, and completing the post-migration cleanup.
This is the exact process I used, including the commands.
If your Mattermost is running on MySQL today and you want long-term stability, PostgreSQL is the right choice.
Use Docker to quickly spin up a PostgreSQL master instance.
docker run -d \
--name postgres-master \
--restart unless-stopped \
-e TZ=Asia/Kolkata \
-e POSTGRES_PASSWORD={DB_PASSWORD} \
-v /mnt/docker/volume/postgres:/var/lib/postgresql \
-p 5432:5432 \
postgres:{POSTGRES_VERSION}15, 16, etc./mnt/docker/volume/postgrespgloader is the easiest and most reliable way to migrate MySQL → PostgreSQL.
You can install pgloader directly from apt.postgresql.org and from official debian repositories, see packages.debian.org/pgloader.
Run the below command to compile the latest code, sudo apt install pgloader will install the old version of it.
sudo apt update
sudo apt install build-essential sbcl libsqlite3-dev gawk curl make freetds-dev libzip-dev git
git clone https://github.com/dimitri/pgloader.git
cd pgloader
make
sudo make installThe Postgres community repository for RPM packages is yum.postgresql.org and does include binary packages for pgloader.
pgloader copies schema, tables, indexes, and data automatically.
If you installed pgloader by compiling from source using make, the binary will be available under your build directory—typically something like:
{CURRENT_WORKING_DIRECTORY}/build/bin/pgloaderUse the following migration command:
{CURRENT_WORKING_DIRECTORY}/build/bin/pgloader \
'mysql://{MYSQL_USER}:{MYSQL_PASSWORD}@{MYSQL_HOST}:{MYSQL_PORT}/{MYSQL_DATABASE}' \
'postgresql://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:5432/{POSTGRES_DATABASE}'
make.3306mattermost DB in PostgreSQL before running the command.This usually finishes in just a few minutes, depending on dataset size.
After migration, you must fix a few Mattermost-specific schema settings.
✔ Fix incorrect migration entry
UPDATE {YOUR_DB_NAME}.db_migrations
SET name = 'add_createat_to_teamembers'
WHERE version = 92;✔ Cleanup: Drop the default ‘public’ schema
DROP SCHEMA IF EXISTS public CASCADE;✔ Rename the Mattermost schema to public
ALTER SCHEMA {YOUR_MYSQL_DB_NAME} RENAME TO public;✔ Set correct PostgreSQL search path
SELECT pg_catalog.set_config('search_path', '"$user", public', false);
ALTER USER postgres SET SEARCH_PATH TO 'public';⚠️ If renaming fails
Use this alternative:
ALTER SCHEMA {YOUR_MYSQL_DB_NAME} RENAME TO public;Mattermost uses a PostgreSQL connection string like this:
postgres://{DB_USER}:{DP_PASSWORD}@{DP_HOST}:5432/{YOUR_MATTERMOST_DB}?sslmode=disable&connect_timeout=10config.json under SqlSettings.DataSource, orMM_SQLSETTINGS_DATASOURCE="postgres://{DB_USER}:{DB_PASSWORD}@{DB_HOST}:5432/{POSTGRES_DATABASE}?sslmode=disable&connect_timeout=10"Then restart Mattermost to apply the new configuration.
After Mattermost starts:
Check logs if needed:
docker logs mattermostIf the UI loads and messages are visible, the migration is successful.
Migrating Mattermost from MySQL to PostgreSQL is straightforward when using pgloader and a few schema adjustments. PostgreSQL offers better performance, improved reliability, and long-term support—making it the ideal choice for production Mattermost systems.