External access
External access to managed MySQL on Bahriya: TLS-only connections on an allocated port, IP allowlists, per-region hostnames and custom hostnames.
By default a MySQL instance is reachable only by containers in its own project. You can additionally expose it at the platform edge — for an application hosted elsewhere, a reporting tool, a data pipeline or a migration.
External access is TLS-only and allowlisted — always
An externally exposed instance must have both:
- TLS on, and
- a non-empty IP allowlist (CIDR notation, e.g.
198.51.100.0/24, 203.0.113.42/32).
These are enforced by the platform — a configuration missing either is rejected. There is no way to put an unencrypted or world-reachable database on the internet.
Hostname and port
Every exposed instance gets a hostname per region:
<default-hostname>.<region>.mysql.on.bahriya.appand a port allocated to the instance when you first enable external access. The port is the same in every region, stays with the instance while external access is on, and is shown on the instance's detail page, in reis mysql:show and in Terraform's externalport attribute. You do not choose it.
Unlike HTTP, the MySQL protocol does not tell the server which hostname a client asked for, so the port — not the hostname — is what routes your connection to your instance. The hostname is what your client verifies the TLS certificate against.
Each region is an independent copy with its own data, reachable only at its own hostname.
mysql --host orders.helsinki-1.mysql.on.bahriya.app --port <externalport> \
--user orders-app -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=orders-ca.pem ordersTurning external access off releases the port; turning it on again may allocate a different one.
Custom hostnames
You can attach hostnames of your own — db.example.com — as convenience names. Point a CNAME at the generated hostname of the region that name should reach:
db.example.com. CNAME orders.helsinki-1.mysql.on.bahriya.app.Clients still connect on the allocated port. For a multi-region instance, create one custom name per region and point each at its region's hostname.
TLS certificates: managed or bring your own
Platform managed (recommended). With TLS on and no bundle selected, the platform issues a certificate bundle, stores it in your organisation's vault as <handle>-tls, and keeps it valid for every name the instance answers to — generated hostnames and custom hostnames alike. Add a region or a hostname and the certificate is reissued to cover it. It is also renewed 30 days before it expires; you choose its lifetime (1, 3, 5 or 10 years). Every reissue is signed by the same CA, so download the CA certificate once from the bundle in your vault and your clients keep verifying the server. See Getting the CA certificate.
Bring your own. To serve your own certificate, create a TLS bundle in your vault and attach it to the instance's project — it then becomes selectable on the instance. A supplied bundle must cover every hostname the instance answers to; the API rejects a bundle with missing names and tells you which ones.
Clients should connect with ssl-mode=VERIFY_IDENTITY (or your driver's equivalent) and pass the bundle's CA certificate with --ssl-ca, so they check both the certificate and the hostname.
Checklist for an external client
- Host: the regional hostname, or your CNAME.
- Port: the instance's allocated port.
- TLS: required; verify identity, passing the CA certificate from the instance's
<handle>-tlsbundle with--ssl-ca. - User and password: the database user, revealed from the console or with
reis mysql:credentials. - Source IP: within the instance's allowlist.
Containers in the same project should keep using the internal endpoint — it is faster and does not depend on the exposure settings. For occasional browser access, see phpMyAdmin.