Skip to content

How to connect to a database on a private network

How-to
Before this

How to connect to a database on a private network

Open a client session against a PostgreSQL or MySQL/MariaDB instance that has no floating IP. The steps cover both connection paths: an application instance already on the private network, and a workstation reaching the subnet through a bastion.

Prerequisites

Windows: CLI examples use bash. Set up a Linux CLI environment on Windows before proceeding.

Replace DB_PRIVATE_IP with the database instance's private address, JUMP_HOST with your bastion's reachable address, and YOUR_PRIVATE_KEY_PATH with the key matching the key_name on the deployment. The templates default to Ubuntu 24.04, so the SSH user is ubuntu.

Step 1: Find the private address#

List the instances in the project and read the address from the database row:

bash
openstack server list -c Name -c Networks -c Status

The database instance shows one address on the private network and no floating IP:

+----------+-------------------------------+--------+
| Name     | Networks                      | Status |
+----------+-------------------------------+--------+
| postgres | postgres-net=192.168.40.12    | ACTIVE |
| app-01   | postgres-net=192.168.40.20    | ACTIVE |
+----------+-------------------------------+--------+

Step 2: Confirm the security group allows your source#

Find the group attached to the database instance, then list its rules:

bash
openstack server show postgres -c security_groups
openstack security group rule list SECURITY_GROUP_NAME

The rule you need shows the engine's port with your source range in the IP Range column: 5432 for PostgreSQL, 3306 for MySQL and MariaDB. If your source address falls outside every listed range, add a rule for it with How to create security group rules. Scope the new rule to the narrowest range that covers the client, such as the application subnet or a single instance address.

Step 3: Connect from an application instance#

An instance on the same private network connects directly. SSH to the application instance, install the client package, and open a session.

For PostgreSQL:

bash
sudo apt update && sudo apt install -y postgresql-client
PGPASSWORD='YOUR_DB_PASSWORD' psql -h DB_PRIVATE_IP -U appuser -d appdb -c "SELECT version();"

For MySQL or MariaDB:

bash
sudo apt update && sudo apt install -y mariadb-client
mysql -h DB_PRIVATE_IP -u appuser -p'YOUR_DB_PASSWORD' appdb -e "SELECT VERSION();"

A version string in the output confirms the network path, the security group rule, and the account all work.

Step 4: Connect from your workstation through a bastion#

A workstation has no route to the private subnet, so forward a local port through the bastion and point the client at 127.0.0.1.

For PostgreSQL:

bash
ssh -i YOUR_PRIVATE_KEY_PATH -N -L 5432:DB_PRIVATE_IP:5432 ubuntu@JUMP_HOST

For MySQL or MariaDB:

bash
ssh -i YOUR_PRIVATE_KEY_PATH -N -L 3306:DB_PRIVATE_IP:3306 ubuntu@JUMP_HOST

Leave that session running and connect from a second terminal:

bash
PGPASSWORD='YOUR_DB_PASSWORD' psql -h 127.0.0.1 -U appuser -d appdb
mysql -h 127.0.0.1 -u appuser -p'YOUR_DB_PASSWORD' appdb

The tunnel keeps the engine port off the public internet: the bastion terminates the SSH session, and the database still accepts connections only from inside the subnet.

Step 5: Verify from the application#

Point the application at the private address and confirm it connects with its own credentials rather than yours:

postgresql://appuser:[email protected]:5432/appdb
mysql://appuser:[email protected]:3306/appdb

Store the password with the rest of the application's secrets; see How to inject application secrets.

Troubleshoot a refused connection#

SymptomWhere to look
The client hangs, then times outSecurity group: no rule allows the source range on the engine port
Connection refused immediatelyThe engine is not listening on that address (listen_addresses for PostgreSQL, bind-address for MySQL and MariaDB), or the service is down
no pg_hba.conf entry for hostPostgreSQL authentication: add a matching pg_hba.conf line and reload the server
Access denied for userThe MySQL account's host pattern does not cover the client address, or the password is wrong
The tunnel command exits at onceLocal port already in use; choose another local port and point the client at it

Next steps#

Usage Guidelines

The sample code, software libraries, command line tools, proofs of concept, templates, and other related technology on this page (including any of the foregoing that is provided by Quake AI personnel) is provided to you as Quake AI Content under the Quake AI Customer Agreement, or the relevant written agreement between you and Quake AI (whichever applies). Do not use this Quake AI Content in your production accounts, or on production or other critical data. You are responsible for testing, securing, and optimizing the Quake AI Content (such as sample code) as appropriate for production grade use based on your specific quality control practices and standards. Deploying Quake AI Content may incur Quake AI charges for creating or using Quake AI chargeable resources, such as running Compute instances or storing data in Object Storage. Your use is also subject to the Acceptable Use Policy.

For the full policy, see Usage Guidelines.

Was this page helpful?