Skip to content

Databases

Engine Versions Port On
MySQL 8.4.6, 8.0.44 13306 macOS, Windows, Linux
MariaDB 12.3.2, 11.4.12 LTS 13307 macOS only
PostgreSQL 18.6.0, 17.11.0, 16.15.0 15432 macOS, Windows, Linux
Redis 8.8.0 16379 macOS only

MariaDB and Redis are refused by name on Windows and Linux, so a site there has MySQL or PostgreSQL.

Engines start on demand:

Terminal window
rex service start mariadb
rex db versions --set mysql 8.0.44
rex db browse # Adminer

A site picks MySQL, MariaDB or PostgreSQL at create time, and gets its own database. Nothing is shared between sites except the server process. The engine is fixed once the site exists; what switches is each engine’s version series, below.

Each engine keeps a separate data directory per version series. Switching MySQL from 8.4 to 8.0 does not attempt to downgrade a data directory — it starts the 8.0 series with its own directory, and 8.4’s data is still there when you switch back.

That is why switching is safe and why it is not a migration: data does not follow you across. To move data between series, export from one and import into the other.

Terminal window
rex db export myshop.rex # writes to ~/Downloads, prints the path
rex db import myshop.rex dump.sql # OVERWRITES the site's tables

A server that was killed rather than stopped — a reboot that ran out of patience and sent SIGKILL, a hard power-off — leaves its lock file behind with its old process id inside: mysql.sock.lock for MySQL, postmaster.pid for PostgreSQL. After the boot that id usually exists again, as some other program, and both servers ask only whether it exists. PostgreSQL then refuses with “lock file already exists — is another postmaster running?”, mysqld aborts with “Unable to setup unix socket lock file”, and through 0.8.9 the health watchdog respawned each three times, gave up, and every site stayed down until two files were removed by hand.

On macOS and Linux a start now asks the stricter question: is that process id alive and is its command line the server that wrote the file? When it is not, the lock is removed — and MySQL’s socket with it — and the log says so:

mysql: removed a stale lock before starting — …/mysql.sock.lock: pid 2009 is now /usr/bin/rexenv, not the server that wrote it

A live server’s lock is never touched, so a start against a server that really is running still fails the honest way, on the server’s own message.

rex db browse, or the button on a site, opens Adminer 6.1.1 deep-linked straight into that site’s database — already connected, already on the right schema. It is served as an internal vhost through the shared nginx, so it holds no port of its own.

The console takes its palette from rexenv, not from the OS. It is Adminer’s own light/dark switch being set, not a paint job over it. The console renders in its own process off its own stylesheet, so it used to consult the OS while the app sat on its own preference — a light-themed rexenv framing a dark console, which reads as a broken embed.

Adminer is served through rexenv’s web services and reads the site’s database engine, so with either one stopped a site’s Database tab says which — MySQL is stopped, or rexenv’s web services are stopped — and offers Start all, instead of the blank frame it used to show. The WordPress tab does the same when the site’s database is down.

The Databases screen carries an Adminer card under the engine table, on the same screen the console opens from. It states the version being served and offers the one control that changes it, when a signed manifest offers a newer one.

There is no “exists but you cannot have it” gap here, unlike PHP: rexenv downloads Adminer’s own release asset, so a version that exists and a version rexenv can install are the same thing.

Two limits worth knowing before you press it:

  • Major 6 is the ceiling. That is the newest major whose plugin API has been checked against rexenv’s wrapper — measured on 18 August 2026 by binding the wrapper’s exact subclass shape through PHP 8.3.32 against 5.4.2, 5.5.1 and 6.0.1. A ceiling nobody has tested is superstition with a constant name, so raising it means re-running that probe.
  • A build that no longer binds is refused. rexenv’s login gate and frame protections for this console live inside Adminer’s plugin API, so a version that moved the base class would turn them off silently. The downloaded file is run through the bundled PHP in a throwaway directory first, and a refusal there has changed nothing — nothing is written and the docroot is untouched.

Going back is a second press. Once a newer Adminer is chosen, the card offers Back to the version this rexenv ships. It is the same action as the update, pointed the other way — the same download-and-check, the same restage — and the pinned version’s files are still on disk. Until 30 September 2026 the card offered it nowhere: this page said recovery was “a second press”, and there was nothing to press.

Redis is a service rather than a per-site choice. Start it when a project needs it, and point the project at 127.0.0.1:16379.

MySQL on 13306 rather than 3306, and so on, so rexenv never collides with a database you already installed. See Ports.