ignition-stack 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ignition_stack/__init__.py +1 -0
- ignition_stack/catalog/__init__.py +10 -0
- ignition_stack/catalog/download.py +145 -0
- ignition_stack/catalog/loader.py +65 -0
- ignition_stack/catalog/schema.py +158 -0
- ignition_stack/catalog/verify.py +72 -0
- ignition_stack/cli.py +354 -0
- ignition_stack/commands/__init__.py +0 -0
- ignition_stack/commands/modules.py +178 -0
- ignition_stack/completion.py +46 -0
- ignition_stack/compose/__init__.py +4 -0
- ignition_stack/compose/engine.py +397 -0
- ignition_stack/compose/templates/footer.yaml.j2 +12 -0
- ignition_stack/compose/templates/header.yaml.j2 +14 -0
- ignition_stack/compose/templates/services/bootstrap.yaml.j2 +19 -0
- ignition_stack/compose/templates/services/ignition.yaml.j2 +35 -0
- ignition_stack/compose/writer.py +428 -0
- ignition_stack/config/__init__.py +8 -0
- ignition_stack/config/schema.py +311 -0
- ignition_stack/lifecycle/__init__.py +31 -0
- ignition_stack/lifecycle/cleanup.py +71 -0
- ignition_stack/lifecycle/record.py +67 -0
- ignition_stack/lifecycle/regenerate.py +62 -0
- ignition_stack/modules.yaml +83 -0
- ignition_stack/postsetup/__init__.py +3 -0
- ignition_stack/postsetup/generator.py +187 -0
- ignition_stack/profiles/__init__.py +27 -0
- ignition_stack/profiles/advisory.py +132 -0
- ignition_stack/profiles/base.py +108 -0
- ignition_stack/profiles/hub_and_spoke.py +87 -0
- ignition_stack/profiles/mcp_n8n.py +55 -0
- ignition_stack/profiles/scaleout.py +65 -0
- ignition_stack/profiles/standalone.py +44 -0
- ignition_stack/services/__init__.py +25 -0
- ignition_stack/services/loader.py +69 -0
- ignition_stack/services/manifest.py +106 -0
- ignition_stack/services/resolver.py +133 -0
- ignition_stack/templates/__init__.py +0 -0
- ignition_stack/templates/post-setup/_default.md.j2 +12 -0
- ignition_stack/templates/post-setup/device-connection.md.j2 +11 -0
- ignition_stack/templates/post-setup/gateway-network-link.md.j2 +18 -0
- ignition_stack/templates/post-setup/identity-provider.md.j2 +13 -0
- ignition_stack/templates/post-setup/kafka-connector.md.j2 +11 -0
- ignition_stack/templates/post-setup/mcp-module.md.j2 +11 -0
- ignition_stack/templates/post-setup/mqtt-engine-connection.md.j2 +11 -0
- ignition_stack/templates/post-setup/opc-ua-connection.md.j2 +11 -0
- ignition_stack/templates/post-setup/reverse-proxy.md.j2 +8 -0
- ignition_stack/templates/services/chariot/compose.yaml.j2 +17 -0
- ignition_stack/templates/services/chariot/manifest.yaml +22 -0
- ignition_stack/templates/services/chariot/seed/service/USAGE.md +14 -0
- ignition_stack/templates/services/emqx/compose.yaml.j2 +16 -0
- ignition_stack/templates/services/emqx/manifest.yaml +21 -0
- ignition_stack/templates/services/emqx/seed/service/USAGE.md +11 -0
- ignition_stack/templates/services/hivemq/compose.yaml.j2 +12 -0
- ignition_stack/templates/services/hivemq/manifest.yaml +19 -0
- ignition_stack/templates/services/hivemq/seed/service/USAGE.md +16 -0
- ignition_stack/templates/services/kafka/compose.yaml.j2 +27 -0
- ignition_stack/templates/services/kafka/manifest.yaml +20 -0
- ignition_stack/templates/services/kafka/seed/service/USAGE.md +17 -0
- ignition_stack/templates/services/keycloak/compose.yaml.j2 +31 -0
- ignition_stack/templates/services/keycloak/manifest.yaml +25 -0
- ignition_stack/templates/services/keycloak/seed/service/import/ignition-realm.json +31 -0
- ignition_stack/templates/services/mariadb/compose.yaml.j2 +26 -0
- ignition_stack/templates/services/mariadb/manifest.yaml +15 -0
- ignition_stack/templates/services/mariadb/seed/service/initdb/00-create-extra-databases.sh +19 -0
- ignition_stack/templates/services/modbus-sim/compose.yaml.j2 +12 -0
- ignition_stack/templates/services/modbus-sim/manifest.yaml +19 -0
- ignition_stack/templates/services/modbus-sim/seed/service/USAGE.md +10 -0
- ignition_stack/templates/services/mongo/compose.yaml.j2 +21 -0
- ignition_stack/templates/services/mongo/manifest.yaml +14 -0
- ignition_stack/templates/services/mongo/seed/service/initdb/01-demo-collection.js +10 -0
- ignition_stack/templates/services/mysql/compose.yaml.j2 +26 -0
- ignition_stack/templates/services/mysql/manifest.yaml +15 -0
- ignition_stack/templates/services/mysql/seed/service/initdb/00-create-extra-databases.sh +19 -0
- ignition_stack/templates/services/n8n/compose.yaml.j2 +16 -0
- ignition_stack/templates/services/n8n/manifest.yaml +16 -0
- ignition_stack/templates/services/n8n/seed/service/USAGE.md +11 -0
- ignition_stack/templates/services/opcua-sim/compose.yaml.j2 +13 -0
- ignition_stack/templates/services/opcua-sim/manifest.yaml +21 -0
- ignition_stack/templates/services/opcua-sim/seed/service/USAGE.md +11 -0
- ignition_stack/templates/services/postgres/compose.yaml.j2 +26 -0
- ignition_stack/templates/services/postgres/manifest.yaml +21 -0
- ignition_stack/templates/services/postgres/seed/gateway-resources/config/resources/core/ignition/database-connection/db/config.json +32 -0
- ignition_stack/templates/services/postgres/seed/gateway-resources/config/resources/core/ignition/database-connection/db/resource.json +19 -0
- ignition_stack/templates/services/postgres/seed/gateway-resources/config/resources/core/ignition/secret-provider/internal-secret-provider/config.json +19 -0
- ignition_stack/templates/services/postgres/seed/gateway-resources/config/resources/core/ignition/secret-provider/internal-secret-provider/resource.json +19 -0
- ignition_stack/templates/services/postgres/seed/service/initdb/00-create-extra-databases.sh +17 -0
- ignition_stack/templates/services/rabbitmq/compose.yaml.j2 +19 -0
- ignition_stack/templates/services/rabbitmq/manifest.yaml +23 -0
- ignition_stack/templates/services/rabbitmq/seed/service/enabled_plugins +1 -0
- ignition_stack/templates/standalone-postgres/docker-compose.yaml +62 -0
- ignition_stack/templates/standalone-postgres/scripts/docker-bootstrap.sh +78 -0
- ignition_stack/templates/standalone-postgres/services/ignition/config/resources/core/config-mode.json +7 -0
- ignition_stack/templates/standalone-postgres/services/ignition/config/resources/dev/config-mode.json +7 -0
- ignition_stack/templates/standalone-postgres/services/ignition/projects/.gitkeep +0 -0
- ignition_stack/wizard.py +362 -0
- ignition_stack-0.1.0.dist-info/METADATA +97 -0
- ignition_stack-0.1.0.dist-info/RECORD +100 -0
- ignition_stack-0.1.0.dist-info/WHEEL +4 -0
- ignition_stack-0.1.0.dist-info/entry_points.txt +2 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: {{ image_ref }}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
CLUSTER_ID: ${KAFKA_CLUSTER_ID}
|
|
8
|
+
KAFKA_NODE_ID: "1"
|
|
9
|
+
KAFKA_PROCESS_ROLES: broker,controller
|
|
10
|
+
KAFKA_CONTROLLER_QUORUM_VOTERS: 1@{{ name }}:29093
|
|
11
|
+
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092,CONTROLLER://0.0.0.0:29093,PLAINTEXT_HOST://0.0.0.0:9094
|
|
12
|
+
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://{{ name }}:9092,PLAINTEXT_HOST://localhost:${KAFKA_PORT}
|
|
13
|
+
KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
|
|
14
|
+
KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
|
|
15
|
+
KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
|
|
16
|
+
KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: "1"
|
|
17
|
+
KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: "1"
|
|
18
|
+
KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: "1"
|
|
19
|
+
KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: "0"
|
|
20
|
+
ports:
|
|
21
|
+
- "${KAFKA_PORT}:9094"
|
|
22
|
+
{%- if networks %}
|
|
23
|
+
networks:
|
|
24
|
+
{%- for net in networks %}
|
|
25
|
+
- {{ net }}
|
|
26
|
+
{%- endfor %}
|
|
27
|
+
{%- endif %}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
# Kafka - single-node KRaft broker. Ignition talks to it via the built-in
|
|
2
|
+
# Kafka connector / Event Streams modules (no third-party .modl needed).
|
|
3
|
+
name: kafka
|
|
4
|
+
kind: streaming
|
|
5
|
+
summary: Single-node Kafka broker (KRaft mode) for Event Streams demos.
|
|
6
|
+
image: confluentinc/cp-kafka:8.2.1
|
|
7
|
+
image_env: KAFKA_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- kafka-broker
|
|
11
|
+
requires: []
|
|
12
|
+
env:
|
|
13
|
+
KAFKA_PORT: "9094"
|
|
14
|
+
KAFKA_CLUSTER_ID: 4L6g3nShT-eMCtK--X86sw
|
|
15
|
+
seeds_gateway_resources: false
|
|
16
|
+
post_setup:
|
|
17
|
+
- connection: kafka-connector
|
|
18
|
+
reason: >-
|
|
19
|
+
Configure Ignition's built-in Kafka connector to point at
|
|
20
|
+
kafka:9092 in the gateway once the broker is up.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Kafka (single-node KRaft)
|
|
2
|
+
|
|
3
|
+
A single-node Kafka broker. No ZooKeeper - it runs as its own KRaft controller.
|
|
4
|
+
|
|
5
|
+
- In-stack bootstrap server (for the gateway and other containers):
|
|
6
|
+
`kafka:9092`.
|
|
7
|
+
- Host bootstrap server (for local tools): `localhost:${KAFKA_PORT}`.
|
|
8
|
+
|
|
9
|
+
Create a topic and produce from the host:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
docker compose exec kafka kafka-topics --bootstrap-server kafka:9092 \
|
|
13
|
+
--create --topic demo --partitions 1 --replication-factor 1
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Ignition connects via the built-in Kafka connector (Event Streams) - point it
|
|
17
|
+
at `kafka:9092`. No third-party module is required.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: {{ image_ref }}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
{%- if depends_on %}
|
|
6
|
+
depends_on:
|
|
7
|
+
{%- for dep in depends_on %}
|
|
8
|
+
{{ dep }}:
|
|
9
|
+
condition: service_healthy
|
|
10
|
+
{%- endfor %}
|
|
11
|
+
{%- endif %}
|
|
12
|
+
command: ["start-dev", "--import-realm"]
|
|
13
|
+
environment:
|
|
14
|
+
TZ: ${TZ}
|
|
15
|
+
KC_BOOTSTRAP_ADMIN_USERNAME: ${KEYCLOAK_ADMIN_USER}
|
|
16
|
+
KC_BOOTSTRAP_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD}
|
|
17
|
+
KC_DB: {{ db_kind }}
|
|
18
|
+
KC_DB_URL_HOST: ${DB_HOST}
|
|
19
|
+
KC_DB_URL_DATABASE: keycloak
|
|
20
|
+
KC_DB_USERNAME: ${DB_USER}
|
|
21
|
+
KC_DB_PASSWORD: ${DB_PASSWORD}
|
|
22
|
+
ports:
|
|
23
|
+
- "${KEYCLOAK_HTTP_PORT}:8080"
|
|
24
|
+
volumes:
|
|
25
|
+
- ./services/{{ name }}/import:/opt/keycloak/data/import:ro
|
|
26
|
+
{%- if networks %}
|
|
27
|
+
networks:
|
|
28
|
+
{%- for net in networks %}
|
|
29
|
+
- {{ net }}
|
|
30
|
+
{%- endfor %}
|
|
31
|
+
{%- endif %}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Keycloak - OIDC/SAML identity provider for gateway single sign-on.
|
|
2
|
+
# Requires a SQL database; the resolver auto-adds Postgres (and a dedicated
|
|
3
|
+
# "keycloak" logical database) when none is selected.
|
|
4
|
+
name: keycloak
|
|
5
|
+
kind: idp
|
|
6
|
+
summary: Keycloak identity provider for gateway OIDC/SAML single sign-on.
|
|
7
|
+
image: quay.io/keycloak/keycloak:26.6.2
|
|
8
|
+
image_env: KEYCLOAK_IMAGE
|
|
9
|
+
network: backend
|
|
10
|
+
provides:
|
|
11
|
+
- oidc-idp
|
|
12
|
+
requires:
|
|
13
|
+
- sql-database
|
|
14
|
+
env:
|
|
15
|
+
KEYCLOAK_ADMIN_USER: admin
|
|
16
|
+
KEYCLOAK_ADMIN_PASSWORD: admin
|
|
17
|
+
KEYCLOAK_HTTP_PORT: "8081"
|
|
18
|
+
seeds_gateway_resources: false
|
|
19
|
+
post_setup:
|
|
20
|
+
- connection: identity-provider
|
|
21
|
+
reason: >-
|
|
22
|
+
Keycloak generates the OIDC client secret at runtime, so it cannot be
|
|
23
|
+
file-seeded into the gateway's identity-provider config. Create (or open)
|
|
24
|
+
the ignition-gateway client in Keycloak, copy its secret, and paste it
|
|
25
|
+
into the gateway's IdP configuration.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"realm": "ignition",
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"displayName": "Ignition",
|
|
5
|
+
"clients": [
|
|
6
|
+
{
|
|
7
|
+
"clientId": "ignition-gateway",
|
|
8
|
+
"name": "Ignition Gateway",
|
|
9
|
+
"description": "OIDC client for Ignition gateway single sign-on. Copy this client's secret into the gateway IdP config (see POST-SETUP.md).",
|
|
10
|
+
"enabled": true,
|
|
11
|
+
"protocol": "openid-connect",
|
|
12
|
+
"publicClient": false,
|
|
13
|
+
"standardFlowEnabled": true,
|
|
14
|
+
"directAccessGrantsEnabled": true,
|
|
15
|
+
"redirectUris": [
|
|
16
|
+
"*"
|
|
17
|
+
],
|
|
18
|
+
"webOrigins": [
|
|
19
|
+
"*"
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
],
|
|
23
|
+
"roles": {
|
|
24
|
+
"realm": [
|
|
25
|
+
{
|
|
26
|
+
"name": "ignition-admin",
|
|
27
|
+
"description": "Maps to the Administrator role in the Ignition gateway."
|
|
28
|
+
}
|
|
29
|
+
]
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: ${MARIADB_IMAGE}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
MARIADB_ROOT_PASSWORD: ${DB_PASSWORD}
|
|
8
|
+
MARIADB_DATABASE: ${DB_USER}
|
|
9
|
+
MARIADB_USER: ${DB_USER}
|
|
10
|
+
MARIADB_PASSWORD: ${DB_PASSWORD}
|
|
11
|
+
{%- if extra_databases %}
|
|
12
|
+
EXTRA_DATABASES: ${EXTRA_DATABASES}
|
|
13
|
+
volumes:
|
|
14
|
+
- ./services/{{ name }}/initdb:/docker-entrypoint-initdb.d:ro
|
|
15
|
+
{%- endif %}
|
|
16
|
+
healthcheck:
|
|
17
|
+
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
|
|
18
|
+
interval: 5s
|
|
19
|
+
timeout: 10s
|
|
20
|
+
retries: 10
|
|
21
|
+
{%- if networks %}
|
|
22
|
+
networks:
|
|
23
|
+
{%- for net in networks %}
|
|
24
|
+
- {{ net }}
|
|
25
|
+
{%- endfor %}
|
|
26
|
+
{%- endif %}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# MariaDB - SQL database, MySQL-compatible. Ignition ships a MariaDB driver
|
|
2
|
+
# config built in, so no external JDBC driver is attached.
|
|
3
|
+
name: mariadb
|
|
4
|
+
kind: database
|
|
5
|
+
summary: MariaDB database (MySQL-compatible), driver built into Ignition.
|
|
6
|
+
image: mariadb:11
|
|
7
|
+
image_env: MARIADB_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- sql-database
|
|
11
|
+
- mysql-compatible
|
|
12
|
+
requires: []
|
|
13
|
+
env: {}
|
|
14
|
+
seeds_gateway_resources: false
|
|
15
|
+
post_setup: []
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# MariaDB runs every *.sh in /docker-entrypoint-initdb.d once, on first init.
|
|
3
|
+
# Creates each database named in EXTRA_DATABASES (comma-separated) and grants
|
|
4
|
+
# the application user access. The resolver sets EXTRA_DATABASES to "keycloak"
|
|
5
|
+
# when Keycloak is selected against this database.
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
if [ -z "${EXTRA_DATABASES:-}" ]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
for db in $(echo "${EXTRA_DATABASES}" | tr ',' ' '); do
|
|
13
|
+
echo "Ensuring database '${db}' exists..."
|
|
14
|
+
mariadb -u root -p"${MARIADB_ROOT_PASSWORD}" <<-SQL
|
|
15
|
+
CREATE DATABASE IF NOT EXISTS \`${db}\`;
|
|
16
|
+
GRANT ALL PRIVILEGES ON \`${db}\`.* TO '${MARIADB_USER}'@'%';
|
|
17
|
+
FLUSH PRIVILEGES;
|
|
18
|
+
SQL
|
|
19
|
+
done
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Modbus TCP simulation server (oitc/modbus-server). Serves simulated
|
|
2
|
+
# holding/input registers over Modbus TCP for driver demos.
|
|
3
|
+
name: modbus-sim
|
|
4
|
+
kind: simulator
|
|
5
|
+
summary: Modbus TCP simulation server for the gateway Modbus driver.
|
|
6
|
+
image: oitc/modbus-server:2.2.0
|
|
7
|
+
image_env: MODBUS_SIM_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- modbus-server
|
|
11
|
+
requires: []
|
|
12
|
+
env:
|
|
13
|
+
MODBUS_SIM_PORT: "5020"
|
|
14
|
+
seeds_gateway_resources: false
|
|
15
|
+
post_setup:
|
|
16
|
+
- connection: device-connection
|
|
17
|
+
reason: >-
|
|
18
|
+
The gateway Modbus device connection (unit ID, register mappings) is set
|
|
19
|
+
up in the gateway UI once the simulator is reachable.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Modbus TCP Simulation Server
|
|
2
|
+
|
|
3
|
+
Serves simulated Modbus registers over TCP on `5020` (host port
|
|
4
|
+
`${MODBUS_SIM_PORT}`).
|
|
5
|
+
|
|
6
|
+
Endpoint from another container: `modbus-sim:5020`. From the host:
|
|
7
|
+
`localhost:${MODBUS_SIM_PORT}`.
|
|
8
|
+
|
|
9
|
+
In the Ignition gateway, add a Modbus TCP device pointing at `modbus-sim:5020`
|
|
10
|
+
(unit ID 1) and map the holding/input registers you want to poll.
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: ${MONGO_IMAGE}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
MONGO_INITDB_ROOT_USERNAME: ${DB_USER}
|
|
8
|
+
MONGO_INITDB_ROOT_PASSWORD: ${DB_PASSWORD}
|
|
9
|
+
volumes:
|
|
10
|
+
- ./services/{{ name }}/initdb:/docker-entrypoint-initdb.d:ro
|
|
11
|
+
healthcheck:
|
|
12
|
+
test: ["CMD", "mongosh", "--quiet", "--eval", "db.adminCommand('ping')"]
|
|
13
|
+
interval: 5s
|
|
14
|
+
timeout: 10s
|
|
15
|
+
retries: 10
|
|
16
|
+
{%- if networks %}
|
|
17
|
+
networks:
|
|
18
|
+
{%- for net in networks %}
|
|
19
|
+
- {{ net }}
|
|
20
|
+
{%- endfor %}
|
|
21
|
+
{%- endif %}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# MongoDB - document store. Used by automation/streaming demos that want a
|
|
2
|
+
# NoSQL backend. Not a SQL database, so it does not satisfy Keycloak.
|
|
3
|
+
name: mongo
|
|
4
|
+
kind: database
|
|
5
|
+
summary: MongoDB document store for NoSQL demos.
|
|
6
|
+
image: mongo:7
|
|
7
|
+
image_env: MONGO_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- document-store
|
|
11
|
+
requires: []
|
|
12
|
+
env: {}
|
|
13
|
+
seeds_gateway_resources: false
|
|
14
|
+
post_setup: []
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
// MongoDB runs every *.js in /docker-entrypoint-initdb.d once, on first init.
|
|
2
|
+
// Seeds a small "ignition" database with one demo collection so the store is
|
|
3
|
+
// non-empty when you first connect (replace with your own schema).
|
|
4
|
+
db = db.getSiblingDB("ignition");
|
|
5
|
+
db.createCollection("readings");
|
|
6
|
+
db.readings.insertOne({
|
|
7
|
+
source: "ignition-stack-seed",
|
|
8
|
+
note: "Demo document. Safe to delete.",
|
|
9
|
+
createdAt: new Date(),
|
|
10
|
+
});
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: ${MYSQL_IMAGE}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
MYSQL_ROOT_PASSWORD: ${DB_PASSWORD}
|
|
8
|
+
MYSQL_DATABASE: ${DB_USER}
|
|
9
|
+
MYSQL_USER: ${DB_USER}
|
|
10
|
+
MYSQL_PASSWORD: ${DB_PASSWORD}
|
|
11
|
+
{%- if extra_databases %}
|
|
12
|
+
EXTRA_DATABASES: ${EXTRA_DATABASES}
|
|
13
|
+
volumes:
|
|
14
|
+
- ./services/{{ name }}/initdb:/docker-entrypoint-initdb.d:ro
|
|
15
|
+
{%- endif %}
|
|
16
|
+
healthcheck:
|
|
17
|
+
test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
|
|
18
|
+
interval: 5s
|
|
19
|
+
timeout: 10s
|
|
20
|
+
retries: 10
|
|
21
|
+
{%- if networks %}
|
|
22
|
+
networks:
|
|
23
|
+
{%- for net in networks %}
|
|
24
|
+
- {{ net }}
|
|
25
|
+
{%- endfor %}
|
|
26
|
+
{%- endif %}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# MySQL - SQL database. Selecting MySQL makes the resolver attach the
|
|
2
|
+
# mysql-jdbc driver to every gateway (Ignition ships no MySQL driver built-in).
|
|
3
|
+
name: mysql
|
|
4
|
+
kind: database
|
|
5
|
+
summary: MySQL database; pulls in the MySQL JDBC driver for the gateway.
|
|
6
|
+
image: mysql:9
|
|
7
|
+
image_env: MYSQL_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- sql-database
|
|
11
|
+
- mysql-compatible
|
|
12
|
+
requires: []
|
|
13
|
+
env: {}
|
|
14
|
+
seeds_gateway_resources: false
|
|
15
|
+
post_setup: []
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# MySQL runs every *.sh in /docker-entrypoint-initdb.d once, on first init.
|
|
3
|
+
# Creates each database named in EXTRA_DATABASES (comma-separated) and grants
|
|
4
|
+
# the application user access. The resolver sets EXTRA_DATABASES to "keycloak"
|
|
5
|
+
# when Keycloak is selected against this database.
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
if [ -z "${EXTRA_DATABASES:-}" ]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
for db in $(echo "${EXTRA_DATABASES}" | tr ',' ' '); do
|
|
13
|
+
echo "Ensuring database '${db}' exists..."
|
|
14
|
+
mysql -u root -p"${MYSQL_ROOT_PASSWORD}" <<-SQL
|
|
15
|
+
CREATE DATABASE IF NOT EXISTS \`${db}\`;
|
|
16
|
+
GRANT ALL PRIVILEGES ON \`${db}\`.* TO '${MYSQL_USER}'@'%';
|
|
17
|
+
FLUSH PRIVILEGES;
|
|
18
|
+
SQL
|
|
19
|
+
done
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: {{ image_ref }}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
N8N_SECURE_COOKIE: "false"
|
|
8
|
+
N8N_RUNNERS_ENABLED: "true"
|
|
9
|
+
ports:
|
|
10
|
+
- "${N8N_PORT}:5678"
|
|
11
|
+
{%- if networks %}
|
|
12
|
+
networks:
|
|
13
|
+
{%- for net in networks %}
|
|
14
|
+
- {{ net }}
|
|
15
|
+
{%- endfor %}
|
|
16
|
+
{%- endif %}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# n8n - workflow automation. The user-facing service in the catalog, so it
|
|
2
|
+
# lands on the frontend network when the network split is on. Pairs with the
|
|
3
|
+
# Ignition MCP module in the mcp-n8n profile (Phase 6).
|
|
4
|
+
name: n8n
|
|
5
|
+
kind: automation
|
|
6
|
+
summary: n8n workflow automation engine.
|
|
7
|
+
image: n8nio/n8n:2.23.0
|
|
8
|
+
image_env: N8N_IMAGE
|
|
9
|
+
network: frontend
|
|
10
|
+
provides:
|
|
11
|
+
- automation
|
|
12
|
+
requires: []
|
|
13
|
+
env:
|
|
14
|
+
N8N_PORT: "5678"
|
|
15
|
+
seeds_gateway_resources: false
|
|
16
|
+
post_setup: []
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# n8n
|
|
2
|
+
|
|
3
|
+
Workflow automation engine with a web editor on `5678`
|
|
4
|
+
(host port `${N8N_PORT}`): http://localhost:${N8N_PORT}.
|
|
5
|
+
|
|
6
|
+
On first visit, n8n walks you through creating the owner account. From a
|
|
7
|
+
workflow you can call the Ignition gateway's HTTP/WebDev endpoints at
|
|
8
|
+
`http://gateway:8088` to read tags or trigger logic.
|
|
9
|
+
|
|
10
|
+
In the mcp-n8n profile (Phase 6) this pairs with the Ignition MCP module so an
|
|
11
|
+
assistant can drive the gateway through n8n.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: {{ image_ref }}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
command: ["--pn=50000", "--autoaccept", "--unsecuretransport"]
|
|
6
|
+
ports:
|
|
7
|
+
- "${OPCUA_SIM_PORT}:50000"
|
|
8
|
+
{%- if networks %}
|
|
9
|
+
networks:
|
|
10
|
+
{%- for net in networks %}
|
|
11
|
+
- {{ net }}
|
|
12
|
+
{%- endfor %}
|
|
13
|
+
{%- endif %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# OPC-UA simulation server - Microsoft OPC-PLC, the mainstream containerized
|
|
2
|
+
# OPC-UA test server (Prosys ships no Docker image). Anonymous, unsecured
|
|
3
|
+
# endpoint suitable for demos.
|
|
4
|
+
name: opcua-sim
|
|
5
|
+
kind: simulator
|
|
6
|
+
summary: Microsoft OPC-PLC OPC-UA simulation server.
|
|
7
|
+
image: mcr.microsoft.com/iotedge/opc-plc:2.9.9
|
|
8
|
+
image_env: OPCUA_SIM_IMAGE
|
|
9
|
+
network: backend
|
|
10
|
+
provides:
|
|
11
|
+
- opcua-server
|
|
12
|
+
requires: []
|
|
13
|
+
env:
|
|
14
|
+
OPCUA_SIM_PORT: "50000"
|
|
15
|
+
seeds_gateway_resources: false
|
|
16
|
+
post_setup:
|
|
17
|
+
- connection: opc-ua-connection
|
|
18
|
+
reason: >-
|
|
19
|
+
The gateway's outbound OPC-UA connection config is file-seedable, but is
|
|
20
|
+
left to post-setup here so the endpoint URL and security mode can be
|
|
21
|
+
confirmed against the running simulator.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# OPC-UA Simulation Server (Microsoft OPC-PLC)
|
|
2
|
+
|
|
3
|
+
An anonymous, unsecured OPC-UA server with simulated nodes, listening on `50000`
|
|
4
|
+
(host port `${OPCUA_SIM_PORT}`).
|
|
5
|
+
|
|
6
|
+
Endpoint from another container: `opc.tcp://opcua-sim:50000`. From the host:
|
|
7
|
+
`opc.tcp://localhost:${OPCUA_SIM_PORT}`.
|
|
8
|
+
|
|
9
|
+
In the Ignition gateway, add an OPC-UA connection to that endpoint with security
|
|
10
|
+
policy `None` and anonymous authentication. The server auto-accepts client
|
|
11
|
+
certificates (`--autoaccept`) so no certificate exchange is needed.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: ${POSTGRES_IMAGE}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
POSTGRES_USER: ${DB_USER}
|
|
8
|
+
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
|
9
|
+
{%- if extra_databases %}
|
|
10
|
+
EXTRA_DATABASES: ${EXTRA_DATABASES}
|
|
11
|
+
{%- endif %}
|
|
12
|
+
{%- if extra_databases %}
|
|
13
|
+
volumes:
|
|
14
|
+
- ./services/{{ name }}/initdb:/docker-entrypoint-initdb.d:ro
|
|
15
|
+
{%- endif %}
|
|
16
|
+
healthcheck:
|
|
17
|
+
test: ["CMD", "pg_isready", "-h", "localhost", "-U", "${DB_USER}"]
|
|
18
|
+
interval: 5s
|
|
19
|
+
timeout: 10s
|
|
20
|
+
retries: 10
|
|
21
|
+
{%- if networks %}
|
|
22
|
+
networks:
|
|
23
|
+
{%- for net in networks %}
|
|
24
|
+
- {{ net }}
|
|
25
|
+
{%- endfor %}
|
|
26
|
+
{%- endif %}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# PostgreSQL - the default Ignition SQL store / historian backend.
|
|
2
|
+
# Provides the sql-database capability Keycloak depends on.
|
|
3
|
+
name: postgres
|
|
4
|
+
kind: database
|
|
5
|
+
summary: PostgreSQL database, the default Ignition historian and SQL store.
|
|
6
|
+
image: postgres:18.1
|
|
7
|
+
image_env: POSTGRES_IMAGE
|
|
8
|
+
network: backend
|
|
9
|
+
provides:
|
|
10
|
+
- sql-database
|
|
11
|
+
- postgres-compatible
|
|
12
|
+
requires: []
|
|
13
|
+
# DB credentials (DB_USER / DB_PASSWORD / DB_HOST) are emitted by the writer's
|
|
14
|
+
# shared database .env section, not here, so every database kind shares one
|
|
15
|
+
# credential vocabulary.
|
|
16
|
+
env: {}
|
|
17
|
+
# Ships a pre-seeded gateway database-connection (config.json + resource.json)
|
|
18
|
+
# plus the internal-secret-provider that holds its password, per the Phase-1
|
|
19
|
+
# matrix db-connection row (file-seedable-config: yes, file-seedable-secret: yes).
|
|
20
|
+
seeds_gateway_resources: true
|
|
21
|
+
post_setup: []
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"connectURL": "jdbc:postgresql://db:5432/ignition",
|
|
3
|
+
"connectionProps": "",
|
|
4
|
+
"connectionResetParams": "",
|
|
5
|
+
"defaultTransactionLevel": "DEFAULT",
|
|
6
|
+
"driver": "PostgreSQL",
|
|
7
|
+
"evictionRate": -1,
|
|
8
|
+
"evictionTests": 3,
|
|
9
|
+
"evictionTime": 1800000,
|
|
10
|
+
"failoverMode": "STANDARD",
|
|
11
|
+
"includeSchemaInTableName": false,
|
|
12
|
+
"password": {
|
|
13
|
+
"data": {
|
|
14
|
+
"providerName": "internal-secret-provider",
|
|
15
|
+
"secretName": "db-password"
|
|
16
|
+
},
|
|
17
|
+
"type": "Referenced"
|
|
18
|
+
},
|
|
19
|
+
"poolInitSize": 0,
|
|
20
|
+
"poolMaxActive": 8,
|
|
21
|
+
"poolMaxIdle": 8,
|
|
22
|
+
"poolMaxWait": 5000,
|
|
23
|
+
"poolMinIdle": 0,
|
|
24
|
+
"slowQueryLogThreshold": 60000,
|
|
25
|
+
"testOnBorrow": true,
|
|
26
|
+
"testOnReturn": false,
|
|
27
|
+
"testWhileIdle": false,
|
|
28
|
+
"translator": "POSTGRES",
|
|
29
|
+
"username": "ignition",
|
|
30
|
+
"validationQuery": "SELECT 1",
|
|
31
|
+
"validationSleepTime": 10000
|
|
32
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scope": "A",
|
|
3
|
+
"description": "Pre-seeded connection to the bundled Postgres service.",
|
|
4
|
+
"version": 1,
|
|
5
|
+
"restricted": false,
|
|
6
|
+
"overridable": true,
|
|
7
|
+
"files": [
|
|
8
|
+
"config.json"
|
|
9
|
+
],
|
|
10
|
+
"attributes": {
|
|
11
|
+
"lastModification": {
|
|
12
|
+
"actor": "admin",
|
|
13
|
+
"timestamp": "2025-10-08T20:07:51Z"
|
|
14
|
+
},
|
|
15
|
+
"uuid": "9727b3a7-bff4-4249-93f5-25f9010886a3",
|
|
16
|
+
"lastModificationSignature": "e09b7a5df3f22e15d47311335de7420e2024239ecf71af85946b2798dba069b3",
|
|
17
|
+
"enabled": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"profile": {
|
|
3
|
+
"type": "internal"
|
|
4
|
+
},
|
|
5
|
+
"settings": {
|
|
6
|
+
"secrets": {
|
|
7
|
+
"db-password": {
|
|
8
|
+
"ciphertext": {
|
|
9
|
+
"ciphertext": "QZshnhoavcjVfg",
|
|
10
|
+
"encrypted_key": "MmT2XEQuLfmKj0dHURyIT0BuTJJMxgE-7W6kZTf5vL4jo9BnWkwxiQ",
|
|
11
|
+
"iv": "7wMQIa5Vdy1QZ0cj",
|
|
12
|
+
"protected": "eyJhbGciOiJBMjU2S1ciLCJlbmMiOiJBMjU2R0NNIiwiaWF0IjoxNzU0NDI5NTI2LCJ6aXAiOiJERUYifQ",
|
|
13
|
+
"tag": "ckxlkktV8u9b_43pjuXCBA"
|
|
14
|
+
},
|
|
15
|
+
"description": "Password for the bundled Postgres connection."
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"scope": "A",
|
|
3
|
+
"description": "",
|
|
4
|
+
"version": 1,
|
|
5
|
+
"restricted": false,
|
|
6
|
+
"overridable": true,
|
|
7
|
+
"files": [
|
|
8
|
+
"config.json"
|
|
9
|
+
],
|
|
10
|
+
"attributes": {
|
|
11
|
+
"lastModification": {
|
|
12
|
+
"actor": "admin",
|
|
13
|
+
"timestamp": "2025-08-05T21:32:06Z"
|
|
14
|
+
},
|
|
15
|
+
"uuid": "cadfe4ea-4f3a-448a-a4b5-c8836a701c41",
|
|
16
|
+
"lastModificationSignature": "74930ea8c842fffac05dc1ae3446dbb60db71c74e88f5bbb45da275b880486e6",
|
|
17
|
+
"enabled": true
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Postgres runs every *.sh in /docker-entrypoint-initdb.d once, on first init.
|
|
3
|
+
# Creates each database named in POSTGRES_EXTRA_DATABASES (comma-separated)
|
|
4
|
+
# beyond the default one Postgres creates for POSTGRES_USER. The resolver sets
|
|
5
|
+
# this to "keycloak" when Keycloak is selected against this database.
|
|
6
|
+
set -e
|
|
7
|
+
|
|
8
|
+
if [ -z "${EXTRA_DATABASES:-}" ]; then
|
|
9
|
+
exit 0
|
|
10
|
+
fi
|
|
11
|
+
|
|
12
|
+
for db in $(echo "${EXTRA_DATABASES}" | tr ',' ' '); do
|
|
13
|
+
echo "Ensuring database '${db}' exists..."
|
|
14
|
+
if ! psql -tAc "SELECT 1 FROM pg_database WHERE datname = '${db}'" --username "${POSTGRES_USER}" | grep -q 1; then
|
|
15
|
+
psql --username "${POSTGRES_USER}" -c "CREATE DATABASE \"${db}\""
|
|
16
|
+
fi
|
|
17
|
+
done
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{{ name }}:
|
|
2
|
+
image: {{ image_ref }}
|
|
3
|
+
hostname: {{ name }}
|
|
4
|
+
container_name: {{ container_name_ref }}
|
|
5
|
+
environment:
|
|
6
|
+
TZ: ${TZ}
|
|
7
|
+
RABBITMQ_DEFAULT_USER: ${RABBITMQ_USER}
|
|
8
|
+
RABBITMQ_DEFAULT_PASS: ${RABBITMQ_PASSWORD}
|
|
9
|
+
ports:
|
|
10
|
+
- "${RABBITMQ_MQTT_PORT}:1883"
|
|
11
|
+
- "${RABBITMQ_MGMT_PORT}:15672"
|
|
12
|
+
volumes:
|
|
13
|
+
- ./services/{{ name }}/enabled_plugins:/etc/rabbitmq/enabled_plugins:ro
|
|
14
|
+
{%- if networks %}
|
|
15
|
+
networks:
|
|
16
|
+
{%- for net in networks %}
|
|
17
|
+
- {{ net }}
|
|
18
|
+
{%- endfor %}
|
|
19
|
+
{%- endif %}
|