Skip to content
+1 (813) 212-3723 support@layeronecloud.com
Guides

A private database behind a web server

Keep PostgreSQL on a private address while preserving a safe path for updates and administration.

3 min read Reviewed 24 Aug 2026

The safe default is a public web server and a database that listens only on a private address. The database server keeps a public address for operating-system updates, but the database port is blocked by two firewalls and has no public listener.

What you are building

internet -> web-01  (203.0.113.10 + 10.10.0.10)
                |
             private network
                |
            db-01   (203.0.113.20 + 10.10.0.20)
                       PostgreSQL listens on 10.10.0.20 only

1. Create the private network

Networking in the client portal, then create a network with a range such as 10.10.0.0/24. See Private networks.

2. Deploy the database server with both networks

Leave public IPv4 on and join the private network as 10.10.0.20. The public path lets the operating system reach package repositories. You will block public application access before creating the database.

Turning public IPv4 off does not lower the plan price. It also removes internet access: LayerOne does not provide NAT for private networks, and a public address cannot be added to that server later.

3. Deploy the web server on the same network

Leave public IPv4 on and join the same private network as 10.10.0.10.

4. Confirm they can see each other

From web-01:

ping -c 3 10.10.0.20
ip -brief address

5. Set both firewalls on db-01

On the LayerOne Networking tab, set inbound policy to DROP and outbound to ACCEPT. Allow SSH from your own public address. Allow TCP 5432 only from 10.10.0.10/32.

Apply the same boundary inside the server. For Ubuntu with UFW:

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow from YOUR.PUBLIC.IP.ADDRESS to any port 22 proto tcp
sudo ufw allow from 10.10.0.10 to any port 5432 proto tcp
sudo ufw enable

Keep the browser console open until you have confirmed a new SSH connection.

6. Install PostgreSQL on db-01

sudo apt update && sudo apt install -y postgresql

Listen on the private address only, never on 0.0.0.0:

sudo -u postgres psql -c "ALTER SYSTEM SET listen_addresses = '10.10.0.20';"

Allow the web server, and nothing else:

echo 'host  appdb  appuser  10.10.0.10/32  scram-sha-256' \
  | sudo tee -a /etc/postgresql/*/main/pg_hba.conf
sudo systemctl restart postgresql

10.10.0.10/32 is one address, not the whole subnet. Widening it to 10.10.0.0/24 would admit every server you ever put on this network.

7. Create the database and user

sudo -u postgres psql <<'SQL'
CREATE USER appuser WITH PASSWORD 'use-a-long-random-one';
CREATE DATABASE appdb OWNER appuser;
SQL

8. Connect from the web server

sudo apt install -y postgresql-client
psql "postgresql://appuser@10.10.0.20/appdb"

9. Verify it is private

From your laptop, not from either server:

nc -zv 203.0.113.20 5432   # db-01's public address

That must fail. From web-01, the same check against 10.10.0.20 must succeed. Also verify the listening socket on db-01:

sudo ss -lntp | grep 5432

It should show 10.10.0.20:5432, never 0.0.0.0:5432.

If the database must have no public address

Build a dual-homed router or firewall first, enable NAT in that guest, and set it as the private network's gateway. Confirm that a test server can reach package repositories through it before deploying the database without public IPv4. See pfSense, OPNsense and VyOS.

Without that customer-managed route, a private-only server can be reached only through the browser console or another server on the same private network. It cannot run apt update, reach an external backup destination, or contact a public monitoring service.

Notes on this design

  • Private-network traffic counts toward transfer usage. Usage includes inbound and outbound traffic across public and private guest interfaces. See Bandwidth.
  • Encrypt anyway if the data is sensitive. A private network is not the internet, but it is not encrypted either. Turn on TLS in Postgres for anything regulated.
  • You still need backups. pg_dump on a schedule, shipped off the server. Nothing on the platform does this for you.
  • Add both firewall layers on the web server too. Its public services normally need ports 80 and 443; its database client does not need public port 5432.
Still stuck

Chat with us from the portal.

Ask the assistant from the Chat bar. During business hours you can ask for a person and a human joins live.