Product
External Databases

External Databases

By default, every environment gets a PostgreSQL container deployed on its own server and fully managed by OEC.sh. If you already run PostgreSQL elsewhere — AWS RDS or Aurora, a managed cluster from DigitalOcean, Vultr, Hetzner, Azure, or Google Cloud SQL, or your own self-hosted instance — you can point an environment at it instead.

External databases require a Pro plan or above and the org.external_database.manage permission (Owner or Admin).


Step 1: Add a Connection

  1. Go to Settings > Database Connections
  2. Click Add Connection
  3. Fill in:
    • Name — a label to recognize this cluster by
    • Provider — AWS RDS, AWS Aurora, DigitalOcean Managed, Vultr Managed, Hetzner Managed, Azure Database, GCP Cloud SQL, Self-hosted, or Other (locked once the connection is created)
    • Host and Port (default 5432)
    • SSL Mode — Require (recommended), Verify CA, Verify Full, or Disable
    • Custom CA Certificate — only needed for Verify CA / Verify Full, paste your cluster's CA cert in PEM format
    • Admin Username and Admin Password — used once to create the environment's database, its dedicated user, and required extensions. OEC.sh never uses these credentials from your environment's Odoo container.
    • Replica Host / Port (optional) — any PostgreSQL read replica: an Aurora reader endpoint, an RDS or managed-provider replica, or your own streaming standby. See Read replicas below.
  4. Click Add Connection. A connection test runs automatically and shows a health badge (Healthy, Unreachable, Auth Failed, Invalid Pooling, or Needs server test). The test runs from your default test server if you've set one, otherwise from the servers of the environments that use the connection, otherwise from the platform.
⚠️

If your endpoint is a PgBouncer instance running in transaction-pooling mode, the test reports Invalid Pooling. Odoo requires session-pooling or a direct connection — point the host at the real PostgreSQL port (usually 5432) instead.

You can re-run the test anytime from the connection list, and edit or delete a connection later. A connection that's in use by one or more environments can't be deleted until those environments are moved off it.

Testing from the platform or from your server

Each connection has two test buttons:

  • Test from platform checks the database from OEC.sh. This only works when the database has a public address.
  • Test from server checks it from one of your own servers. Pick the server, and optionally tick Use this server for future tests to make it the connection's default test server. If several of your servers run environments that use the database, Test on all environment servers checks it from each of them and shows one result per server; the badge shows the worst result.

Only your own servers in the organization can run a test. Shared servers and demo servers are never offered.


Step 2: Use It on an Environment

When creating or editing an environment, the Database Provider section offers two options:

  • Use platform-managed PostgreSQL (recommended) — the default; a container on your server, fully managed by OEC.sh
  • Use your own database — pick a connection from Step 1, then set a Database Name (lowercase letters, digits, underscores, or hyphens, 1–63 characters; leave blank to auto-generate one). The list shows healthy connections, plus private ones marked checked at deploy (see Private Networks).
⚠️

Database provider can't be changed after the environment is created. Choose carefully at creation time.


Private Networks

If your database is only reachable on a private network (a private subnet, a VPC or private network between your servers, or a database that isn't exposed to the public internet at all), it's supported as long as the environment runs on one of your own servers that can reach it. You never need to open your database to the public internet.

When the environment runs on your own server, everything that talks to the database runs on that server:

  • the connection re-test and database setup at deploy;
  • the check for an already-initialized database on redeploy;
  • backups;
  • restores and clones, including dropping and re-creating the database before the data is loaded.

The database password and CA certificate are written to your server in files only root can read, and removed after each operation.

What to expect:

  • Test from platform on a private address shows Needs server test. That isn't a failure. Use Test from server to check it, or pick it for an environment anyway: the deploy checks it from the environment's server and stops if the server can't reach it.
  • If an environment that uses a private database runs on a shared server (not one of your own), the deploy stops with a message that the database can only be reached from your own server.
  • A database with a public address and no server of your own works from the platform, as before.
  • Connections tested before this change may still show Unreachable. Run Test from server once to refresh them.

Read replicas

A replica is optional. When you add one, OEC.sh writes its address into Odoo's configuration next to the primary, and Odoo sends some read-only requests to it.

  • Any provider works. Aurora and RDS are only examples: a Vultr or other managed replica, or a streaming standby you run yourself, works the same way. For a self-hosted cluster, choose Self-hosted, put the primary in Host and the standby in Replica Host / Port.
  • Same login. Odoo signs in to the replica with the same database user as the primary. A streaming replica already has that user.
  • Checked, not required. Saving the connection also checks that the replica answers. The result is for your information and never blocks a deploy.
  • Odoo 18 and later. Odoo added replica support in 18.0. On older versions the replica is ignored and everything runs on the primary.
  • Applied on deploy. The settings are written on every deploy. If you change the replica address, redeploy the environment to apply it.

Failover

OEC.sh does not switch from the primary to the replica for you, and writes never go to the replica:

  • Odoo always writes to the Host you enter. To survive a primary failure, point Host at an address that always follows your current primary (a DNS name, a floating IP, or a proxy) and handle the promotion on your side.
  • If a request tries to write on the replica, Odoo retries it on the primary.
  • If the replica goes down, Odoo keeps working on the primary alone and tries the replica again later.
  • Data read from the replica can be a few moments behind the primary.

What Works With External Databases

  • Connect As — signs in as any Odoo user the same way it does for a platform-managed database. See Connect As.
  • Database Terminal — opens directly into a psql prompt against your external cluster, same as for a platform-managed database.
  • Backups — manual and scheduled backups run against your external database the same way they do for platform-managed ones. See Backups.
  • Deployments — the platform automatically caps its own connection pool per deployment so it stays within your cluster's connection limit, even on a busy environment.

Troubleshooting

Health statusWhat it meansWhat to check
UnreachableThe host/port couldn't be reached from where the test ran (the platform, or the server shown in the result)Hostname and port are correct; the database's firewall allows connections from that server; for a private address, use Test from server
Auth FailedUsername or password didn't workDouble-check both, especially after a password rotation on the cluster
Invalid PoolingThe endpoint is PgBouncer in transaction-pooling modePoint the host at the real PostgreSQL port instead
Needs server testThe platform can't test this host: it's a private address, or a name only your network can resolveClick Test from server, or use it on an environment on your own server (the deploy checks it)
UntestedNo connection test has run yetClick one of the test icons next to the connection

The connection list also shows where the last test ran ("from your server" or "from the platform").