Moving from PostgreSQL to MariaDB
Older Agora versions kept their data in PostgreSQL, the current one in MariaDB: the data is taken over at the first update and your old database stays intact.
Updated on Oct 8, 2026, 6:50 p.m.
On this page
- Before you start
- Steps
- Docker with install.sh
- Panel (egg) or Node.js server
- Docker with a hand-written compose file
- External database (advanced option)
- You know it worked when…
- If it does not work
- Going further
- Finding the duplicate values
- What happens during the conversion
- How long it takes
- Going back
- What is kept, and for how long
- When to delete the old database
- What changes for you after the conversion
In short. Up to version 0.2.0, Agora kept its Hub's data (members, forum, applications, settings, license) in a PostgreSQL database. Later versions use MariaDB. If you have an existing installation, the data is taken over during the first update to the MariaDB version: Agora reads the old database without changing it, copies everything into the new one, checks the copy, then starts. Your old database stays intact and, if the new version does not start, Agora puts the previous version back on it by itself. On Docker there is one thing to do first: run the installation command again. On a panel (egg) or a Node.js server, you update as usual.
Before you start #
- You are concerned if your installation dates from a version that used PostgreSQL. A new installation starts directly on MariaDB: this page is not about you, go to The two Agora databases.
- Make an Agora backup first, as a habit: Administration → Agora → Backups → Download a dump now, then keep the file off the server. That
.sqltaken on the old version cannot be restored on MariaDB (the format is not the same): it is a record, not a plan B. The real plan B is the old database, which the conversion does not touch (see below). - Plan for a short outage: the site restarts during the update. Pick a quiet moment.
- Keep some disk space free: the old database stays in place and the new one is added next to it.
- The words (database, migration, dump) are in the glossary.
Steps #
Docker with install.sh #
Run the installation command again, as
root(it keeps your key, your.envand your volumes):curl -fsSL https://agorapanel.com/install.sh | shThe script prepares the move and says so:
Passage à MariaDB préparé : /opt/agora/.env réécrit (l'ancien est gardé dans /opt/agora/.env.avant-mariadb). Ton site reste sur PostgreSQL jusqu'à la mise à jour vers la version MariaDB…("Move to MariaDB prepared: … your site stays on PostgreSQL until the update to the MariaDB version"). Concretely, it adds anagora-mariadbcontainer (new volumeagora_mariadb), keeps your oldagora-dbcontainer and itsagora_dbvolume, and writes the old database's address intoAGORA_CONVERT_FROM. If the launcher (boot.mjs) changed, it restarts Agora (Amorçage mis à jour : redémarrage d'Agora…). Your site keeps running on the old version and the old database.Update Agora from Administration → Agora (see Update Agora): this is when the data is copied.
Watch the console (
docker logs -f agora) during the update: see "You know it worked when…".Do not cut the server during the copy. If it happens anyway, nothing is lost: see "If it does not work".
Panel (egg) or Node.js server #
- Start the update from Administration → Agora (see Update Agora). The panel or server keeps its embedded PostgreSQL database (the
.agora/pgfolder); Agora copies it into its new embedded MariaDB database. - First pass with an old launcher. If your
boot.mjs(oragora.mjson a Node.js server) predates MariaDB, the update stops once while replacing it itself (signature checked): the console sayscette version d'Agora tourne sur MariaDB : ton amorçage (boot.mjs) était trop ancien pour copier les données, il vient d'être mis à jour… Redémarre le serveur, puis relance la mise à jour("this Agora version runs on MariaDB: your launcher was too old to copy the data and has just been updated… Restart the server, then run the update again"). Do it: restart, then run the update again. Nothing was changed in the meantime. - Watch the console during the copy: see "You know it worked when…".
Docker with a hand-written compose file #
The new compose file starts MariaDB in a new volume (mariadb_data). The old PostgreSQL volume (db_data) is neither read nor erased, except to take the data over, through a temporary service of the legacy profile.
Replace your compose file with the new one, and in
.envreplacePOSTGRES_PASSWORDwith a MariaDB password:MARIADB_ROOT_PASSWORD(long, letters and digits only).Add to
.envthe old PostgreSQL password and the address of the old database:POSTGRES_PASSWORD=<old PostgreSQL password> AGORA_CONVERT_FROM=postgresql://agora:<old PostgreSQL password>@db-pg:5432/agoraStart the old database as well as the new one, then Agora:
cd /opt/agora && docker compose --profile legacy up -dFollow the log:
docker compose logs -f agora. The conversion runs once, on the first start.
External database (advanced option) #
If you had brought your own PostgreSQL database through DATABASE_URL:
- Create an empty MariaDB or MySQL 8 database, reserved for Agora, in
utf8mb4, and its user. - Replace
DATABASE_URLwith its address:mysql://user:password@host:3306/database. - Add
AGORA_CONVERT_FROMwith the old PostgreSQL address (postgresql://…), then restart or run the update: the takeover happens as above. The old database is only read.
You know it worked when… #
- The console shows, in this order:
✓ schéma à jour,reprise des données de l'ancienne base PostgreSQL (elle n'est pas modifiée)…, the list of copied tables,vérification…,reprise terminée : 59 tables, … lignes, … membre(s) — l'ancienne base est intacte., then✓ données reprises …and finally✓ Agora … répond : mise à jour confirmée(the console is in French). - Your Hub's
/api/healthaddress answers"ok": trueand"db": "ok". - In Administration → Members, you find all your members, with the same number of administrators as before; the forum, applications and your settings are there.
- Your license is active without doing anything: the installation keeps the same identity for the license server, no seat is taken (see Free a license seat only if the "seats taken" message shows up anyway).
If it does not work #
In every case below, your old database was not modified, the new database is emptied before starting again, and the previous version stays (or comes back) in service: the console says mise à jour impossible : … then la version … reste en place.
| What you see | Cause | What to do |
|---|---|---|
la base est encore PostgreSQL, mais cette version d'Agora tourne sur MariaDB et ton amorçage (boot.mjs) est trop ancien pour copier les données (fichier monté en lecture seule) (the message also has an English copy [EN] …) | Docker: the boot.mjs file is mounted read-only, Agora cannot replace it itself (or it is write-protected on a panel) | Docker: run the installation command again as root (step 1 of the "Docker with install.sh" section). Panel or Node.js: download boot.mjs and boot.mjs.sig (or agora.mjs and agora.mjs.sig) from https://agorapanel.com/ into the server folder, replacing the old ones, then restart. Then run the update again |
mise à jour impossible : les migrations ont échoué right after Agora 0.3.0-beta.1 installé, then la version 0.2.0-beta.42 reste en place | A very old launcher (panel installed before early October 2026) cannot replace itself (MariaDB versions published after 0.3.0-beta.1 replace it for you and tell you so): it tries the MariaDB migrations on the old PostgreSQL database, which refuses them. Nothing was changed | Download boot.mjs and boot.mjs.sig from https://agorapanel.com/ into the server folder (they replace the old ones), restart, then run the update again |
cette version d'Agora tourne sur MariaDB : ton amorçage (boot.mjs) était trop ancien… il vient d'être mis à jour | Normal, once: Agora has just replaced the launcher itself | Restart the server, then run the update again |
des valeurs sont différentes dans l'ancienne base mais IDENTIQUES pour MariaDB, qui ignore la casse, les accents et les espaces de fin : User(email) : 1 groupe(s) en double, par exemple « D***@exemple.test / d***@exemple.test » (or une clé unique est en double dans la nouvelle base); an English copy [EN] Some values differ in the old database but are IDENTICAL for MariaDB… follows | Two rows of the old database differ only by a capital letter, an accent or a trailing space (for example two members with the same email apart from case). PostgreSQL sees them as different, MariaDB does not: the copy would be refused | Nothing was copied. Fix the old database so that each value exists only once, then run the update again. The message gives the table and the column and masks the values: see "Finding the duplicate values" below. Then change one of the two values (a username or an email, from Administration → Members) or delete the useless duplicate |
l'ancienne base PostgreSQL ne répond pas (…) : vérifie qu'elle tourne et que l'adresse AGORA_CONVERT_FROM est la bonne | The old database is not running, or the AGORA_CONVERT_FROM address or password is wrong | Docker: cd /opt/agora && docker compose up -d (and --profile legacy with a hand-written compose), then check the address in .env. External database: check the address and that Agora's machine can reach it |
la copie de la table … a échoué | A write into MariaDB failed (disk space, memory) | Free some space (old backups) or enlarge the disk, then run the update again |
la vérification a échoué : … | The copy is not identical to the original (row count, a row's fingerprint) | Do not force anything: open a ticket with those lines (see Open a support ticket). The old database stays your reference |
An older .sql is refused on restore | It is a PostgreSQL backup, which MariaDB cannot read | Normal: see Backups and restore |
| The server was cut (Stop, Kill, power cut) during the copy | The copy was half done | Nothing to do: at the next start, Agora recognises the interrupted copy and redoes it from the beginning |
Going further #
Finding the duplicate values #
The refusal message names the table and the column (for example User(email)) and only shows the beginning of the values. To find the pair in the old database (replace User and email with what the message says):
docker exec agora-db psql -U agora -d agora -c 'SELECT lower(email), count(*) FROM "User" GROUP BY 1 HAVING count(*) > 1;'Without Docker, run the same query in your PostgreSQL. Fix one of the two values, then run the update again: until that is done, nothing is copied.
What happens during the conversion #
- Agora first checks, before copying anything, that no value hides another one for MariaDB (the case, accent or trailing-space duplicates described above).
- It opens the old database read-only and freezes it at a given instant: even if someone were still writing, it copies a consistent state.
- It copies the tables in the right order (the links between tables are respected).
- It checks the copy: row count of each table, fingerprint of each row, no orphan row, same number of members. It also carries over the database's identity (
db_instance_id), which keeps the license fingerprint. - It leaves a mark in the new database so as to never redo the conversion on the next start, then launches Agora.
If a step fails, Agora empties the new database, puts the previous version back on the old database and says so; the old one was never written to.
How long it takes #
Measured on the test bench: a few seconds for an ordinary installation (59 tables, a few hundred rows). The duration follows the number of messages and rows; we have not measured a very large forum, so allow more time and keep the console open. The site is unavailable during the update. Do not cut the server: if you do, the copy starts over from zero, losing nothing.
Going back #
- During the update: it is automatic. If the copy fails, or if the new version does not start, Agora puts the previous version back on its old database by itself (message
repli vers … : la version … n'a pas démarré). What was written before the update is intact there, and if you then run the update again, the copy is redone from scratch. - Once the new version is confirmed (
mise à jour confirmée), there is no automatic way back: what you write afterwards exists only in MariaDB, it is not copied back into the old database. If you really must go back, open a ticket (Open a support ticket): the old database and your old.envare kept for that.
What is kept, and for how long #
Agora never deletes the old database by itself: it stays until you delete it.
- Docker with
install.sh: theagora-dbcontainer and itsagora_dbvolume (the old database), and the/opt/agora/.env.avant-mariadbfile (your old.env, with the old password: readable by root only). - Docker with a hand-written compose: the
db_datavolume, and thePOSTGRES_PASSWORDandAGORA_CONVERT_FROMlines of your.env. - Panel or Node.js: the
.agora/pgfolder (the old database) and.agora/pg-portable(the PostgreSQL program). Do not delete.agora/pg-converted.json: it is the "already converted" mark. - Pre-update backups (
pre-update-…): Agora keeps the last five.
When to delete the old database #
Once you have lived a few days on MariaDB without trouble and made an Agora backup of the new database (Administration → Agora → Backups, downloaded off the server). Then:
- Docker with
install.sh: remove theAGORA_CONVERT_FROMandPOSTGRES_PASSWORDlines from/opt/agora/.env, run the installation command again (it rewrites the compose file without the old database), thencd /opt/agora && docker compose up -d --remove-orphans. When you are sure, delete the volume:docker volume lsgives its full name (it ends inagora_db), thendocker volume rm <name>. Also delete.env.avant-mariadb. - Docker with a hand-written compose:
docker compose --profile legacy down, remove theAGORA_CONVERT_FROMandPOSTGRES_PASSWORDlines from.env, then delete thedb_datavolume (docker volume lsgives you its full name). - Panel or Node.js: delete the
.agora/pgand.agora/pg-portablefolders to free the space.
What changes for you after the conversion #
- The forum search finds whole words or word beginnings ("dealer" finds "dealership"), ignoring accents and capitals. It no longer reduces words to their root: if you type the full plural "cars", it will not find "car".
- Usernames are compared without accents or capitals: "Élise" and "Elise" are the same name. This avoids look-alike usernames.
- Agora's backups are made without any external program and are in a different format: your old PostgreSQL
.sqlfiles can no longer be restored. See Backups and restore. - The license does not move: same identity, same seat.
- Nothing else: the Hub, MDT, live map, dealership and the rest work as before. Your game server's database is never touched by this conversion.
Was this article helpful?
Related articles
- The two Agora databases: the Hub's and the game'sYour installation uses two databases: the Hub's (MariaDB, provided and managed by Agora) and your game server's (MySQL or MariaDB, which you already have).
- Backups and restoreBack up Agora's database from the admin area, download it off the server and restore it. A panel's file copy is not a backup.
- Troubleshoot the Hub's built-in databaseMemory too small, disk full, "la base intégrée n'a pas démarré": the console messages when the Hub's built-in database has a problem, and each fix.
- One-click updates (and the beta channel)Administration → Agora backs up the database, downloads and verifies the new version, migrates, restarts, and rolls back on its own if it does not start.
- Failed update and rolling backA failing update changes nothing, or returns to the previous version on its own; to undo the database too, restore the pre-update backup.
- Install with Docker (install.sh)A single command installs Agora and its MariaDB database on a Linux machine with Docker: you have no database to prepare.
- Environment variablesWhere and how to change Agora's startup settings depending on your installation route (Docker, panel, Node.js server), and the list of the ones that matter.
- Move Agora to another machineBack up the database, copy the files and the session secret, reinstall on the new machine (Docker, panel or Node.js), restore, then take over the license seat.
- Free a license seatA key matches one installation; after a reinstall or a move, the old installation keeps the seat until you free it.