02-environment merges the old 02-env and 03-containers - both answered the
same question, 'where does this run and how do I reach it', and were split
for no reason.
README.md the two hosts, access, ports, secrets, health
checks, known issues
YAU_Linux_Host_Onboarding.md the Linux host's own brief, copied with a
provenance banner: owned by the host owner, not
maintained here, and its 'save this as CLAUDE.md'
instruction does not apply in this repo
openplc-container.md the container as read from the running host
openplc-compose.yml verbatim copy of the live file
MIGRATION.md moving the container - as-built plus runbook
secrets.local.md.template the shape of the git-ignored secrets file
The README leads with the fact that shapes every decision on that machine:
yau-sls-poc-lin001 is a SHARED, LIVE host running ~28 containers for
several projects behind Caddy and Authelia, and this project owns exactly
one of them. Never restart Caddy or Authelia, never publish on 0.0.0.0,
never put growing data on the 62 GB root disk.
Records four known issues rather than leaving them in anyone's head: the
100 ms scan overruns, the 354 MB migration tarballs still sitting on the
host with the JWT secret inside one of them, the runtime image existing in
no registry, and the missing Editor toolchain.
Not carried across: Host_Documentation.md. ~400 lines on ChirpStack,
Forgejo, EQP licensing and the Telegraf fleet - none of it WRPS, owned
elsewhere, and a stale copy here would be worse than a pointer.
6.5 KiB
02-environment — where this runs and how to reach it
Two machines. One runs the PLC, the other runs the SCADA. Both sit on the
10.0.0.0/24 PoC network.
| Role | Hostname | LAN | Notes |
|---|---|---|---|
| SCADA — Yokogawa CI Server R1.03 | yau-poc-cicore1 |
10.0.0.21 |
Windows. Polls the PLC over Modbus TCP. |
| PLC — OpenPLC Runtime v4 in Docker | yau-sls-poc-lin001 |
10.0.0.17 |
Ubuntu 22.04 on Azure, public IP 20.211.144.151. Shared, live host — see below. |
Also on the network: an Active Directory domain controller at 10.0.0.5
(yau.poc), and roughly a dozen other Windows hosts.
⚠️ The Linux host is shared, live, and not ours
yau-sls-poc-lin001 is the YAU Innovation Team's general-purpose Docker host and
VPN gateway. It runs ~28 containers for several unrelated projects — Grafana,
InfluxDB, Node-RED, Forgejo, Authelia, Portainer and more — behind a Caddy reverse
proxy with AD + Duo MFA. It serves customer-facing demos.
openplc-runtime is one container among many, and this project owns only that
one. Rules that follow from it:
- Never restart Caddy or Authelia — they interrupt every other service.
- Never put growing data on the root disk (
/is 62 GB). Use/datadisk. - Never publish a container port on
0.0.0.0. The host has a public IP. - Everyone shares the
azureuserlogin, so there is no per-person audit trail — announce disruptive work.
YAU_Linux_Host_Onboarding.md is the host's own brief, written by its owner
(Daniel Watson) and current as of 2026-09-01. Read it before changing anything
on that machine. Its §10 is a list of rules, each of which exists because
breaking it already caused an outage.
Access
The Linux host — SSH
ssh -i ~/.ssh/yau-sls-poc-lin001_key.pem azureuser@20.211.144.151
An SSH config alias makes this shorter. The working copy used during the audit:
Host lin001
HostName 20.211.144.151
User azureuser
IdentityFile ~/.ssh/yau-sls-poc-lin001_key.pem
IdentitiesOnly yes
10.0.0.17 is only routable from inside the VNet or over the WireGuard VPN —
from outside, use the public IP.
The CI Server host
No remote access route is recorded. It was reached interactively during development. If you need one, ask.
What you need from the host owner
| Item | What it is |
|---|---|
yau-sls-poc-lin001_key.pem |
SSH private key — chmod 600 it or SSH refuses to use it |
AD account in HTTPS_UserAccess |
required for every web UI on the host |
| Duo enrolment | second factor for those UIs |
| A WireGuard peer | optional, but it is what makes 10.0.0.x reachable directly |
Ports
| Service | Host | Port | Bound to | Notes |
|---|---|---|---|---|
| OpenPLC Modbus TCP server | 10.0.0.17 |
502 | 10.0.0.17 only |
The PLC is the Modbus slave. CI Server polls it. |
| OpenPLC REST API (HTTPS) | 10.0.0.17 |
8443 | 10.0.0.17 only |
Control channel — upload, start/stop. JWT auth. No browser UI. |
| CI Server Modbus client | 10.0.0.21 |
— | outbound |
Important
The bind address is the security control. Modbus has no authentication or encryption, and 8443 is the control channel with only JWT in front of it. The host has a public IP, so binding these to
10.0.0.17rather than0.0.0.0is the only thing keeping them off the internet. Never widen it.
There is no host firewall. ufw is inactive on yau-sls-poc-lin001; inbound
filtering is entirely the Azure Network Security Group. Opening a port means
editing the NSG in the Azure portal, not the host.
Secrets
Live in secrets.local.md, which is git-ignored and must never be committed.
secrets.local.md.template shows the shape — copy it, fill it in, keep it local.
It holds the OpenPLC runtime admin password and CI Server credentials. The SSH
key is a file, not a line in that document, and is likewise never committed.
Host-level credentials (service admin passwords, API tokens for Grafana, Influx,
Authelia and so on) are not this project's — they live in the host owner's
Linux Machine Config.txt. Ask; do not copy them here.
Files here
| File | What |
|---|---|
YAU_Linux_Host_Onboarding.md |
The Linux host's own brief — the stack, the auth model, the deployment pattern, and the rules. Written and owned by the host owner, not by this project. Current 2026-09-01. |
openplc-container.md |
How the PLC container is configured, as read from the running host |
openplc-compose.yml |
Verbatim copy of the live ~/openplc-compose.yml |
MIGRATION.md |
Moving the PLC container to another host — the as-built record of the 2026-08-19 move, kept as a repeatable runbook |
secrets.local.md.template |
The shape of the git-ignored secrets file |
Not kept here: the host's full operations manual (Host_Documentation.md,
~400 lines covering ChirpStack, Forgejo, EQP licensing, the Telegraf fleet and the
rest of the platform). None of it is WRPS, it is owned elsewhere, and a stale copy
in this repo would be worse than a pointer. Ask the host owner for the current
version.
Checking the environment is healthy
ssh lin001 "docker ps --filter name=openplc-runtime"
ssh lin001 "docker logs --tail 30 openplc-runtime"
ssh lin001 "df -h / /datadisk" # both disks - / is only 62 GB
From a machine that can route to 10.0.0.17 (VNet or VPN):
python ../05-tests/verify_modbus.py --host 10.0.0.17 --port 502 --unit 1
From anywhere else, poll from a throwaway container on the host's own network:
ssh lin001 "docker run --rm --network openplc-net python:3.12-alpine \
sh -c 'pip install -q pymodbus && python -c \"...\"'"
Known issues
| Issue | Detail |
|---|---|
| PLC scan overruns | The 100 ms task overran ~100 times between 2026-08-19 and 2026-08-28 — roughly one per 4–5 days. Logged as a warning; the task runs at a reduced rate and the demo continues. Not investigated; the host is shared, so contention is a candidate. |
| Migration artefacts left on the host | ~/openplc-migration/ still holds openplc-image.tar.gz (354 MB) and openplc-vol.tar.gz. MIGRATION.md Part G says to delete them, and the volume tarball contains the runtime's JWT secret. |
| The runtime image cannot be re-pulled | It was produced by docker commit and exists in no registry. Deleting it loses the compiled PLC program. See 03-plc/as-built/. |
| No deployment toolchain | The OpenPLC Editor lived only on the retired dev-ubuntu host. See 03-plc/DEPLOY.md §0. |