Skip to content

IronShep POC — 3-host RHEL 9 deployment

Splits the stack across three separate machines instead of the single-box lab in ironshep-core/docs/POC_LAB.md:

# Doc Host runs Talks to
0 00-local-mac.md the whole stack on one Mac — dev/demo alternative to the three VMs below, with captured output from a real run
1 01-database-host.md PostgreSQL 16 + TimescaleDB + pgvector accepts connections from Host 2 only
2 02-core-host.md ironshep-core (gRPC/mTLS ingest + web console) Host 1 (DB), accepts connections from Host 3 and operator browsers
3 03-edge-host.md ironshep-edge (protocol collector) + scheduled test jobs Host 2 (core)
4 04-redeploy.md (any host) — push a code change to core or edge onto an already-installed host
5 05-deploy-release.md (any host) — install or upgrade from a pre-built CI release bundle, no toolchain needed
                          operator browser
                                 │ 8080 http (console)
┌────────────────┐        ┌────────────────┐        ┌────────────────┐
│  Host 1         │        │  Host 2         │        │  Host 3         │
│  db.ironshep    │◄──5432─│  core.ironshep  │◄─50051─│  edge-lab1.     │
│  .local         │  tcp   │  .local         │  gRPC/ │  ironshep.local │
│                 │        │                 │  mTLS  │                 │
│  TimescaleDB    │        │  ironshep-core  │        │  ironshep-edge  │
└────────────────┘        └────────────────┘        │  + cron test jobs│
                                                    └────────────────┘

Ports at a glance

Port Host Who connects Notes
5432/tcp 1 Host 2 only scoped by pg_hba.conf + firewalld rich rule
50051/tcp 2 edge hosts gRPC, mTLS required
8080/tcp 2 operator browsers web console; plain HTTP in the POC — management network or TLS proxy
5514/udp+tcp, 5162/udp, 47808/udp 3 plant devices only the listeners you enable

Before you start

Substitute your real values everywhere <...> appears below:

Placeholder Example Meaning
<DB_HOST_IP> 10.0.10.10 Host 1's address, reachable from Host 2
<CORE_HOST_IP> 10.0.10.20 Host 2's address, reachable from Hosts 1 and 3
<CORE_HOSTNAME> core.ironshep.local Host 2's DNS name, if you have one (else use the IP everywhere and skip the DNS SAN)
<DB_PASSWORD> (generate one) ironshep role's password — do not keep the script default
<EDGE_ID> lab1 short id for this edge; becomes the site on every asset row

Do the hosts in order: Host 1, then Host 2 (needs Host 1 reachable), then Host 3 (needs Host 2's certificate + Host 2 reachable). All three commands below assume sudo access and outbound internet for package/crate downloads.

Repos

https://gitlab.com/ironshep/ironshep-core.git   -> Host 1 (sql/scripts only) and Host 2 (full build)
https://gitlab.com/ironshep/ironshep-edge.git   -> Host 3 (full build)

Verifying the whole chain

Easiest: open the console at http://<CORE_HOST_IP>:8080 and sign in with the account created in Host 2's step 8. The Fleet page should show a card per edge, online, with a climbing 24h event count.

Or from Host 1, straight against the database:

sudo -u postgres /usr/pgsql-16/bin/psql -d ironshep -c \
  "SELECT ts, edge_id, protocol, category, left(message,60) FROM events ORDER BY ts DESC LIMIT 10;"

Rows tagged edge_id = <EDGE_ID> confirm the full path: edge capture → gRPC/mTLS → core → TimescaleDB.

Keeping it exercised

Host 3's doc (step 8) installs two cron jobs — a synthetic traffic generator that keeps realistic plant messages flowing every 5 minutes, and a health check that mails you when the edge stops being healthy. Both stay quiet while things work.