Skip to content

Host 1 — Database host (RHEL 9)

Runs PostgreSQL 16 + TimescaleDB + pgvector. Accepts connections only from Host 2 (core). Nothing here needs the Rust toolchain.

Substitute: <CORE_HOST_IP> (Host 2's address), <DB_PASSWORD> (pick a real one — do not keep the script default).


1. Get the schema + install script

You don't need the whole repo built here, just the SQL and the installer:

sudo dnf install -y git
git clone https://gitlab.com/ironshep/ironshep-core.git
cd ironshep-core

2. Install PostgreSQL 16 + TimescaleDB + pgvector

sudo IRONSHEP_DB_PASS='<DB_PASSWORD>' bash scripts/install_db_rhel9.sh

This adds the PGDG and TimescaleDB repos, installs the packages, initializes the cluster, enables the timescaledb preload library, creates the ironshep role/database, and applies sql/schema.sql. It's idempotent — safe to re-run if a step fails partway.

Confirm:

sudo -u postgres /usr/pgsql-16/bin/psql -d ironshep -c '\dx'
# expect: timescaledb and vector both listed

3. Open Postgres to Host 2 only

By default Postgres listens on localhost only. Point it at this host's private interface and allow just Host 2's IP:

sudo tee -a /var/lib/pgsql/16/data/postgresql.conf > /dev/null <<'EOF'
listen_addresses = 'localhost,<THIS_HOST_PRIVATE_IP>'
EOF

echo "host  ironshep  ironshep  <CORE_HOST_IP>/32  scram-sha-256" | \
  sudo tee -a /var/lib/pgsql/16/data/pg_hba.conf

sudo systemctl restart postgresql-16

Replace <THIS_HOST_PRIVATE_IP> with this host's own address (the one Host 2 will dial), and <CORE_HOST_IP> with Host 2's address. Narrow the /32 to a subnet only if Host 2's IP is expected to change.

4. Firewall

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="<CORE_HOST_IP>/32" port port="5432" protocol="tcp" accept'
sudo firewall-cmd --reload

This opens 5432 to Host 2 specifically, not the whole network. SELinux stays Enforcing — nothing here needs a custom policy.

5. Double-check the password took

If you didn't set IRONSHEP_DB_PASS before running the installer, it used the placeholder default. Fix that now:

sudo -u postgres /usr/pgsql-16/bin/psql -c \
  "ALTER ROLE ironshep PASSWORD '<DB_PASSWORD>';"

Done

Hand <DB_PASSWORD> and this host's address to whoever configures Host 2 — it goes into core.toml's [db] url or the IRONSHEP_DB_URL environment variable there. Nothing further runs on this host; Postgres itself is the whole job.

Troubleshooting

Symptom Likely cause
Host 2 gets "connection refused" firewall rule missing, or listen_addresses not restarted
Host 2 gets "no pg_hba.conf entry" wrong IP/CIDR in the pg_hba.conf line, or Host 2's outbound IP differs from what you expected (NAT)
Host 2 gets "password authentication failed" password mismatch between here and Host 2's config