Run MySQL or MariaDB

Last updated

The same shape as Postgres, and the same context applies: read Databases first, because the port will be publicly reachable.

Create the database app

Use Existing Image:

  • Image: mysql:8 or mariadb:11 — pin a version rather than using latest
  • Volume: /var/lib/mysql
  • Port: container 3306, protocol TCP
  • Environment variables:
    • MYSQL_ROOT_PASSWORD — required, and it should be long and random
    • MYSQL_DATABASE — optional, created on first start
    • MYSQL_USER and MYSQL_PASSWORD — optional, creates a non-root user

Create an application user rather than connecting as root. It costs one extra variable and limits what a leaked credential can do.

Without the volume, your data is discarded whenever the container is recreated — which includes any configuration change, not just deploys.

Connect your application

A TCP binding is published on a generated high port, not 3306. Take the host and port from the database app's Ports tab, then set a connection string on your application:

DATABASE_URL=mysql://USER:PASSWORD@HOST:PORT/DBNAME

Create the database app first, read its address, then configure the app that uses it.

Because it's public

  • Long random passwords, and don't reuse the root one for your application.
  • Remove the port binding when nothing outside needs it.
  • Use TLS if your client supports it.
  • Keep the connection pool small — a handful of connections is plenty for a small app.

Backups

mysqldump -h HOST -P PORT -u USER -p DBNAME > /data/backup.sql

Write to a volume, download from the Files tab or ship off-platform, and prune old dumps — volume size counts toward the account disk limit that stops all your apps when exceeded.

Migrations

Run them deliberately from the shell, not from your app's start command — startup code runs on every restart, including every iteration of a crash loop.