Files
framework-ignition-docker/CLAUDE.md
2026-03-17 13:23:56 -05:00

5.2 KiB

Ignition + Docker Development Framework

What This Is

Reusable scaffold for Ignition + Docker projects with Claude Code. The PLC I/O Testing Platform is the first project built on this framework.

Stack

  • Ignition 8.3 (Git-native project storage, Perspective, WebDev, OPC-UA)
  • Rockwell Allen-Bradley ControlLogix/CompactLogix, Studio 5000, PlantPAx
  • Docker Compose on Ubuntu 24 (Ignition, PostgreSQL, Traefik, Modbus sims)
  • Gitea at 192.168.3.59:3000 for source control
  • Jython 2.7 inside Ignition; Python 3.10+ for external tooling
  • Claude Code on the Linux host (VS Code Remote to Docker host)
  • WikiJS at wikijs.primecontrols-dev.com for team documentation (.md files auto-sync on git push via tools/publish_docs.py)

Gateway HTTP API

Ignition 8.3 exposes a full REST API. Use it for infrastructure-as-code configuration — adding DB connections, OPC connections, importing tags, managing projects, etc.

  • Browse: http://<gateway-host>:8088/openapi
  • Spec: http://<gateway-host>:8088/openapi.json
  • Auth header: X-Ignition-API-Token: <name>:<token>
  • Full reference: ignition/ignition-api.md
  • Skill: /ignition-configure — resolves token and walks through config tasks

API Key / Secrets Policy

Source of truth: ~/.config/ignition-dev/secrets.env (chmod 600, never committed) Template: .env.example in repo root — update this when adding new secrets

  • All secrets via environment variables — no hardcoded values in any file
  • Docker Compose references host env vars: VAR=${VAR} pattern
  • Python scripts use python-dotenv + os.environ["KEY"] (loud failure on missing)
  • .env at project root is a symlink to secrets file — listed in .gitignore
  • CI secrets live in Gitea repository secrets settings

Key variables: IGNITION_API_TOKEN, POSTGRES_PASSWORD — see .env.example for full list.

Language Rules

Jython 2.7 (Inside Ignition)

All scripts in ignition/project/ run Jython 2.7. Top violations:

  • NO f-strings → use "text {}".format(val)
  • NO walrus operator :=
  • NO type hints → no def foo(x: int) -> str:

Full constraint list: ignition/CLAUDE.md

Python 3.10+ (External Tooling)

All scripts outside Ignition use Python 3.10+. Add at top of every file:

# env: python3.10+ (external tooling — NOT Ignition)

Safety Rules (Non-Negotiable)

  1. Validate JSON before writing to any Ignition resource directory.
  2. Back up files before overwriting: cp file file.bak
  3. Sorted-key JSON for all JSON files (Git-friendly diffs).
  4. Never restart Ignition gateway without explicit user confirmation.
  5. Never docker compose down without confirmation (destroys unnamed volumes).
  6. Every change needs a verification step — scenario run, curl, tag read.
  7. Scan after file edits — after editing ignition/project/ run POST /data/api/v1/scan/projects; after editing docker/gw-config/ run POST /data/api/v1/scan/config. Use /ignition-configure.

Canonical Patterns (Do Not Change Without Discussion)

UDT / Linking Pattern

Linking/Link sub-UDT with LinkPath + LinkData for PLC signal binding. Decouples simulation from PLC I/O structure. All device test tags follow this.

JSON Test Scenarios

Five required sections: identity, device, initial_state, sequence, expected_outcomes. See testing/CLAUDE.md for full schema.

WebDev API

All external I/O goes through WebDev endpoints — never direct tag file edits at runtime: tagWrite, tagRead, tagBrowse, health. See webdev/CLAUDE.md.

Ignition as I/O Orchestrator

Ignition writes to Modbus containers and PLC I/O tags. PLC runs real logic. Test runner talks to Ignition only. Never bypass Ignition to write directly to Modbus or PLC.

Directory Layout

project-root/
├── CLAUDE.md
├── scripts/               ← setup.sh and utility scripts
├── docker/
│   ├── CLAUDE.md
│   ├── docker-compose.yml
│   ├── docker-compose.override.yml
│   ├── gw-build/              ← custom Ignition Dockerfile
│   ├── gw-init/               ← gateway env vars (no secrets)
│   ├── gw-commission/         ← commissioning.json
│   ├── gw-config/             ← gateway runtime config (bind-mounted; runtime dirs gitignored)
│   ├── gw-secret/             ← admin password file (gitignored)
│   └── config/
│       ├── postgres/          ← init.sql
│       └── traefik/           ← traefik.yml, dynamic/
├── ignition/
│   ├── CLAUDE.md
│   ├── ignition-api.md        ← Gateway HTTP API reference
│   └── project/
│       ├── com.inductiveautomation.perspective/
│       ├── com.inductiveautomation.webdev/
│       └── ignition/
│           ├── named-query/
│           ├── script-python/
│           └── global-props/
├── testing/
│   ├── CLAUDE.md
│   ├── scenarios/
│   ├── runner/
│   └── results/
├── webdev/
│   ├── CLAUDE.md
│   └── endpoints/
├── tools/
│   └── (Python 3.10+ external utilities)
└── docs/