├── .gitignore ├── README.md ├── assets ├── compose-up-env.sh ├── compose-up.sh ├── enterprise-change-wd.cast ├── enterprise-change-wd.gif ├── enterprise-compose-up.cast ├── enterprise-compose-up.gif ├── hub-spoke-change-wd.cast ├── hub-spoke-change-wd.gif ├── hub-spoke-compose-up.cast ├── hub-spoke-compose-up.gif ├── iiot-change-wd.cast ├── iiot-change-wd.gif ├── iiot-compose-up.cast ├── iiot-compose-up.gif ├── scale-out-change-wd.cast ├── scale-out-change-wd.gif ├── scale-out-compose-up.cast ├── scale-out-compose-up.gif ├── standard-change-wd.cast ├── standard-change-wd.gif ├── standard-compose-up.cast ├── standard-compose-up.gif └── test.cast ├── enterprise ├── .env ├── README.md ├── docker-compose.yml ├── eam-archive │ └── .gitignore ├── gw-init │ ├── central-gw.gwbk │ ├── gateway.env │ ├── sitea-edge.gwbk │ ├── sitea-gw.gwbk │ └── siteb-gw.gwbk ├── secrets │ ├── db-ignition-password │ ├── db-root-password │ └── gateway-admin-password └── sql-init │ └── setup.sql ├── hub-spoke ├── .env ├── README.md ├── docker-compose.yml ├── gw-backup │ └── .gitignore ├── gw-init │ ├── central-gw.gwbk │ ├── gateway.env │ ├── local1-gw.gwbk │ └── remote1-gw.gwbk ├── secrets │ ├── db-ignition-password │ ├── db-root-password │ └── gateway-admin-password └── sql-init │ └── setup.sql ├── iiot ├── .env ├── README.md ├── docker-compose.yml ├── gw-backup │ └── .gitignore ├── gw-build │ ├── Dockerfile │ ├── base.gwbk │ ├── docker-entrypoint-shim.sh │ ├── edge1.gwbk │ ├── gateway.gwbk │ ├── register-module.sh │ ├── register-password.sh │ └── retrieve-modules.sh ├── gw-init │ └── gateway.env └── secrets │ ├── db-ignition-password │ ├── db-root-password │ └── gateway-admin-password ├── scale-out ├── .env ├── README.md ├── docker-compose.yml ├── gw-backup │ └── .gitignore ├── gw-init │ ├── gateway-fe.gwbk │ └── gateway.env └── secrets │ ├── db-ignition-password │ ├── db-root-password │ └── gateway-admin-password └── standard ├── .env ├── README.md ├── docker-compose.yml ├── gw-backup └── .gitignore ├── gw-init ├── base.gwbk ├── gateway-independent.xml ├── gateway-redundancy.xml ├── gateway.env └── gatewayr-redundancy.xml └── secrets ├── db-ignition-password ├── db-root-password └── gateway-admin-password /.gitignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ignition Architectures with Docker Compose 2 | 3 | ![Ignition 8.1.43](https://img.shields.io/badge/ignition-8.1.43-brightgreen.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAEt2lUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNS41LjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iCiAgICB4bWxuczpleGlmPSJodHRwOi8vbnMuYWRvYmUuY29tL2V4aWYvMS4wLyIKICAgIHhtbG5zOnBob3Rvc2hvcD0iaHR0cDovL25zLmFkb2JlLmNvbS9waG90b3Nob3AvMS4wLyIKICAgIHhtbG5zOnhtcD0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLyIKICAgIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIgogICAgeG1sbnM6c3RFdnQ9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZUV2ZW50IyIKICAgdGlmZjpJbWFnZUxlbmd0aD0iNDgiCiAgIHRpZmY6SW1hZ2VXaWR0aD0iNDgiCiAgIHRpZmY6UmVzb2x1dGlvblVuaXQ9IjIiCiAgIHRpZmY6WFJlc29sdXRpb249IjcyLjAiCiAgIHRpZmY6WVJlc29sdXRpb249IjcyLjAiCiAgIGV4aWY6UGl4ZWxYRGltZW5zaW9uPSI0OCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjQ4IgogICBleGlmOkNvbG9yU3BhY2U9IjEiCiAgIHBob3Rvc2hvcDpDb2xvck1vZGU9IjMiCiAgIHBob3Rvc2hvcDpJQ0NQcm9maWxlPSJzUkdCIElFQzYxOTY2LTIuMSIKICAgeG1wOk1vZGlmeURhdGU9IjIwMjAtMTEtMTVUMjE6MTQ6NDctMDY6MDAiCiAgIHhtcDpNZXRhZGF0YURhdGU9IjIwMjAtMTEtMTVUMjE6MTQ6NDctMDY6MDAiPgogICA8eG1wTU06SGlzdG9yeT4KICAgIDxyZGY6U2VxPgogICAgIDxyZGY6bGkKICAgICAgc3RFdnQ6YWN0aW9uPSJwcm9kdWNlZCIKICAgICAgc3RFdnQ6c29mdHdhcmVBZ2VudD0iQWZmaW5pdHkgUGhvdG8gKE5vdiAgNiAyMDIwKSIKICAgICAgc3RFdnQ6d2hlbj0iMjAyMC0xMS0xNVQyMToxNDo0Ny0wNjowMCIvPgogICAgPC9yZGY6U2VxPgogICA8L3htcE1NOkhpc3Rvcnk+CiAgPC9yZGY6RGVzY3JpcHRpb24+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+cMqVDwAAAYFpQ0NQc1JHQiBJRUM2MTk2Ni0yLjEAACiRdZHPK0RRFMc/ZoiMX8XCwuIlrIYGJTbKTBpqksYog83M82ZGzYzXeyPJVtlOUWLj14K/gK2yVopIycrCmtgwPecaNZI5t3PP537vPad7zwVXJK1n7EofZLI5Kxz0azPRWa36CQ9NuGnAE9Ntc2RyMkRZe7+lQsXrblWr/Ll/zbNg2DpU1AgP66aVEx4TDq3kTMVbwi16KrYgfCLsteSCwjdKjxf5WXGyyJ+KrUg4AK4mYS35i+O/WE9ZGWF5OR2Z9LL+cx/1kjojOz0lsV28DZswQfxojDNKgAF6GZJ5gG766JEVZfJ93/kTLEmuLrPJKhaLJEmRwyvqslQ3JCZEN2SkWVX9/9tXO9HfV6xe54eqR8d57YTqTSjkHefjwHEKh+B+gPNsKX9pHwbfRM+XtI49aFyH04uSFt+Gsw1ovTdjVuxbcou7Egl4OYb6KDRfQe1csWc/+xzdQWRNvuoSdnahS843zn8B7IhnrjeRmuAAAAAJcEhZcwAACxMAAAsTAQCanBgAAAQkSURBVGiBzdrdqxVlFAbwn2YfI2nHsLQuhiAqqCj7IImCEoo+BEWSyiKyhFBOwoRgYAgFJUKUQ2FFRn9AViBoVIQS566LtIu6qCCawDK1RKIxjnm6mDmd3ZyZvWfmnPbZz9We9a5Z73rm/VprvXuWAUMah/PxEtbiLOzHKxgJouR0UX92X73rgTQO5+AjDON8BFiOT/F42TsDRQB34BbMKsjnYEcah1cVXxgYAmkczsZmnF2hMg8risKBIYA7cVcPnWNFwUAQSONwFjbq7s8R7CkKB4IA5uv+9cewJYiS34oNg0LgHdmuU4VDeK+sobja+440Dq/G111UjmBJECW/lDUOwgg81KP95SrnmWECaRwOYX0Xlb3Y2c3GjBHId57NuLhC5Rg2BlFyqpudmRyBIazp0v4sfuxlZM60udMc9yOsaNsdRMm7dYzMyAikcTgXr1X0fwpb6tqaqSm0BheWyEfxYBAl39c1NFMEnqiQ78XHTQz1/SBL43CZLEkp4ndcFkTJySb2+joCaRwGiEuazmB9U+fp/xRagklJiWzafNjGYL8JRDi3IPsWq8vy3TooPQfyU/J63ISj2BdEyd9tOuiwuQQPFMRj2BpESdrW7qQRyJ1/DgdlYe4e7EnjsCrVq4tIVmUYxxjeCqKkNEyui7IptBRbC7LluKdtJ3m14b6C+DCeb2tzHGUEbsU5JfLVU+jnBf8N2v7E2iBKfp2CTZQTOFChuzKfXo2QxuElJocGbwZR8llTW2WYRCCIkkP4oER3SDaVmmJl4fk7bG9hpxRV2+g2lO0Ma5qMQr7whztEJ7EqiJJJ5ZG2qCJwEOtkO0UnbsTcBvYfwbUdz2/jmwbv90QpgSBKxvA+9hWaFmNBHcNpHJ6HpztEn8v2/OJHmRIqT+IgSkZlFeKfO8RDuKam7StwXf57FJt6pYdt0DWUCKLkOJ5E5yncLQ3sxE4T2/FGfNnYuxrouSDzout2bJIRPoHFQZT81eWd2zGSP34SRMm90+BrKXoGc0GUnAmiZLOJGH7IxNSowngtfxQb2rvXG02i0Q0YPzmXVimlcbhQdmqfxrogSn5o715v1CaQ56mPypLum8t08jNim2yURrB7Gnzsiqb5wH68gRsq2i/FKlmgtuL/2HWKaEQgiJIzsoLTwxUqh3E3Hgui5I8p+lYLU0rq0zichwvyxxP9croTrQjkc/0pPIOLcjtH8Sp25SPVF7QtLW7BiwXZArwui5V2TMWpJmgT3y/CT6pvE8kuJL5q7VUDtKlKDOvuPNlC7gvaELi8hs7CFnZboQ2BOvF85ZXQdKPNIt4lK5FUfeVTsiIt/v3zxm04HkTJFy3664rGI5BXEraiLBodrzZ0lseHsAhXtvKwB9qWFnfJ/pgxYiLtPIBlJsc/x2X3XdOaSo7jH8bM+Sebu28XAAAAAElFTkSuQmCC) 4 | 5 | Inductive Automation's Ignition [Architectures](https://inductiveautomation.com/ignition/architectures) implemented with Docker Compose. 6 | 7 | - [Ignition Standard Architecture](standard) - Single Gateway and Database 8 | - [Ignition Scale-Out Architecture](scale-out) - 2 Backend and 1 Frontend Gateway 9 | - [Ignition Hub & Spoke Architecture](hub-spoke) - Central and Remote Site Gateways w/ site-local Database. 10 | - [Ignition Enterprise Architecture](enterprise) - Central and Remote Site Gateways with EAM Configuration and site-local Database. 11 | - [Ignition IIoT Architecture](iiot) - Central and Remote Site Gateways with MQTT/Sparkplug Transport. 12 | 13 | > [!WARNING] 14 | > **These architecture stacks are for demonstration purposes only. Production deployments should be using SSL/TLS for Gateway Web UI and Gateway Network connections!** 15 | 16 | ## Prerequisites 17 | 18 | To launch these architecture examples, you'll need to have Docker Engine and Docker Compose installed. These are available as part of [Docker Desktop](https://www.docker.com/products/docker-desktop). You can also install [Docker Engine](https://docs.docker.com/engine/install/) directly on Linux and follow up with [Compose V2 CLI plugin](https://docs.docker.com/compose/cli-command/#install-on-linux). 19 | 20 | Once you've got Docker ready to go, click one of the architecture links up top to get started! 21 | 22 | ## Common Configuration 23 | 24 | Each of the Compose solutions in this repository leverage some common configurability. 25 | 26 | - `.env` file - This contains some environment variables that will be loaded in by Docker Compose. Variables such as `COMPOSE_PROFILES` can be used to enable some optional functionality (such as redundancy) in the solution. Additionally, global settings such as the `IGNITION_VERSION` for the image tag can be defined here. 27 | 28 | - `docker-compose.yml` - This is the YAML file that defines the containers and associated configuration for the architecture. 29 | 30 | - `secrets` folder - **⚠️ WARNING: These secrets exist in-repo for demo purposes only. Never commit your secrets to source control!** This folder contains secrets that are mapped into a given container and used for setting up credentials. The files here are referenced within the `secrets:` keys of the `docker-compose.yml`. Note that the gateway admin password of `password` can be updated by uncommenting the `GATEWAY_ADMIN_*` environment variables in `gw-init/gateway.env` prior to bringing up a given architecture solution. 31 | 32 | - `gw-init` folder - This folder contains seed files for the solution that are sourced from the `docker-compose.yml` file. Items such as gateway backups, gateway network keystores/identifiers, and environment files are used when launching the solution. 33 | 34 | - `gw-backup` folder - Sub-folders under here may be bind-mounted into the various containers and used as the target for scheduled gateway backups. 35 | 36 | - `gw-build` folder - If this folder is present, it is used to build a derived image as part of the solution. Custom functionality such as third-party module bundling can be layered onto the base `inductiveautomation/ignition` image. The derived image is then automatically used to launch containers in the solution. 37 | 38 | - `sql-init` folder - Many database containers allow some pre-configuration scripts to be executed on first-launch. If this folder is present, the database server container may stage schemas/users on startup to provide the required configuration for the connected gateways. 39 | -------------------------------------------------------------------------------- /assets/compose-up-env.sh: -------------------------------------------------------------------------------- 1 | . ~/.bashrc 2 | echo -n "${PS1@P}" 3 | echo ${INDIRECT_CMD} | pv -qL 10 4 | eval "${INDIRECT_CMD}" 5 | echo -n "${PS1@P}" 6 | sleep 2 7 | echo 8 | exit 0 9 | -------------------------------------------------------------------------------- /assets/compose-up.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | if [ "$(basename ${PWD})" != "assets" ]; then 3 | echo "Must run from within 'assets' sub-folder" 4 | exit 1 5 | fi 6 | 7 | for arch in standard scale-out hub-spoke enterprise iiot; do 8 | cast_file="${arch}-compose-up.cast" 9 | gif_file="${cast_file%.*}.gif" 10 | if [ -f "${cast_file}" ] || [ -f "${gif_file}" ]; then 11 | echo "files exist for $arch, skipping" 12 | continue 13 | fi 14 | pushd "../${arch}" 15 | export INDIRECT_CMD="docker-compose up -d" 16 | asciinema rec -i 2.0 -e SHELL,TERM,INDIRECT_CMD -c "PS1='\e[1;36m\w\e[m> ' bash --init-file ../assets/compose-up-env.sh" "../assets/${cast_file}" 17 | docker-compose down -v 18 | popd 19 | cast_lines="$(asciinema play ${cast_file} | wc -l)" 20 | asciicast2gif -S 2 -h $((cast_lines+2)) "${cast_file}" "${gif_file}" 21 | done 22 | 23 | -------------------------------------------------------------------------------- /assets/enterprise-change-wd.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 13, "timestamp": 1634583136, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.017573, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples\u001b[m> "] 3 | [0.880864, "o", "c"] 4 | [0.948339, "o", "d"] 5 | [1.084021, "o", " "] 6 | [1.39948, "o", "e"] 7 | [1.555495, "o", "n"] 8 | [1.645627, "o", "t"] 9 | [1.814696, "o", "e"] 10 | [1.882091, "o", "r"] 11 | [2.061683, "o", "p"] 12 | [2.231939, "o", "rise/"] 13 | [3.254603, "o", "\r\n\u001b[?2004l\r"] 14 | [3.254871, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples/enterprise\u001b[m> "] 15 | [4.33483, "o", "d"] 16 | [4.390708, "o", "o"] 17 | [4.447844, "o", "c"] 18 | [4.559344, "o", "k"] 19 | [4.604691, "o", "e"] 20 | [4.672284, "o", "r"] 21 | [4.728275, "o", "-"] 22 | [4.844147, "o", "c"] 23 | [4.943178, "o", "o"] 24 | [4.986906, "o", "m"] 25 | [5.065865, "o", "p"] 26 | [5.144955, "o", "o"] 27 | [5.234205, "o", "s"] 28 | [5.290558, "o", "e"] 29 | [5.404477, "o", " "] 30 | [5.888269, "o", "."] 31 | [6.033229, "o", "."] 32 | [6.203295, "o", "."] 33 | [7.608537, "o", ""] 34 | -------------------------------------------------------------------------------- /assets/enterprise-change-wd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/enterprise-change-wd.gif -------------------------------------------------------------------------------- /assets/enterprise-compose-up.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 32, "timestamp": 1634591252, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color", "INDIRECT_CMD": "docker-compose up -d"}} 2 | [0.020051, "o", "\u001b[1;36m~/Development/ignition-examples/enterprise\u001b[m> "] 3 | [0.025135, "o", "d"] 4 | [0.213975, "o", "o"] 5 | [0.306775, "o", "c"] 6 | [0.399087, "o", "k"] 7 | [0.490423, "o", "e"] 8 | [0.585385, "o", "r"] 9 | [0.677973, "o", "-"] 10 | [0.772134, "o", "c"] 11 | [0.865007, "o", "o"] 12 | [0.956077, "o", "m"] 13 | [1.047636, "o", "p"] 14 | [1.139517, "o", "o"] 15 | [1.232906, "o", "s"] 16 | [1.325874, "o", "e"] 17 | [1.513984, "o", " "] 18 | [1.608703, "o", "u"] 19 | [1.702258, "o", "p"] 20 | [1.796497, "o", " "] 21 | [1.886628, "o", "-"] 22 | [1.977055, "o", "d"] 23 | [2.068757, "o", "\r\n"] 24 | [2.487892, "o", "Creating network \"enterprise_corporate\" with the default driver\r\n"] 25 | [2.529778, "o", "Creating network \"enterprise_sitea\" with the default driver\r\n"] 26 | [2.572539, "o", "Creating network \"enterprise_siteb\" with the default driver\r\n"] 27 | [2.615409, "o", "Creating volume \"enterprise_central-gw-data\" with default driver\r\n"] 28 | [2.621248, "o", "Creating volume \"enterprise_sitea-gw-data\" with default driver\r\n"] 29 | [2.627274, "o", "Creating volume \"enterprise_sitea-edge-data\" with default driver\r\n"] 30 | [2.633793, "o", "Creating volume \"enterprise_siteb-gw-data\" with default driver\r\n"] 31 | [2.639647, "o", "Creating volume \"enterprise_db-data\" with default driver\r\n"] 32 | [2.733913, "o", "Creating enterprise_siteb-gw_1 ... \r\r\n"] 33 | [2.736337, "o", "Creating enterprise_sitea-edge_1 ... \r\r\n"] 34 | [2.736945, "o", "Creating enterprise_db_1 ... \r\r\n"] 35 | [2.737625, "o", "Creating enterprise_sitea-gw_1 ... \r\r\n"] 36 | [2.737911, "o", "Creating enterprise_central-gw_1 ... \r\r\n"] 37 | [3.433496, "o", "\u001b[3A\u001b[2K\rCreating enterprise_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[3B"] 38 | [3.556561, "o", "\u001b[2A\u001b[2K\rCreating enterprise_sitea-gw_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 39 | [3.813338, "o", "\u001b[4A\u001b[2K\rCreating enterprise_sitea-edge_1 ... \u001b[32mdone\u001b[0m\r\u001b[4B"] 40 | [3.8693, "o", "\u001b[5A\u001b[2K\rCreating enterprise_siteb-gw_1 ... \u001b[32mdone\u001b[0m\r\u001b[5B"] 41 | [3.929002, "o", "\u001b[1A\u001b[2K\rCreating enterprise_central-gw_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 42 | [4.009492, "o", "\u001b[1;36m~/Development/ignition-examples/enterprise\u001b[m> "] 43 | [6.01493, "o", "\r\n"] 44 | -------------------------------------------------------------------------------- /assets/enterprise-compose-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/enterprise-compose-up.gif -------------------------------------------------------------------------------- /assets/hub-spoke-change-wd.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 13, "timestamp": 1634583164, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.018274, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples\u001b[m> "] 3 | [0.897885, "o", "c"] 4 | [1.000338, "o", "d"] 5 | [1.088843, "o", " "] 6 | [1.302881, "o", "h"] 7 | [1.406471, "o", "u"] 8 | [1.449004, "o", "b"] 9 | [2.204207, "o", "-"] 10 | [2.461489, "o", "s"] 11 | [2.552836, "o", "p"] 12 | [2.822361, "o", "oke/"] 13 | [3.690899, "o", "\r\n\u001b[?2004l\r"] 14 | [3.691123, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples/hub-spoke\u001b[m> "] 15 | [4.182659, "o", "d"] 16 | [4.284479, "o", "o"] 17 | [4.373808, "o", "c"] 18 | [4.486276, "o", "k"] 19 | [4.555254, "o", "e"] 20 | [4.635032, "o", "r"] 21 | [4.735001, "o", "-"] 22 | [4.846457, "o", "c"] 23 | [4.925227, "o", "o"] 24 | [5.004415, "o", "m"] 25 | [5.082721, "o", "p"] 26 | [5.18404, "o", "o"] 27 | [5.251947, "o", "s"] 28 | [5.307809, "o", "e"] 29 | [5.397879, "o", " "] 30 | [5.510755, "o", "."] 31 | [5.679171, "o", "."] 32 | [5.870232, "o", "."] 33 | [7.705041, "o", ""] 34 | -------------------------------------------------------------------------------- /assets/hub-spoke-change-wd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/hub-spoke-change-wd.gif -------------------------------------------------------------------------------- /assets/hub-spoke-compose-up.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 32, "timestamp": 1634591221, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color", "INDIRECT_CMD": "docker-compose up -d"}} 2 | [0.019023, "o", "\u001b[1;36m~/Development/ignition-examples/hub-spoke\u001b[m> "] 3 | [0.024009, "o", "d"] 4 | [0.207306, "o", "o"] 5 | [0.299548, "o", "c"] 6 | [0.394571, "o", "k"] 7 | [0.489525, "o", "e"] 8 | [0.579649, "o", "r"] 9 | [0.67218, "o", "-"] 10 | [0.762894, "o", "c"] 11 | [0.856983, "o", "o"] 12 | [0.950356, "o", "m"] 13 | [1.040709, "o", "p"] 14 | [1.131917, "o", "o"] 15 | [1.226892, "o", "s"] 16 | [1.411786, "o", "e"] 17 | [1.504542, "o", " "] 18 | [1.598388, "o", "u"] 19 | [1.690518, "o", "p"] 20 | [1.784973, "o", " "] 21 | [1.875264, "o", "-"] 22 | [1.965526, "o", "d"] 23 | [2.056474, "o", "\r\n"] 24 | [2.463607, "o", "Creating network \"hub-spoke_centralnet\" with the default driver\r\n"] 25 | [2.507484, "o", "Creating network \"hub-spoke_local1net\" with the default driver\r\n"] 26 | [2.548653, "o", "Creating network \"hub-spoke_remote1net\" with the default driver\r\n"] 27 | [2.59117, "o", "Creating volume \"hub-spoke_central-gw-data\" with default driver\r\n"] 28 | [2.596904, "o", "Creating volume \"hub-spoke_local1-gw-data\" with default driver\r\n"] 29 | [2.602413, "o", "Creating volume \"hub-spoke_remote1-gw-data\" with default driver\r\n"] 30 | [2.608875, "o", "Creating volume \"hub-spoke_db-data\" with default driver\r\n"] 31 | [2.715768, "o", "Creating hub-spoke_remote1-gw_1 ... \r\r\n"] 32 | [2.716571, "o", "Creating hub-spoke_local1-gw_1 ... \r\r\n"] 33 | [2.717638, "o", "Creating hub-spoke_central-gw_1 ... \r\r\n"] 34 | [2.718518, "o", "Creating hub-spoke_mailhog_1 ... \r\r\n"] 35 | [2.719395, "o", "Creating hub-spoke_db_1 ... \r\r\n"] 36 | [3.46631, "o", "\u001b[5A\u001b[2K\r"] 37 | [3.466693, "o", "Creating hub-spoke_remote1-gw_1 ... \u001b[32mdone\u001b[0m\r"] 38 | [3.466834, "o", "\u001b[5B"] 39 | [3.466902, "o", "\u001b[2A\u001b[2K\r"] 40 | [3.467081, "o", "Creating hub-spoke_mailhog_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 41 | [3.806162, "o", "\u001b[4A\u001b[2K\rCreating hub-spoke_local1-gw_1 ... \u001b[32mdone\u001b[0m\r\u001b[4B"] 42 | [3.918816, "o", "\u001b[1A\u001b[2K\rCreating hub-spoke_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 43 | [3.996796, "o", "\u001b[3A\u001b[2K\rCreating hub-spoke_central-gw_1 ... \u001b[32mdone\u001b[0m\r\u001b[3B"] 44 | [4.079546, "o", "\u001b[1;36m~/Development/ignition-examples/hub-spoke\u001b[m> "] 45 | [6.088013, "o", "\r\n"] 46 | -------------------------------------------------------------------------------- /assets/hub-spoke-compose-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/hub-spoke-compose-up.gif -------------------------------------------------------------------------------- /assets/iiot-change-wd.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 13, "timestamp": 1634583101, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.017542, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples\u001b[m> "] 3 | [0.857585, "o", "c"] 4 | [0.925787, "o", "d"] 5 | [1.026065, "o", " "] 6 | [1.296776, "o", "i"] 7 | [1.431333, "o", "i"] 8 | [1.532522, "o", "o"] 9 | [1.667642, "o", "t/"] 10 | [2.151097, "o", "\r\n"] 11 | [2.151199, "o", "\u001b[?2004l\r"] 12 | [2.151416, "o", "\u001b[?2004h"] 13 | [2.151459, "o", "\u001b[1;36m~/Development/ignition-examples/iiot\u001b[m> "] 14 | [4.210104, "o", "d"] 15 | [4.267924, "o", "o"] 16 | [4.378708, "o", "c"] 17 | [4.468619, "o", "k"] 18 | [4.536919, "o", "e"] 19 | [4.55905, "o", "r"] 20 | [4.648658, "o", "-"] 21 | [4.738649, "o", "c"] 22 | [4.85114, "o", "o"] 23 | [4.941683, "o", "m"] 24 | [5.023339, "o", "p"] 25 | [5.098471, "o", "o"] 26 | [5.188851, "o", "s"] 27 | [5.23385, "o", "e"] 28 | [5.325046, "o", " "] 29 | [5.380757, "o", "."] 30 | [5.57138, "o", "."] 31 | [5.763493, "o", "."] 32 | [7.877965, "o", ""] 33 | -------------------------------------------------------------------------------- /assets/iiot-change-wd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/iiot-change-wd.gif -------------------------------------------------------------------------------- /assets/iiot-compose-up.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 32, "timestamp": 1634591283, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color", "INDIRECT_CMD": "docker-compose up -d"}} 2 | [0.020941, "o", "\u001b[1;36m~/Development/ignition-examples/iiot\u001b[m> "] 3 | [0.025959, "o", "d"] 4 | [0.209362, "o", "o"] 5 | [0.299548, "o", "c"] 6 | [0.392699, "o", "k"] 7 | [0.483602, "o", "e"] 8 | [0.57734, "o", "r"] 9 | [0.667669, "o", "-"] 10 | [0.76008, "o", "c"] 11 | [0.854379, "o", "o"] 12 | [0.949354, "o", "m"] 13 | [1.040189, "o", "p"] 14 | [1.133715, "o", "o"] 15 | [1.226749, "o", "s"] 16 | [1.411988, "o", "e"] 17 | [1.503271, "o", " "] 18 | [1.596691, "o", "u"] 19 | [1.691683, "o", "p"] 20 | [1.785902, "o", " "] 21 | [1.876039, "o", "-"] 22 | [1.97007, "o", "d"] 23 | [2.065236, "o", "\r\n"] 24 | [2.45771, "o", "Creating network \"iiot_default\" with the default driver\r\n"] 25 | [2.499114, "o", "Creating volume \"iiot_gateway-data\" with default driver\r\n"] 26 | [2.504654, "o", "Creating volume \"iiot_gateway-edge1-data\" with default driver\r\n"] 27 | [2.510255, "o", "Creating volume \"iiot_db-data\" with default driver\r\n"] 28 | [2.575178, "o", "Creating iiot_db_1 ... \r\r\n"] 29 | [2.576434, "o", "Creating iiot_gateway-edge1_1 ... \r\r\n"] 30 | [2.576849, "o", "Creating iiot_gateway_1 ... \r\r\n"] 31 | [3.087161, "o", "\u001b[3A\u001b[2K\rCreating iiot_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[3B"] 32 | [3.143826, "o", "\u001b[1A\u001b[2K\rCreating iiot_gateway_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 33 | [3.191248, "o", "\u001b[2A\u001b[2K\r"] 34 | [3.191451, "o", "Creating iiot_gateway-edge1_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 35 | [3.261479, "o", "\u001b[1;36m~/Development/ignition-examples/iiot\u001b[m> "] 36 | [5.266439, "o", "\r\n"] 37 | -------------------------------------------------------------------------------- /assets/iiot-compose-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/iiot-compose-up.gif -------------------------------------------------------------------------------- /assets/scale-out-change-wd.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 13, "timestamp": 1634583197, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.01726, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples\u001b[m> "] 3 | [1.02991, "o", "c"] 4 | [1.093763, "o", "d"] 5 | [1.217389, "o", " "] 6 | [1.499207, "o", "s"] 7 | [1.588675, "o", "c"] 8 | [1.657561, "o", "a"] 9 | [1.904075, "o", "le-out/"] 10 | [2.792648, "o", "\r\n\u001b[?2004l\r"] 11 | [2.792849, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples/scale-out\u001b[m> "] 12 | [3.31003, "o", "d"] 13 | [3.388481, "o", "o"] 14 | [3.478859, "o", "c"] 15 | [3.569127, "o", "k"] 16 | [3.6251, "o", "e"] 17 | [3.681022, "o", "r"] 18 | [3.907583, "o", "-"] 19 | [4.018705, "o", "c"] 20 | [4.097482, "o", "o"] 21 | [4.176153, "o", "m"] 22 | [4.288842, "o", "p"] 23 | [4.357442, "o", "o"] 24 | [4.402632, "o", "s"] 25 | [4.447294, "o", "e"] 26 | [4.560131, "o", " "] 27 | [5.166483, "o", "."] 28 | [5.302468, "o", "."] 29 | [5.447682, "o", "."] 30 | [6.7755, "o", ""] 31 | -------------------------------------------------------------------------------- /assets/scale-out-change-wd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/scale-out-change-wd.gif -------------------------------------------------------------------------------- /assets/scale-out-compose-up.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 32, "timestamp": 1634591192, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color", "INDIRECT_CMD": "docker-compose up -d"}} 2 | [0.019946, "o", "\u001b[1;36m~/Development/ignition-examples/scale-out\u001b[m> "] 3 | [0.024766, "o", "d"] 4 | [0.207642, "o", "o"] 5 | [0.301592, "o", "c"] 6 | [0.395817, "o", "k"] 7 | [0.487087, "o", "e"] 8 | [0.580058, "o", "r"] 9 | [0.670992, "o", "-"] 10 | [0.762579, "o", "c"] 11 | [0.856793, "o", "o"] 12 | [0.951805, "o", "m"] 13 | [1.043977, "o", "p"] 14 | [1.138278, "o", "o"] 15 | [1.228594, "o", "s"] 16 | [1.417611, "o", "e"] 17 | [1.512457, "o", " "] 18 | [1.604664, "o", "u"] 19 | [1.699383, "o", "p"] 20 | [1.792201, "o", " "] 21 | [1.882529, "o", "-"] 22 | [1.973338, "o", "d"] 23 | [2.06679, "o", "\r\n"] 24 | [2.45414, "o", "Creating network \"scale-out_default\" with the default driver\r\n"] 25 | [2.495703, "o", "Creating volume \"scale-out_gateway-fe-data\" with default driver\r\n"] 26 | [2.501738, "o", "Creating volume \"scale-out_gateway-tag1-data\" with default driver\r\n"] 27 | [2.507785, "o", "Creating volume \"scale-out_gateway-tag2-data\" with default driver\r\n"] 28 | [2.514281, "o", "Creating volume \"scale-out_db-data\" with default driver\r\n"] 29 | [2.598586, "o", "Creating scale-out_gateway-tag1_1 ... \r\r\n"] 30 | [2.601108, "o", "Creating scale-out_gateway-tag2_1 ... \r\r\n"] 31 | [2.601501, "o", "Creating scale-out_db_1 ... \r\r\n"] 32 | [2.601772, "o", "Creating scale-out_gateway-fe_1 ... \r\r\n"] 33 | [3.230231, "o", "\u001b[4A\u001b[2K\rCreating scale-out_gateway-tag1_1 ... \u001b[32mdone\u001b[0m\r\u001b[4B"] 34 | [3.289464, "o", "\u001b[1A\u001b[2K\rCreating scale-out_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 35 | [3.290254, "o", "\u001b[3A\u001b[2K\rCreating scale-out_gateway-tag2_1 ... \u001b[32mdone\u001b[0m\r\u001b[3B"] 36 | [3.372133, "o", "\u001b[2A\u001b[2K\rCreating scale-out_gateway-fe_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 37 | [3.443157, "o", "\u001b[1;36m~/Development/ignition-examples/scale-out\u001b[m> "] 38 | [5.449986, "o", "\r\n"] 39 | -------------------------------------------------------------------------------- /assets/scale-out-compose-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/scale-out-compose-up.gif -------------------------------------------------------------------------------- /assets/standard-change-wd.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 13, "timestamp": 1634583043, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.01763, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples\u001b[m> "] 3 | [1.112626, "o", "c"] 4 | [1.202133, "o", "d"] 5 | [1.315942, "o", " "] 6 | [1.449587, "o", "s"] 7 | [1.52807, "o", "t"] 8 | [1.674589, "o", "a"] 9 | [1.809351, "o", "n"] 10 | [1.865661, "o", "d"] 11 | [2.000529, "o", "a"] 12 | [2.047027, "o", "r"] 13 | [2.236906, "o", "d"] 14 | [2.552056, "o", "\r\n\u001b[?2004l\r"] 15 | [2.552291, "o", "\u001b[?2004h\u001b[1;36m~/Development/ignition-examples/standard\u001b[m> "] 16 | [2.889241, "o", "d"] 17 | [2.968073, "o", "o"] 18 | [3.058314, "o", "c"] 19 | [3.159581, "o", "k"] 20 | [3.22834, "o", "e"] 21 | [3.260548, "o", "r"] 22 | [3.329688, "o", "-"] 23 | [3.45273, "o", "c"] 24 | [3.544539, "o", "o"] 25 | [3.62063, "o", "m"] 26 | [3.734498, "o", "p"] 27 | [3.824489, "o", "o"] 28 | [3.901884, "o", "s"] 29 | [3.946883, "o", "e"] 30 | [4.025543, "o", " "] 31 | [4.126891, "o", "."] 32 | [4.295634, "o", "."] 33 | [4.464334, "o", "."] 34 | [5.578667, "o", ""] 35 | -------------------------------------------------------------------------------- /assets/standard-change-wd.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/standard-change-wd.gif -------------------------------------------------------------------------------- /assets/standard-compose-up.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 132, "height": 32, "timestamp": 1634591165, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color", "INDIRECT_CMD": "docker-compose up -d"}} 2 | [0.017469, "o", "\u001b[1;36m~/Development/ignition-examples/standard\u001b[m> "] 3 | [0.02233, "o", "d"] 4 | [0.207517, "o", "o"] 5 | [0.297929, "o", "c"] 6 | [0.392886, "o", "k"] 7 | [0.485424, "o", "e"] 8 | [0.575619, "o", "r"] 9 | [0.665686, "o", "-"] 10 | [0.756319, "o", "c"] 11 | [0.847441, "o", "o"] 12 | [0.937509, "o", "m"] 13 | [1.031657, "o", "p"] 14 | [1.125549, "o", "o"] 15 | [1.307907, "o", "s"] 16 | [1.398262, "o", "e"] 17 | [1.491334, "o", " "] 18 | [1.581645, "o", "u"] 19 | [1.671705, "o", "p"] 20 | [1.764314, "o", " "] 21 | [1.857762, "o", "-"] 22 | [1.950633, "o", "d"] 23 | [2.041705, "o", "\r\n"] 24 | [2.423171, "o", "Creating network \"standard_default\" with the default driver\r\n"] 25 | [2.463927, "o", "Creating volume \"standard_gateway-data\" with default driver\r\n"] 26 | [2.470099, "o", "Creating volume \"standard_db-data\" with default driver\r\n"] 27 | [2.521553, "o", "Creating standard_gateway_1 ... \r\r\n"] 28 | [2.521921, "o", "Creating standard_db_1 ... \r\r\n"] 29 | [2.922997, "o", "\u001b[1A\u001b[2K\rCreating standard_db_1 ... \u001b[32mdone\u001b[0m\r\u001b[1B"] 30 | [3.028611, "o", "\u001b[2A\u001b[2K\rCreating standard_gateway_1 ... \u001b[32mdone\u001b[0m\r\u001b[2B"] 31 | [3.093271, "o", "\u001b[1;36m~/Development/ignition-examples/standard\u001b[m> "] 32 | [5.097301, "o", "\r\n"] 33 | -------------------------------------------------------------------------------- /assets/standard-compose-up.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/assets/standard-compose-up.gif -------------------------------------------------------------------------------- /assets/test.cast: -------------------------------------------------------------------------------- 1 | {"version": 2, "width": 149, "height": 24, "timestamp": 1634584175, "idle_time_limit": 2.0, "env": {"SHELL": "/bin/zsh", "TERM": "xterm-256color"}} 2 | [0.017246, "o", "foo\r\n"] 3 | -------------------------------------------------------------------------------- /enterprise/.env: -------------------------------------------------------------------------------- 1 | # Place environment variable overrides here to be read in by Docker Compose 2 | IGNITION_VERSION=8.1.43 3 | # Default max memory for each of the enterprise gateways 4 | GATEWAY_MAX_MEMORY=512 5 | -------------------------------------------------------------------------------- /enterprise/README.md: -------------------------------------------------------------------------------- 1 | # Ignition Enterprise Architecture 2 | 3 | With the Ignition enterprise architecture, you can send data from independent local sites and remote sites up to a centralized corporate site and to cloud services. 4 | 5 | ![Ignition Enterprise Architecture Diagram](https://inductiveautomation.com/static/images/architectures/enterprise-scada-architecture.509ea1a50cff.png) 6 | 7 | The Ignition enterprise architecture enables you to create a connected system while also securing data at multiple levels. Connect multiple sites to a central corporate server, and use Ignition Edge to ensure data from critical assets is never compromised. Connecting through a DMZ provides an additional layer of security for transferring and accessing data. The Ignition Gateway connects easily to cloud services like Microsoft Azure, AWS, IBM Cloud, and Google Cloud for storage and analytics. 8 | 9 | ## Configure 10 | 11 | See [common configuration](../README.md#common-configuration) for specifics on files/folders in this solution. 12 | 13 | ## Enable 14 | 15 | First, make sure your working directory is `enterprise`: 16 | 17 | ![Change Working Directory](../assets/enterprise-change-wd.gif) 18 | 19 | To bring up the solution: 20 | 21 | docker-compose up -d 22 | 23 | ![Bringing up the solution](../assets/enterprise-compose-up.gif) 24 | 25 | ## Connect 26 | 27 | Once the solution has been launched, you can begin to access the services at: 28 | 29 | - Central Ignition Gateway - http://central-gw.localtest.me:8088 30 | - Site A Gateway - http://sitea-gw.localtest.me:8089 31 | - Site A Edge Gateway - http://sitea-edge-gw.localtest.me:8090 32 | - Site B Gateway - http://remote1-gw.localtest.me:8091 33 | - MariaDB Database - `localhost:3306` 34 | 35 | Default admin credentials for Ignition Gateways are `admin` / `password`. Default admin credentials for MariaDB are `root` / `ignition`. 36 | 37 | ## Monitor 38 | 39 | If you'd like to monitor the logs of any of the services, you can use the following: 40 | 41 | docker-compose logs --tail=250 -f 42 | 43 | ... where `` is one of the named services from `docker-compose.yml`, e.g. `gateway` or `db`. Omit the `` to start viewing logs from all services. Use `CTRL-C` to break out of the log view. 44 | 45 | ## Shutdown 46 | 47 | To shutdown the containers within the solution: 48 | 49 | docker-compose down 50 | 51 | Note that this will leave data volumes intact on your system so that bringing the solution back online will return to the previous state. If you want to also remove the data volumes and return the solution to the original state, add a `-v` flag to the *down* command. -------------------------------------------------------------------------------- /enterprise/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Enterprise Architecture Example 2 | # https://inductiveautomation.com/ignition/architectures 3 | # https://inductiveautomation.com/static/pdf/IgnitionArchitecture-Enterprise.pdf 4 | --- 5 | x-default-logging: 6 | &default-logging 7 | logging: 8 | options: 9 | max-size: '100m' 10 | max-file: '5' 11 | driver: json-file 12 | 13 | x-ignition-opts: 14 | &ignition-opts 15 | <<: *default-logging 16 | image: inductiveautomation/ignition:${IGNITION_VERSION:-latest} 17 | env_file: gw-init/gateway.env 18 | secrets: 19 | - gateway-admin-password 20 | 21 | services: 22 | central-gw: 23 | <<: *ignition-opts 24 | hostname: central-gw 25 | ports: 26 | - 8088:8088 27 | - 8043:8043 28 | command: > 29 | -n Central 30 | -m ${GATEWAY_MAX_MEMORY:-512} 31 | -a central-gw.localtest.me 32 | -h 8088 33 | -s 8043 34 | -r base.gwbk 35 | environment: 36 | GATEWAY_NETWORK_REQUIRESSL: false 37 | GATEWAY_NETWORK_SECURITYPOLICY: SpecifiedList 38 | GATEWAY_NETWORK_WHITELIST: sitea,siteb 39 | EAM_SETUP_INSTALLSELECTION: Controller 40 | EAM_CONTROLLER_ARCHIVELOCATION: Manual 41 | EAM_CONTROLLER_ARCHIVEPATH: /eam-archive 42 | EAM_CONTROLLER_DATASOURCE: central 43 | networks: 44 | - corporate 45 | - sitea 46 | - siteb 47 | volumes: 48 | - central-gw-data:/usr/local/bin/ignition/data 49 | - ./eam-archive:/eam-archive 50 | - ./gw-init/central-gw.gwbk:/usr/local/bin/ignition/base.gwbk 51 | 52 | sitea-gw: 53 | <<: *ignition-opts 54 | hostname: sitea-gw 55 | ports: 56 | - 8089:8088 57 | - 8044:8043 58 | command: > 59 | -n SiteA 60 | -m ${GATEWAY_MAX_MEMORY:-512} 61 | -a sitea-gw.localtest.me 62 | -h 8089 63 | -s 8044 64 | -r base.gwbk 65 | environment: 66 | GATEWAY_NETWORK_REQUIRESSL: false 67 | GATEWAY_NETWORK_SECURITYPOLICY: SpecifiedList 68 | GATEWAY_NETWORK_WHITELIST: sitea-edge 69 | GATEWAY_NETWORK_0_HOST: central-gw 70 | GATEWAY_NETWORK_0_PORT: 8088 71 | GATEWAY_NETWORK_0_ENABLESSL: false 72 | GATEWAY_NETWORK_0_PINGRATE: 5000 73 | EAM_SETUP_INSTALLSELECTION: Agent 74 | EAM_AGENT_CONTROLLERSERVERNAME: Central 75 | networks: 76 | - corporate 77 | - sitea 78 | volumes: 79 | - sitea-gw-data:/usr/local/bin/ignition/data 80 | - ./gw-init/sitea-gw.gwbk:/usr/local/bin/ignition/base.gwbk 81 | 82 | sitea-edge: 83 | <<: *ignition-opts 84 | hostname: sitea-edge 85 | ports: 86 | - 8090:8088 87 | - 8045:8043 88 | command: > 89 | -n SiteA-Edge 90 | -m ${GATEWAY_MAX_MEMORY:-512} 91 | -a sitea-edge.localtest.me 92 | -h 8090 93 | -s 8045 94 | -r /usr/local/bin/ignition/base.gwbk 95 | environment: 96 | IGNITION_EDITION: edge 97 | GATEWAY_NETWORK_0_HOST: sitea-gw 98 | GATEWAY_NETWORK_0_PORT: 8088 99 | GATEWAY_NETWORK_0_ENABLESSL: false 100 | GATEWAY_NETWORK_0_PINGRATE: 5000 101 | EAM_SETUP_INSTALLSELECTION: Agent 102 | EAM_AGENT_CONTROLLERSERVERNAME: Central 103 | networks: 104 | - sitea 105 | volumes: 106 | - sitea-edge-data:/usr/local/bin/ignition/data 107 | - ./gw-init/sitea-edge.gwbk:/usr/local/bin/ignition/base.gwbk 108 | 109 | siteb-gw: 110 | <<: *ignition-opts 111 | hostname: siteb-gw 112 | ports: 113 | - 8091:8088 114 | - 8046:8043 115 | command: > 116 | -n SiteB 117 | -m ${GATEWAY_MAX_MEMORY:-512} 118 | -a siteb-gw.localtest.me 119 | -h 8091 120 | -s 8046 121 | -r /usr/local/bin/ignition/base.gwbk 122 | networks: 123 | - corporate 124 | - siteb 125 | environment: 126 | GATEWAY_NETWORK_0_HOST: central-gw 127 | GATEWAY_NETWORK_0_PORT: 8088 128 | GATEWAY_NETWORK_0_ENABLESSL: false 129 | GATEWAY_NETWORK_0_PINGRATE: 5000 130 | EAM_SETUP_INSTALLSELECTION: Agent 131 | EAM_AGENT_CONTROLLERSERVERNAME: Central 132 | volumes: 133 | - siteb-gw-data:/usr/local/bin/ignition/data 134 | - ./gw-init/siteb-gw.gwbk:/usr/local/bin/ignition/base.gwbk 135 | 136 | db: 137 | <<: *default-logging 138 | image: mariadb:${MARIADB_VERSION:-latest} 139 | ports: 140 | - 3306:3306 141 | environment: 142 | MARIADB_USER: ignition 143 | MARIADB_PASSWORD_FILE: /run/secrets/db-ignition-password 144 | MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db-root-password 145 | networks: 146 | corporate: 147 | aliases: 148 | - central-db 149 | sitea: 150 | aliases: 151 | - sitea-db 152 | siteb: 153 | aliases: 154 | - siteb-db 155 | secrets: 156 | - db-root-password 157 | - db-ignition-password 158 | volumes: 159 | - db-data:/var/lib/mysql 160 | - ./sql-init:/docker-entrypoint-initdb.d 161 | 162 | networks: 163 | corporate: 164 | sitea: 165 | siteb: 166 | 167 | secrets: 168 | gateway-admin-password: 169 | file: secrets/gateway-admin-password 170 | db-ignition-password: 171 | file: secrets/db-ignition-password 172 | db-root-password: 173 | file: secrets/db-root-password 174 | 175 | volumes: 176 | central-gw-data: 177 | sitea-gw-data: 178 | sitea-edge-data: 179 | siteb-gw-data: 180 | db-data: -------------------------------------------------------------------------------- /enterprise/eam-archive/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gwbk 2 | **/manifest.xml 3 | modules/*.modl -------------------------------------------------------------------------------- /enterprise/gw-init/central-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/enterprise/gw-init/central-gw.gwbk -------------------------------------------------------------------------------- /enterprise/gw-init/gateway.env: -------------------------------------------------------------------------------- 1 | ACCEPT_IGNITION_EULA=Y 2 | # GATEWAY_ADMIN_USERNAME=admin 3 | # GATEWAY_ADMIN_PASSWORD_FILE=/run/secrets/gateway-admin-password 4 | IGNITION_EDITION=standard 5 | TZ=America/Los_Angeles 6 | GATEWAY_MODULES_ENABLED=all 7 | -------------------------------------------------------------------------------- /enterprise/gw-init/sitea-edge.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/enterprise/gw-init/sitea-edge.gwbk -------------------------------------------------------------------------------- /enterprise/gw-init/sitea-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/enterprise/gw-init/sitea-gw.gwbk -------------------------------------------------------------------------------- /enterprise/gw-init/siteb-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/enterprise/gw-init/siteb-gw.gwbk -------------------------------------------------------------------------------- /enterprise/secrets/db-ignition-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /enterprise/secrets/db-root-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /enterprise/secrets/gateway-admin-password: -------------------------------------------------------------------------------- 1 | password -------------------------------------------------------------------------------- /enterprise/sql-init/setup.sql: -------------------------------------------------------------------------------- 1 | create schema central; 2 | create or replace user central identified by 'central'; 3 | grant ALL on central.* to central; 4 | 5 | create schema sitea; 6 | create or replace user sitea identified by 'sitea'; 7 | grant ALL on sitea.* to sitea; 8 | 9 | create schema siteb; 10 | create or replace user siteb identified by 'siteb'; 11 | grant ALL on siteb.* to siteb; 12 | -------------------------------------------------------------------------------- /hub-spoke/.env: -------------------------------------------------------------------------------- 1 | # Place environment variable overrides here to be read in by Docker Compose 2 | IGNITION_VERSION=8.1.43 3 | # Default max memory for each of the hub+spoke gateways 4 | GATEWAY_MAX_MEMORY=512 5 | -------------------------------------------------------------------------------- /hub-spoke/README.md: -------------------------------------------------------------------------------- 1 | # Ignition Hub+Spoke Architecture 2 | 3 | In the hub-and-spoke architecture, multiple local and remote sites are linked together by a central Ignition Gateway. 4 | 5 | ![Ignition Hub+Spoke Architecture Diagram](https://inductiveautomation.com/static/images/architectures/ArchitectureDiagram-HubandSpoke@2x.png) 6 | 7 | The hub and spoke architecture consists of two pieces. The hub piece consists of a central Ignition Gateway with Vision, Reporting and Mobile Modules and a database server. The spoke piece consists of a stripped-down Ignition Gateway with OPC UA and SQL Bridge Modules, dedicated for data logging. Each site is fully independent, operating with its own history, alarms, and clients, with the client Gateway being used for coordination and long-term history storage. 8 | 9 | ## Configure 10 | 11 | See [common configuration](../README.md#common-configuration) for specifics on files/folders in this solution. 12 | 13 | ## Enable 14 | 15 | First, make sure your working directory is `hub-spoke`: 16 | 17 | ![Change Working Directory](../assets/hub-spoke-change-wd.gif) 18 | 19 | To bring up the solution: 20 | 21 | docker-compose up -d 22 | 23 | ![Bringing up the solution](../assets/hub-spoke-compose-up.gif) 24 | 25 | ## Connect 26 | 27 | Once the solution has been launched, you can begin to access the services at: 28 | 29 | - Central Ignition Gateway - http://central-gw.localtest.me:8088 30 | - Local Site Gateway - http://local1-gw.localtest.me:8089 31 | - Remote Site Gateway - http://remote1-gw.localtest.me:8090 32 | - MariaDB Database - `localhost:3306` 33 | - MailHog SMTP Test Tool - http://mailhog.localtest.me:8025 34 | 35 | Default admin credentials for Ignition Gateways are `admin` / `password`. Default admin credentials for MariaDB are `root` / `ignition`. 36 | 37 | ## Monitor 38 | 39 | If you'd like to monitor the logs of any of the services, you can use the following: 40 | 41 | docker-compose logs --tail=250 -f 42 | 43 | ... where `` is one of the named services from `docker-compose.yml`, e.g. `gateway` or `db`. Omit the `` to start viewing logs from all services. Use `CTRL-C` to break out of the log view. 44 | 45 | ## Shutdown 46 | 47 | To shutdown the containers within the solution: 48 | 49 | docker-compose down 50 | 51 | Note that this will leave data volumes intact on your system so that bringing the solution back online will return to the previous state. If you want to also remove the data volumes and return the solution to the original state, add a `-v` flag to the *down* command. -------------------------------------------------------------------------------- /hub-spoke/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Hub+Spoke Architecture Example 2 | # https://inductiveautomation.com/ignition/architectures 3 | # https://inductiveautomation.com/static/pdf/IgnitionArchitecture-HubandSpoke.pdf 4 | --- 5 | x-default-logging: 6 | &default-logging 7 | logging: 8 | options: 9 | max-size: '100m' 10 | max-file: '5' 11 | driver: json-file 12 | 13 | x-ignition-opts: 14 | &ignition-opts 15 | <<: *default-logging 16 | image: inductiveautomation/ignition:${IGNITION_VERSION:-latest} 17 | env_file: gw-init/gateway.env 18 | secrets: 19 | - gateway-admin-password 20 | 21 | services: 22 | central-gw: 23 | <<: *ignition-opts 24 | hostname: central-gw 25 | ports: 26 | - 8088:8088 27 | - 8043:8043 28 | command: > 29 | -n Central 30 | -m ${GATEWAY_MAX_MEMORY:-512} 31 | -a central-gw.localtest.me 32 | -h 8088 33 | -s 8043 34 | -r /usr/local/bin/ignition/base.gwbk 35 | environment: 36 | GATEWAY_NETWORK_REQUIRESSL: false 37 | GATEWAY_NETWORK_SECURITYPOLICY: SpecifiedList 38 | GATEWAY_NETWORK_WHITELIST: local1,remote1 39 | networks: 40 | - centralnet 41 | - local1net 42 | - remote1net 43 | volumes: 44 | - central-gw-data:/usr/local/bin/ignition/data 45 | - ./gw-backup/central:/backup 46 | - ./gw-init/central-gw.gwbk:/usr/local/bin/ignition/base.gwbk 47 | 48 | local1-gw: 49 | <<: *ignition-opts 50 | hostname: local1-gw 51 | ports: 52 | - 8089:8088 53 | - 8044:8043 54 | command: > 55 | -n Local1 56 | -m ${GATEWAY_MAX_MEMORY:-512} 57 | -a local1-gw.localtest.me 58 | -h 8089 59 | -s 8044 60 | -r /usr/local/bin/ignition/base.gwbk 61 | environment: 62 | GATEWAY_NETWORK_0_HOST: central-gw 63 | GATEWAY_NETWORK_0_PORT: 8088 64 | GATEWAY_NETWORK_0_ENABLESSL: false 65 | GATEWAY_NETWORK_0_PINGRATE: 5000 66 | networks: 67 | - centralnet 68 | - local1net 69 | volumes: 70 | - local1-gw-data:/usr/local/bin/ignition/data 71 | - ./gw-backup/local1:/backup 72 | - ./gw-init/local1-gw.gwbk:/usr/local/bin/ignition/base.gwbk 73 | 74 | remote1-gw: 75 | <<: *ignition-opts 76 | hostname: remote1-gw 77 | ports: 78 | - 8090:8088 79 | - 8045:8043 80 | command: > 81 | -n Remote1 82 | -m ${GATEWAY_MAX_MEMORY:-512} 83 | -a remote1-gw.localtest.me 84 | -h 8090 85 | -s 8045 86 | -r /usr/local/bin/ignition/base.gwbk 87 | networks: 88 | - centralnet 89 | - remote1net 90 | environment: 91 | GATEWAY_NETWORK_0_HOST: central-gw 92 | GATEWAY_NETWORK_0_PORT: 8088 93 | GATEWAY_NETWORK_0_ENABLESSL: false 94 | GATEWAY_NETWORK_0_PINGRATE: 5000 95 | volumes: 96 | - remote1-gw-data:/usr/local/bin/ignition/data 97 | - ./gw-backup/remote1:/backup 98 | - ./gw-init/remote1-gw.gwbk:/usr/local/bin/ignition/base.gwbk 99 | 100 | db: 101 | <<: *default-logging 102 | image: mariadb:${MARIADB_VERSION:-latest} 103 | ports: 104 | - 3306:3306 105 | environment: 106 | MARIADB_USER: ignition 107 | MARIADB_PASSWORD_FILE: /run/secrets/db-ignition-password 108 | MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db-root-password 109 | networks: 110 | centralnet: 111 | aliases: 112 | - central-db 113 | local1net: 114 | aliases: 115 | - local1-db 116 | remote1net: 117 | aliases: 118 | - remote1-db 119 | secrets: 120 | - db-root-password 121 | - db-ignition-password 122 | volumes: 123 | - db-data:/var/lib/mysql 124 | - ./sql-init:/docker-entrypoint-initdb.d 125 | 126 | mailhog: 127 | <<: *default-logging 128 | image: mailhog/mailhog:1.0.1@sha256:8d76a3d4ffa32a3661311944007a415332c4bb855657f4f6c57996405c009bea 129 | ports: 130 | - 8025:8025 131 | networks: 132 | centralnet: 133 | aliases: 134 | - mail 135 | 136 | networks: 137 | centralnet: 138 | local1net: 139 | remote1net: 140 | 141 | secrets: 142 | gateway-admin-password: 143 | file: secrets/gateway-admin-password 144 | db-ignition-password: 145 | file: secrets/db-ignition-password 146 | db-root-password: 147 | file: secrets/db-root-password 148 | 149 | volumes: 150 | central-gw-data: 151 | local1-gw-data: 152 | remote1-gw-data: 153 | db-data: -------------------------------------------------------------------------------- /hub-spoke/gw-backup/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gwbk -------------------------------------------------------------------------------- /hub-spoke/gw-init/central-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/hub-spoke/gw-init/central-gw.gwbk -------------------------------------------------------------------------------- /hub-spoke/gw-init/gateway.env: -------------------------------------------------------------------------------- 1 | ACCEPT_IGNITION_EULA=Y 2 | # GATEWAY_ADMIN_USERNAME=admin 3 | # GATEWAY_ADMIN_PASSWORD_FILE=/run/secrets/gateway-admin-password 4 | IGNITION_EDITION=standard 5 | TZ=America/Los_Angeles 6 | GATEWAY_MODULES_ENABLED=all 7 | DISABLE_QUICKSTART=true -------------------------------------------------------------------------------- /hub-spoke/gw-init/local1-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/hub-spoke/gw-init/local1-gw.gwbk -------------------------------------------------------------------------------- /hub-spoke/gw-init/remote1-gw.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/hub-spoke/gw-init/remote1-gw.gwbk -------------------------------------------------------------------------------- /hub-spoke/secrets/db-ignition-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /hub-spoke/secrets/db-root-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /hub-spoke/secrets/gateway-admin-password: -------------------------------------------------------------------------------- 1 | password -------------------------------------------------------------------------------- /hub-spoke/sql-init/setup.sql: -------------------------------------------------------------------------------- 1 | create schema central; 2 | create or replace user central identified by 'central'; 3 | grant ALL on central.* to central; 4 | 5 | create schema local1; 6 | create or replace user local1 identified by 'local1'; 7 | grant ALL on local1.* to local1; 8 | 9 | create schema remote1; 10 | create or replace user remote1 identified by 'remote1'; 11 | grant ALL on remote1.* to remote1; 12 | -------------------------------------------------------------------------------- /iiot/.env: -------------------------------------------------------------------------------- 1 | # Place environment variable overrides here to be read in by Docker Compose 2 | IGNITION_VERSION=8.1.43 3 | # Default max memory for each of the IIoT Ignition gateways 4 | GATEWAY_MAX_MEMORY=512 5 | -------------------------------------------------------------------------------- /iiot/README.md: -------------------------------------------------------------------------------- 1 | # Ignition IIoT Architecture 2 | 3 | With the Ignition IIoT architecture you can set up a secure MQTT Message-Oriented Middleware (MOM) infrastructure in the Cloud, on a private on-premise network, or a hybrid of both. 4 | 5 | ![Ignition IIoT Architecture Diagram](https://inductiveautomation.com/static/images/architectures/iiot-architecture-diagram.e30f8b355256.png) 6 | 7 | Ignition IIoT can collects data from any devices at the edge of the network, publish that data to a central broker, and push that data to subscribed industrial and line-of-business applications. Ignition IIoT can connect to PLCs in the field through the use of the MQTT Transmission module, field devices with Ignition Edge MQTT installed, and/or MQTT-enabled edge gateways and field devices that use the Cirrus Link Sparkplug MQTT specification. This data is published to an MQTT broker, this broker can be located on-premise, in the cloud, or a hybrid of the two. The MQTT Engine module located on an Ignition Gateway can subscribe to any data published from the broker, this data can be use in any Ignition application. 8 | 9 | LICENSING NOTE: Use of this solution implies acceptance of the Cirrus Link MQTT Module EULAs as well as the standard Ignition EULA. The EULAs are accepted on the user's behalf during automated launching of the associated Ignition Gateways. 10 | 11 | ## Configure 12 | 13 | See [common configuration](../README.md#common-configuration) for specifics on files/folders in this solution. 14 | 15 | ## Enable 16 | 17 | First, make sure your working directory is `iiot`: 18 | 19 | ![Change Working Directory](../assets/iiot-change-wd.gif) 20 | 21 | To bring up the solution: 22 | 23 | docker-compose up -d 24 | 25 | ![Bringing up the solution](../assets/iiot-compose-up.gif) 26 | 27 | ## Connect 28 | 29 | Once the solution has been launched, you can begin to access the services at: 30 | 31 | - Central Ignition Gateway - http://gateway.localtest.me:8088 32 | - MQTT Distributor - `localhost:1883` 33 | - Edge Gateway 1 - http://gateway-edge1.localtest.me:8090 34 | - MariaDB Database - `localhost:3306` 35 | 36 | Default admin credentials for Ignition Gateways are `admin` / `password`. Default admin credentials for MariaDB are `root` / `ignition`. Default MQTT Distributor credentials are `admin` / `changeme`. 37 | 38 | ## Monitor 39 | 40 | If you'd like to monitor the logs of any of the services, you can use the following: 41 | 42 | docker-compose logs --tail=250 -f 43 | 44 | ... where `` is one of the named services from `docker-compose.yml`, e.g. `gateway` or `db`. Omit the `` to start viewing logs from all services. Use `CTRL-C` to break out of the log view. 45 | 46 | ## Shutdown 47 | 48 | To shutdown the containers within the solution: 49 | 50 | docker-compose down 51 | 52 | Note that this will leave data volumes intact on your system so that bringing the solution back online will return to the previous state. If you want to also remove the data volumes and return the solution to the original state, add a `-v` flag to the *down* command. -------------------------------------------------------------------------------- /iiot/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # IIoT Architecture Example 2 | # https://inductiveautomation.com/ignition/architectures 3 | # https://inductiveautomation.com/static/pdf/IgnitionArchitecture-IIoT-CloudRedundant.pdf 4 | --- 5 | x-default-logging: 6 | &default-logging 7 | logging: 8 | options: 9 | max-size: '100m' 10 | max-file: '5' 11 | driver: json-file 12 | 13 | x-ignition-opts: 14 | &ignition-opts 15 | <<: *default-logging 16 | env_file: gw-init/gateway.env 17 | secrets: 18 | - gateway-admin-password 19 | 20 | services: 21 | gateway: 22 | <<: *ignition-opts 23 | build: 24 | context: gw-build 25 | dockerfile: Dockerfile 26 | args: 27 | IGNITION_VERSION: ${IGNITION_VERSION:-latest} 28 | SUPPLEMENTAL_MODULES: "mqttdistributor mqttengine" 29 | BASE_GWBK_NAME: gateway.gwbk 30 | GATEWAY_ADMIN_USERNAME: admin 31 | secrets: 32 | # NOTE: changing a build secret will not bust the cache, run the build with `--no-cache` to force a rebuild 33 | - gateway-admin-password 34 | pull_policy: build 35 | hostname: gateway 36 | ports: 37 | - 8088:8088 38 | - 1883:1883 39 | command: > 40 | -n Ignition-gateway 41 | -m ${GATEWAY_MAX_MEMORY:-512} 42 | -a gateway.localtest.me 43 | -h 8088 44 | -s 8043 45 | volumes: 46 | - gateway-data:/usr/local/bin/ignition/data 47 | - ./gw-backup/gateway:/backup 48 | 49 | gateway-edge1: 50 | <<: *ignition-opts 51 | build: 52 | context: gw-build 53 | dockerfile: Dockerfile 54 | args: 55 | IGNITION_VERSION: ${IGNITION_VERSION:-latest} 56 | SUPPLEMENTAL_MODULES: "mqtttransmission" 57 | BASE_GWBK_NAME: edge1.gwbk 58 | IGNITION_EDITION: edge 59 | GATEWAY_ADMIN_USERNAME: admin 60 | secrets: 61 | - gateway-admin-password 62 | pull_policy: build 63 | ports: 64 | - 8090:8088 65 | command: > 66 | -n Ignition-edge1 67 | -m ${GATEWAY_MAX_MEMORY:-512} 68 | -a gateway-edge1.localtest.me 69 | -h 8090 70 | -s 8043 71 | volumes: 72 | - gateway-edge1-data:/usr/local/bin/ignition/data 73 | - ./gw-backup/edge1:/backup 74 | 75 | db: 76 | <<: *default-logging 77 | image: mariadb:${MARIADB_VERSION:-latest} 78 | ports: 79 | - 3306:3306 80 | environment: 81 | MARIADB_USER: ignition 82 | MARIADB_PASSWORD_FILE: /run/secrets/db-ignition-password 83 | MARIADB_DATABASE: ignition 84 | MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db-root-password 85 | secrets: 86 | - db-root-password 87 | - db-ignition-password 88 | volumes: 89 | - db-data:/var/lib/mysql 90 | 91 | secrets: 92 | gateway-admin-password: 93 | file: secrets/gateway-admin-password 94 | db-ignition-password: 95 | file: secrets/db-ignition-password 96 | db-root-password: 97 | file: secrets/db-root-password 98 | 99 | volumes: 100 | gateway-data: 101 | gateway-edge1-data: 102 | db-data: 103 | -------------------------------------------------------------------------------- /iiot/gw-backup/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gwbk -------------------------------------------------------------------------------- /iiot/gw-build/Dockerfile: -------------------------------------------------------------------------------- 1 | # Draw from environment (see .env file) for Ignition version/tag to source from 2 | ARG IGNITION_VERSION=${IGNITION_VERSION} 3 | FROM inductiveautomation/ignition:${IGNITION_VERSION} as prep 4 | 5 | # Switch to root user for base image updates 6 | USER root 7 | 8 | # Install some prerequisite packages 9 | RUN apt-get update && apt-get install -y wget jq zip unzip sqlite3 10 | 11 | ARG SUPPLEMENTAL_AWSINJECTOR_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/AWS-Injector-signed.modl" 12 | ARG SUPPLEMENTAL_AWSINJECTOR_DOWNLOAD_SHA256="5aa6ab27829e6dfa67026358553a3e5e5d1b8ec689e5ffaae3cdaddbc9a3c252" 13 | ARG SUPPLEMENTAL_AZUREIOTINJECTOR_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/Azure-Injector-signed.modl" 14 | ARG SUPPLEMENTAL_AZUREIOTINJECTOR_DOWNLOAD_SHA256="90cee320d98fa9c1d8c0f3786586c8cd8dd256803e08ed3fcfc772acccdf3dbd" 15 | ARG SUPPLEMENTAL_GCPINJECTOR_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/Google-Cloud-Injector-signed.modl" 16 | ARG SUPPLEMENTAL_GCPINJECTOR_DOWNLOAD_SHA256="72078b25fb3c6853d85a76c212fb63a8c1277707666b492f67fb91ea333775b8" 17 | ARG SUPPLEMENTAL_MQTTTRANSMISSION_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/MQTT-Transmission-signed.modl" 18 | ARG SUPPLEMENTAL_MQTTTRANSMISSION_DOWNLOAD_SHA256="cb5d620513110c23b618989b56c5c2a67c45c36944a25d127586e8e303f0273a" 19 | ARG SUPPLEMENTAL_MQTTTRANSMISSIONNIGHTLY_DOWNLOAD_URL="https://ignition-modules-nightly.s3.amazonaws.com/Ignition8/MQTT-Transmission-signed.modl" 20 | ARG SUPPLEMENTAL_MQTTTRANSMISSIONNIGHTLY_DOWNLOAD_SHA256="notused" 21 | ARG SUPPLEMENTAL_MQTTENGINE_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/MQTT-Engine-signed.modl" 22 | ARG SUPPLEMENTAL_MQTTENGINE_DOWNLOAD_SHA256="ad8924bdfc248fc4cc1d58badc37d0581081995536780edb260ebff8081ebb99" 23 | ARG SUPPLEMENTAL_MQTTENGINENIGHTLY_DOWNLOAD_URL="https://ignition-modules-nightly.s3.amazonaws.com/Ignition8/MQTT-Engine-signed.modl" 24 | ARG SUPPLEMENTAL_MQTTENGINENIGHTLY_DOWNLOAD_SHA256="notused" 25 | ARG SUPPLEMENTAL_MQTTDISTRIBUTOR_DOWNLOAD_URL="https://files.inductiveautomation.com/third-party/cirrus-link/4.0.24/MQTT-Distributor-signed.modl" 26 | ARG SUPPLEMENTAL_MQTTDISTRIBUTOR_DOWNLOAD_SHA256="10c8026b9ccab90d267291de217d07490b4dab0adbf5af8501482f1fa59b27a5" 27 | ARG SUPPLEMENTAL_MQTTDISTRIBUTORNIGHTLY_DOWNLOAD_URL="https://ignition-modules-nightly.s3.amazonaws.com/Ignition8/MQTT-Distributor-signed.modl" 28 | ARG SUPPLEMENTAL_MQTTDISTRIBUTORNIGHTLY_DOWNLOAD_SHA256="notused" 29 | ARG SUPPLEMENTAL_MODULES 30 | 31 | # Set working directory for this prep image and ensure that exits from sub-shells bubble up and report an error 32 | WORKDIR /root 33 | SHELL [ "/usr/bin/env", "-S", "bash", "-euo", "pipefail", "-O", "inherit_errexit", "-c" ] 34 | 35 | # Retrieve all targeted modules and verify their integrity 36 | COPY --chmod=0755 retrieve-modules.sh . 37 | RUN ./retrieve-modules.sh \ 38 | -m "${SUPPLEMENTAL_MODULES:-}" 39 | 40 | # Set CERTIFICATES/EULAS acceptance in gateway backup config db 41 | COPY *.gwbk ./ 42 | COPY --chmod=0755 register-module.sh register-password.sh ./ 43 | ARG GATEWAY_ADMIN_USERNAME="admin" 44 | ARG BASE_GWBK_NAME="base.gwbk" 45 | RUN --mount=type=secret,id=gateway-admin-password \ 46 | unzip -q "${BASE_GWBK_NAME}" db_backup_sqlite.idb && \ 47 | shopt -s nullglob; \ 48 | for module in *.modl; do \ 49 | ./register-module.sh \ 50 | -f "${module}" \ 51 | -d db_backup_sqlite.idb; \ 52 | done; \ 53 | shopt -u nullglob && \ 54 | ./register-password.sh \ 55 | -u "${GATEWAY_ADMIN_USERNAME}" \ 56 | -f /run/secrets/gateway-admin-password \ 57 | -d db_backup_sqlite.idb && \ 58 | zip -q -f "${BASE_GWBK_NAME}" db_backup_sqlite.idb || \ 59 | if [[ ${ZIP_EXIT_CODE:=$?} == 12 ]]; then \ 60 | echo "No changes to internal database needed during module registration."; \ 61 | else \ 62 | echo "Unknown error (${ZIP_EXIT_CODE}) encountered during re-packaging of config db, exiting." && \ 63 | exit ${ZIP_EXIT_CODE}; \ 64 | fi 65 | 66 | # Final Image 67 | FROM inductiveautomation/ignition:${IGNITION_VERSION} as final 68 | ARG BASE_GWBK_NAME="base.gwbk" 69 | ARG IGNITION_EDITION="standard" 70 | 71 | # Embed modules and base gwbk from prep image as well as entrypoint shim 72 | COPY --from=prep --chown=ignition:ignition /root/*.modl ${IGNITION_INSTALL_LOCATION}/user-lib/modules/ 73 | COPY --from=prep --chown=ignition:ignition /root/${BASE_GWBK_NAME} ${IGNITION_INSTALL_LOCATION}/base.gwbk 74 | COPY --chmod=0755 --chown=root:root docker-entrypoint-shim.sh /usr/local/bin/ 75 | 76 | # Return to ignition user 77 | USER ignition 78 | 79 | # Set Ignition Edition default based on build argument 80 | ENV IGNITION_EDITION="${IGNITION_EDITION}" 81 | 82 | # Target the entrypoint shim for any custom logic prior to gateway launch 83 | ENTRYPOINT [ "docker-entrypoint-shim.sh" ] 84 | -------------------------------------------------------------------------------- /iiot/gw-build/base.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/iiot/gw-build/base.gwbk -------------------------------------------------------------------------------- /iiot/gw-build/docker-entrypoint-shim.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | 4 | # Kick off the built-in entrypoint, with an in-built restore (-r ) directive 5 | exec docker-entrypoint.sh -r base.gwbk "$@" 6 | -------------------------------------------------------------------------------- /iiot/gw-build/edge1.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/iiot/gw-build/edge1.gwbk -------------------------------------------------------------------------------- /iiot/gw-build/gateway.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/iiot/gw-build/gateway.gwbk -------------------------------------------------------------------------------- /iiot/gw-build/register-module.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | shopt -s inherit_errexit 4 | 5 | ############################################################################### 6 | # Performs auto-acceptance of EULA and import of certificates for third-party modules 7 | ############################################################################### 8 | function main() { 9 | if [ ! -f "${MODULE_LOCATION}" ]; then 10 | echo "" 11 | return 0 # Silently exit if there is no /modules path 12 | elif [ ! -f "${DB_LOCATION}" ]; then 13 | echo "WARNING: ${DB_FILE} not found, skipping module registration" 14 | return 0 15 | fi 16 | 17 | register_module 18 | } 19 | 20 | ############################################################################### 21 | # Register the module with the target Config DB 22 | ############################################################################### 23 | function register_module() { 24 | local SQLITE3=( sqlite3 "${DB_LOCATION}" ) 25 | 26 | # Tie into db 27 | local keytool module_sourcepath 28 | module_basename=$(basename "${MODULE_LOCATION}") 29 | module_sourcepath=${MODULE_LOCATION} 30 | keytool=$(which keytool) 31 | 32 | echo "Processing Module: ${module_basename}" 33 | 34 | # Populate CERTIFICATES table 35 | local cert_info subject_name thumbprint next_certificates_id thumbprint_already_exists 36 | cert_info=$( unzip -qq -c "${module_sourcepath}" certificates.p7b | $keytool -printcert -v | head -n 9 ) 37 | thumbprint=$( echo "${cert_info}" | grep -A 2 "Certificate fingerprints" | grep SHA1 | cut -d : -f 2- | sed -e 's/\://g' | awk '{$1=$1;print tolower($0)}' ) 38 | subject_name=$( echo "${cert_info}" | grep -m 1 -Po '^Owner: CN=\K(.+?)(?=, (OU|O|L|ST|C)=)' | sed -e 's/"//g' ) 39 | echo " Thumbprint: ${thumbprint}" 40 | echo " Subject Name: ${subject_name}" 41 | next_certificates_id=$( "${SQLITE3[@]}" "SELECT COALESCE(MAX(CERTIFICATES_ID)+1,1) FROM CERTIFICATES" ) 42 | thumbprint_already_exists=$( "${SQLITE3[@]}" "SELECT 1 FROM CERTIFICATES WHERE lower(hex(THUMBPRINT)) = '${thumbprint}'" ) 43 | if [ "${thumbprint_already_exists}" != "1" ]; then 44 | echo " Accepting Certificate as CERTIFICATES_ID=${next_certificates_id}" 45 | "${SQLITE3[@]}" "INSERT INTO CERTIFICATES (CERTIFICATES_ID, THUMBPRINT, SUBJECTNAME) VALUES (${next_certificates_id}, x'${thumbprint}', '${subject_name}'); UPDATE SEQUENCES SET val=${next_certificates_id} WHERE name='CERTIFICATES_SEQ'" 46 | else 47 | echo " Thumbprint already found in CERTIFICATES table, skipping INSERT" 48 | fi 49 | 50 | # Populate EULAS table 51 | local next_eulas_id license_crc32 module_id 52 | local -i module_id_check 53 | next_eulas_id=$( "${SQLITE3[@]}" "SELECT COALESCE(MAX(EULAS_ID)+1,1) FROM EULAS" ) 54 | license_filename=$( unzip -qq -c "${module_sourcepath}" module.xml | grep -oP '(?<=).*(?=).*(?== 0 )); then 63 | echo " Accepting License on your behalf as EULAS_ID=${next_eulas_id}" 64 | "${SQLITE3[@]}" "INSERT INTO EULAS (EULAS_ID, MODULEID, CRC) VALUES (${next_eulas_id}, '${module_id}', ${license_crc32}); UPDATE SEQUENCES SET val=${next_eulas_id} WHERE name='EULAS_SEQ'" 65 | else 66 | echo " License EULA already found in EULAS table, skipping INSERT" 67 | fi 68 | } 69 | 70 | ############################################################################### 71 | # Outputs to stderr 72 | ############################################################################### 73 | function debug() { 74 | # shellcheck disable=SC2236 75 | if [ ! -z ${verbose+x} ]; then 76 | >&2 echo " DEBUG: $*" 77 | fi 78 | } 79 | 80 | ############################################################################### 81 | # Print usage information 82 | ############################################################################### 83 | function usage() { 84 | >&2 echo "Usage: $0 -f -d " 85 | } 86 | 87 | # Argument Processing 88 | while getopts ":hvf:d:" opt; do 89 | case "$opt" in 90 | v) 91 | verbose=1 92 | ;; 93 | f) 94 | MODULE_LOCATION="${OPTARG}" 95 | ;; 96 | d) 97 | DB_LOCATION="${OPTARG}" 98 | DB_FILE=$(basename "${DB_LOCATION}") 99 | ;; 100 | h) 101 | usage 102 | exit 0 103 | ;; 104 | \?) 105 | usage 106 | echo "Invalid option: -${OPTARG}" >&2 107 | exit 1 108 | ;; 109 | :) 110 | usage 111 | echo "Invalid option: -${OPTARG} requires an argument" >&2 112 | exit 1 113 | ;; 114 | esac 115 | done 116 | 117 | # shift positional args based on number consumed by getopts 118 | shift $((OPTIND-1)) 119 | 120 | if [ -z "${MODULE_LOCATION:-}" ] || [ -z "${DB_LOCATION:-}" ]; then 121 | usage 122 | exit 1 123 | fi 124 | 125 | main 126 | -------------------------------------------------------------------------------- /iiot/gw-build/register-password.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | shopt -s inherit_errexit 4 | 5 | # Global variables 6 | declare -u AUTH_SALT 7 | 8 | ############################################################################### 9 | # Update an Ignition SQLite Configuration DB with a baseline username/password 10 | # ---------------------------------------------------------------------------- 11 | # ref: https://gist.github.com/thirdgen88/c4257bd4c47b6cc7194d1f5e7cbd6444 12 | ############################################################################### 13 | function main() { 14 | if [ ! -f "${SECRET_LOCATION}" ]; then 15 | echo "" 16 | return 0 # Silently exit if there is no secret at target path 17 | elif [ ! -f "${DB_LOCATION}" ]; then 18 | echo "WARNING: ${DB_FILE} not found, skipping password registration" 19 | return 0 20 | fi 21 | 22 | register_password 23 | } 24 | 25 | ############################################################################### 26 | # Updates the target Config DB with the target username and salted pw hash 27 | ############################################################################### 28 | function register_password() { 29 | local SQLITE3=( sqlite3 "${DB_LOCATION}" ) password_hash password_input 30 | 31 | echo "Registering Admin Password with Configuration DB" 32 | 33 | # Generate Salted PW Hash 34 | password_input="$(< "${SECRET_LOCATION}")" 35 | if [[ "${password_input}" =~ ^\[[0-9A-F]{8,}][0-9a-f]{64}$ ]]; then 36 | debug "Password is already hashed" 37 | password_hash="${password_input}" 38 | else 39 | password_hash=$(generate_salted_hash "$(<"${SECRET_LOCATION}")") 40 | fi 41 | 42 | # Update INTERNALUSERTABLE 43 | echo " Setting default admin user to USERNAME='${GATEWAY_ADMIN_USERNAME}' and PASSWORD='${password_hash}'" 44 | "${SQLITE3[@]}" "UPDATE INTERNALUSERTABLE SET USERNAME='${GATEWAY_ADMIN_USERNAME}', PASSWORD='${password_hash}' WHERE PROFILEID=1 AND USERID=1" 45 | } 46 | 47 | ############################################################################### 48 | # Processes password input and translates to salted hash 49 | ############################################################################### 50 | function generate_salted_hash() { 51 | local auth_pwhash auth_pwsalthash auth_password password_input 52 | password_input="${1}" 53 | 54 | debug "auth_salt is ${AUTH_SALT}" 55 | auth_pwhash=$(printf %s "${password_input}" | sha256sum - | cut -c -64) 56 | debug "auth_pwhash is ${auth_pwhash}" 57 | auth_pwsalthash=$(printf %s "${password_input}${AUTH_SALT}" | sha256sum - | cut -c -64) 58 | debug "auth_pwsalthash is ${auth_pwsalthash}" 59 | auth_password="[${AUTH_SALT}]${auth_pwsalthash}" 60 | 61 | echo "${auth_password}" 62 | } 63 | 64 | ############################################################################### 65 | # Outputs to stderr 66 | ############################################################################### 67 | function debug() { 68 | # shellcheck disable=SC2236 69 | if [ ! -z ${verbose+x} ]; then 70 | >&2 echo " DEBUG: $*" 71 | fi 72 | } 73 | 74 | ############################################################################### 75 | # Print usage information 76 | ############################################################################### 77 | function usage() { 78 | >&2 echo "Usage: $0 -u -f -d [...]" 79 | >&2 echo " -u Gateway Admin Username" 80 | >&2 echo " -f Path to secret file containing password or salted hash" 81 | >&2 echo " -d Path to Ignition Configuration DB" 82 | >&2 echo " -s Salt method, either 'timestamp' or 'random' (default)" 83 | } 84 | 85 | # Argument Processing 86 | while getopts ":hvu:f:d:s:" opt; do 87 | case "$opt" in 88 | v) 89 | verbose=1 90 | ;; 91 | u) 92 | GATEWAY_ADMIN_USERNAME="${OPTARG}" 93 | ;; 94 | f) 95 | SECRET_LOCATION="${OPTARG}" 96 | ;; 97 | d) 98 | DB_LOCATION="${OPTARG}" 99 | DB_FILE=$(basename "${DB_LOCATION}") 100 | ;; 101 | s) 102 | # Compute AUTH_SALT based on timestamp or random 103 | case "${OPTARG}" in 104 | timestamp) 105 | AUTH_SALT=$(date +%s | sha256sum | head -c 8) 106 | ;; 107 | random) 108 | # no-op, default will be set below 109 | ;; 110 | *) 111 | usage 112 | echo "Invalid salt method: ${OPTARG}" >&2 113 | exit 1 114 | ;; 115 | esac 116 | ;; 117 | h) 118 | usage 119 | exit 0 120 | ;; 121 | \?) 122 | usage 123 | echo "Invalid option: -${OPTARG}" >&2 124 | exit 1 125 | ;; 126 | :) 127 | usage 128 | echo "Invalid option: -${OPTARG} requires an argument" >&2 129 | exit 1 130 | ;; 131 | esac 132 | done 133 | 134 | # shift positional args based on number consumed by getopts 135 | shift $((OPTIND-1)) 136 | 137 | # Check for required defaults 138 | if [ -z "${GATEWAY_ADMIN_USERNAME:-}" ] || [ -z "${SECRET_LOCATION:-}" ] || [ -z "${DB_LOCATION:-}" ]; then 139 | usage 140 | exit 1 141 | fi 142 | 143 | # set defaults for unset optional args 144 | if [[ -z ${AUTH_SALT+x} ]]; then 145 | AUTH_SALT=$(od -An -v -t x1 -N 4 /dev/random | tr -d ' ') 146 | fi 147 | 148 | main 149 | -------------------------------------------------------------------------------- /iiot/gw-build/retrieve-modules.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | shopt -s inherit_errexit 4 | 5 | ############################################################################### 6 | # Retrieves third-party modules and verifies their checksums 7 | ############################################################################### 8 | function main() { 9 | if [ -z "${SUPPLEMENTAL_MODULES}" ]; then 10 | return 0 # Silently exit if there are no supplemental modules to target 11 | fi 12 | 13 | retrieve_modules 14 | } 15 | 16 | ############################################################################### 17 | # Download the modules 18 | ############################################################################### 19 | function retrieve_modules() { 20 | IFS=', ' read -r -a module_install_key_arr <<< "${SUPPLEMENTAL_MODULES}" 21 | for module_install_key in "${module_install_key_arr[@]}"; do 22 | download_url_env="SUPPLEMENTAL_${module_install_key^^}_DOWNLOAD_URL" 23 | download_sha256_env="SUPPLEMENTAL_${module_install_key^^}_DOWNLOAD_SHA256" 24 | if [ -n "${!download_url_env:-}" ] && [ -n "${!download_sha256_env:-}" ]; then 25 | download_basename=$(basename "${!download_url_env}") 26 | wget --ca-certificate=/etc/ssl/certs/ca-certificates.crt --referer https://inductiveautomation.com/* "${!download_url_env}" && \ 27 | [[ "notused" == "${!download_sha256_env}" ]] || echo "${!download_sha256_env}" "${download_basename}" | sha256sum -c - 28 | else 29 | echo "Error finding specified module ${module_install_key} in build args, aborting..." 30 | exit 1 31 | fi 32 | done 33 | } 34 | 35 | ############################################################################### 36 | # Outputs to stderr 37 | ############################################################################### 38 | function debug() { 39 | # shellcheck disable=SC2236 40 | if [ ! -z ${verbose+x} ]; then 41 | >&2 echo " DEBUG: $*" 42 | fi 43 | } 44 | 45 | ############################################################################### 46 | # Print usage information 47 | ############################################################################### 48 | function usage() { 49 | >&2 echo "Usage: $0 -m \"space-separated modules list\"" 50 | >&2 echo " -m: space-separated list of module identifiers to download" 51 | } 52 | 53 | # Argument Processing 54 | while getopts ":hvm:" opt; do 55 | case "$opt" in 56 | v) 57 | verbose=1 58 | ;; 59 | m) 60 | SUPPLEMENTAL_MODULES="${OPTARG}" 61 | ;; 62 | h) 63 | usage 64 | exit 0 65 | ;; 66 | \?) 67 | usage 68 | echo "Invalid option: -${OPTARG}" >&2 69 | exit 1 70 | ;; 71 | :) 72 | usage 73 | echo "Invalid option: -${OPTARG} requires an argument" >&2 74 | exit 1 75 | ;; 76 | esac 77 | done 78 | 79 | # shift positional args based on number consumed by getopts 80 | shift $((OPTIND-1)) 81 | 82 | # exit on missing required args 83 | if [ -z "${SUPPLEMENTAL_MODULES:-}" ]; then 84 | usage 85 | exit 1 86 | fi 87 | 88 | main 89 | -------------------------------------------------------------------------------- /iiot/gw-init/gateway.env: -------------------------------------------------------------------------------- 1 | ACCEPT_IGNITION_EULA=Y 2 | # GATEWAY_ADMIN_USERNAME=admin 3 | # GATEWAY_ADMIN_PASSWORD_FILE=/run/secrets/gateway-admin-password 4 | TZ=America/Los_Angeles 5 | GATEWAY_MODULES_ENABLED=all 6 | -------------------------------------------------------------------------------- /iiot/secrets/db-ignition-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /iiot/secrets/db-root-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /iiot/secrets/gateway-admin-password: -------------------------------------------------------------------------------- 1 | password -------------------------------------------------------------------------------- /scale-out/.env: -------------------------------------------------------------------------------- 1 | # Place environment variable overrides here to be read in by Docker Compose 2 | IGNITION_VERSION=8.1.43 3 | # Default max memory for each of the scale-out gateways 4 | GATEWAY_MAX_MEMORY=512 5 | -------------------------------------------------------------------------------- /scale-out/README.md: -------------------------------------------------------------------------------- 1 | # Ignition Scale-Out Architecture 2 | 3 | The scale-out architecture links together several Ignition Gateways to form a decentralized system. 4 | 5 | ![Ignition Scale-Out Architecture Diagram](https://inductiveautomation.com/static/images/architectures/ArchitectureDiagram-ScaleOut@2x.png) 6 | 7 | With the scale-out architecture, the workload is split between tags and I/O Gateways that handle device data and front-end Gateways that handle client applications. This architecture scales out easily without overloading any single Gateway. 8 | 9 | ## Configure 10 | 11 | See [common configuration](../README.md#common-configuration) for specifics on files/folders in this solution. 12 | 13 | ## Enable 14 | 15 | First, make sure your working directory is `scale-out`: 16 | 17 | ![Change Working Directory](../assets/scale-out-change-wd.gif) 18 | 19 | To bring up the solution: 20 | 21 | docker-compose up -d 22 | 23 | ![Bringing up the solution](../assets/scale-out-compose-up.gif) 24 | 25 | ## Connect 26 | 27 | Once the solution has been launched, you can begin to access the services at: 28 | 29 | - Frontend Ignition Gateway - http://gateway-fe.localtest.me:8088 30 | - I/O Ignition Gateway 1 - http://gateway-tag1.localtest.me:8090 31 | - I/O Ignition Gateway 2 - http://gateway-tag2.localtest.me:8092 32 | - MariaDB Database - `localhost:3306` 33 | 34 | Default admin credentials for Ignition Gateways are `admin` / `password`. Default admin credentials for MariaDB are `root` / `ignition`. 35 | 36 | ## Monitor 37 | 38 | If you'd like to monitor the logs of any of the services, you can use the following: 39 | 40 | docker-compose logs --tail=250 -f 41 | 42 | ... where `` is one of the named services from `docker-compose.yml`, e.g. `gateway` or `db`. Omit the `` to start viewing logs from all services. Use `CTRL-C` to break out of the log view. 43 | 44 | ## Shutdown 45 | 46 | To shutdown the containers within the solution: 47 | 48 | docker-compose down 49 | 50 | Note that this will leave data volumes intact on your system so that bringing the solution back online will return to the previous state. If you want to also remove the data volumes and return the solution to the original state, add a `-v` flag to the *down* command. -------------------------------------------------------------------------------- /scale-out/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Scale-Out Architecture Example 2 | # https://inductiveautomation.com/ignition/architectures 3 | # https://inductiveautomation.com/static/pdf/IgnitionArchitecture-ScaleOut.pdf 4 | --- 5 | x-default-logging: 6 | &default-logging 7 | logging: 8 | options: 9 | max-size: '100m' 10 | max-file: '5' 11 | driver: json-file 12 | 13 | x-ignition-opts: 14 | &ignition-opts 15 | <<: *default-logging 16 | image: inductiveautomation/ignition:${IGNITION_VERSION:-latest} 17 | env_file: gw-init/gateway.env 18 | secrets: 19 | - gateway-admin-password 20 | 21 | services: 22 | gateway-fe: 23 | <<: *ignition-opts 24 | hostname: gateway-fe 25 | ports: 26 | - 8088:8088 27 | command: > 28 | -n Ignition-frontend 29 | -m ${GATEWAY_MAX_MEMORY:-512} 30 | -a gateway-fe.localtest.me 31 | -h 8088 32 | -s 8043 33 | -r /restore.gwbk 34 | environment: 35 | GATEWAY_NETWORK_REQUIRESSL: false 36 | GATEWAY_NETWORK_SECURITYPOLICY: SpecifiedList 37 | GATEWAY_NETWORK_WHITELIST: Ignition-tag1,Ignition-tag2 38 | volumes: 39 | - gateway-fe-data:/usr/local/bin/ignition/data 40 | - ./gw-backup:/backup 41 | - ./gw-init/gateway-fe.gwbk:/restore.gwbk 42 | 43 | gateway-tag1: 44 | <<: *ignition-opts 45 | hostname: gateway-tag1 46 | ports: 47 | - 8090:8088 48 | command: > 49 | -n Ignition-tag1 50 | -m ${GATEWAY_MAX_MEMORY:-512} 51 | environment: 52 | GATEWAY_NETWORK_0_HOST: gateway-fe 53 | GATEWAY_NETWORK_0_PORT: 8088 54 | GATEWAY_NETWORK_0_ENABLESSL: false 55 | GATEWAY_ADMIN_PASSWORD_FILE: /run/secrets/gateway-admin-password 56 | volumes: 57 | - gateway-tag1-data:/usr/local/bin/ignition/data 58 | 59 | gateway-tag2: 60 | <<: *ignition-opts 61 | hostname: gateway-tag2 62 | ports: 63 | - 8092:8088 64 | command: > 65 | -n Ignition-tag2 66 | -m ${GATEWAY_MAX_MEMORY:-512} 67 | environment: 68 | GATEWAY_NETWORK_0_HOST: gateway-fe 69 | GATEWAY_NETWORK_0_PORT: 8088 70 | GATEWAY_NETWORK_0_ENABLESSL: false 71 | GATEWAY_ADMIN_PASSWORD_FILE: /run/secrets/gateway-admin-password 72 | volumes: 73 | - gateway-tag2-data:/usr/local/bin/ignition/data 74 | 75 | db: 76 | <<: *default-logging 77 | image: mariadb:${MARIADB_VERSION:-latest} 78 | ports: 79 | - 3306:3306 80 | environment: 81 | MARIADB_USER: ignition 82 | MARIADB_PASSWORD_FILE: /run/secrets/db-ignition-password 83 | MARIADB_DATABASE: ignition 84 | MARIADB_ROOT_PASSWORD_FILE: /run/secrets/db-root-password 85 | secrets: 86 | - db-root-password 87 | - db-ignition-password 88 | volumes: 89 | - db-data:/var/lib/mysql 90 | 91 | secrets: 92 | gateway-admin-password: 93 | file: secrets/gateway-admin-password 94 | db-ignition-password: 95 | file: secrets/db-ignition-password 96 | db-root-password: 97 | file: secrets/db-root-password 98 | 99 | volumes: 100 | gateway-fe-data: 101 | gateway-tag1-data: 102 | gateway-tag2-data: 103 | db-data: 104 | -------------------------------------------------------------------------------- /scale-out/gw-backup/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gwbk -------------------------------------------------------------------------------- /scale-out/gw-init/gateway-fe.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/scale-out/gw-init/gateway-fe.gwbk -------------------------------------------------------------------------------- /scale-out/gw-init/gateway.env: -------------------------------------------------------------------------------- 1 | ACCEPT_IGNITION_EULA=Y 2 | # GATEWAY_ADMIN_USERNAME=admin 3 | # GATEWAY_ADMIN_PASSWORD_FILE=/run/secrets/gateway-admin-password 4 | IGNITION_EDITION=standard 5 | TZ=America/Los_Angeles 6 | GATEWAY_MODULES_ENABLED=all 7 | -------------------------------------------------------------------------------- /scale-out/secrets/db-ignition-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /scale-out/secrets/db-root-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /scale-out/secrets/gateway-admin-password: -------------------------------------------------------------------------------- 1 | password -------------------------------------------------------------------------------- /standard/.env: -------------------------------------------------------------------------------- 1 | # Place environment variable overrides here to be read in by Docker Compose 2 | COMPOSE_PROFILES=redundancy 3 | IGNITION_VERSION=8.1.43 4 | GATEWAY_MAX_MEMORY=1024 5 | -------------------------------------------------------------------------------- /standard/README.md: -------------------------------------------------------------------------------- 1 | # Ignition Standard Architecture 2 | 3 | Ignition’s most common architecture consists of a single on-premise Ignition server connected to a SQL database, PLCs, and clients. 4 | 5 | ![Ignition Standard Architecture Diagram](https://inductiveautomation.com/static/images/architectures/redundant-scada-architecture.a3d7edfbcec6.png) 6 | 7 | The standard architecture is best suited for applications that require a scalable, centrally managed SCADA system using only one on-premise Ignition server and select modules. This implementation is the most cost-effective setup since you only pay for one license to have unlimited connections, tags, databases, and web-deployable clients. 8 | 9 | ## Configure 10 | 11 | See [common configuration](../README.md#common-configuration) for specifics on files/folders in this solution. 12 | 13 | ## Enable 14 | 15 | First, make sure your working directory is `standard`: 16 | 17 | ![Change Working Directory](../assets/standard-change-wd.gif) 18 | 19 | To bring up the solution: 20 | 21 | docker-compose up -d 22 | 23 | ![Bringing up the solution](../assets/standard-compose-up.gif) 24 | 25 | ## Connect 26 | 27 | Once the solution has been launched, you can begin to access the services at: 28 | 29 | - Primary Ignition Gateway - http://gateway.localtest.me:8088 30 | - Redundant Ignition Gateway - http://gatewayr.localtest.me:8089 (if redundancy profile was enabled via `COMPOSE_PROFILES` in the `.env` file). 31 | - MariaDB Database - `localhost:3306` 32 | 33 | Default admin credentials for Ignition Gateways are `admin` / `password`. Default admin credentials for MariaDB are `root` / `ignition`. 34 | 35 | ## Monitor 36 | 37 | If you'd like to monitor the logs of any of the services, you can use the following: 38 | 39 | docker-compose logs --tail=250 -f 40 | 41 | ... where `` is one of the named services from `docker-compose.yml`, e.g. `gateway` or `db`. Omit the `` to start viewing logs from all services. Use `CTRL-C` to break out of the log view. 42 | 43 | ## Shutdown 44 | 45 | To shutdown the containers within the solution: 46 | 47 | docker-compose down 48 | 49 | Note that this will leave data volumes intact on your system so that bringing the solution back online will return to the previous state. If you want to also remove the data volumes and return the solution to the original state, add a `-v` flag to the *down* command. -------------------------------------------------------------------------------- /standard/docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Standard Architecture Example 2 | # https://inductiveautomation.com/ignition/architectures 3 | # https://inductiveautomation.com/static/pdf/IgnitionArchitecture-Standard.pdf 4 | --- 5 | x-default-logging: 6 | &default-logging 7 | logging: 8 | options: 9 | max-size: '100m' 10 | max-file: '5' 11 | driver: json-file 12 | 13 | x-ignition-opts: 14 | &ignition-opts 15 | <<: *default-logging 16 | image: inductiveautomation/ignition:${IGNITION_VERSION:-latest} 17 | env_file: gw-init/gateway.env 18 | secrets: 19 | - gateway-admin-password 20 | 21 | services: 22 | gateway: 23 | <<: *ignition-opts 24 | hostname: gateway 25 | ports: 26 | - 8088:8088 27 | command: > 28 | -n Ignition-standard 29 | -m ${GATEWAY_MAX_MEMORY:-1024} 30 | -r /restore.gwbk 31 | -a gateway.localtest.me 32 | -h 8088 33 | -s 8043 34 | environment: 35 | GATEWAY_NETWORK_REQUIRESSL: false 36 | GATEWAY_NETWORK_SECURITYPOLICY: SpecifiedList 37 | GATEWAY_NETWORK_WHITELIST: Ignition-gatewayr-backup,Ignition-standard-backup 38 | volumes: 39 | - gateway-data:/usr/local/bin/ignition/data 40 | - ./gw-backup:/backup 41 | - ./gw-init/base.gwbk:/restore.gwbk 42 | - ./gw-init/gateway-${COMPOSE_PROFILES:-independent}.xml:/usr/local/bin/ignition/data/redundancy.xml 43 | 44 | gatewayr: 45 | <<: *ignition-opts 46 | hostname: gatewayr 47 | ports: 48 | - 8089:8088 49 | command: > 50 | -m ${GATEWAY_MAX_MEMORY:-1024} 51 | -a gatewayr.localtest.me 52 | -h 8089 53 | -s 8043 54 | profiles: 55 | - redundancy 56 | environment: 57 | ACCEPT_IGNITION_EULA: "Y" 58 | GATEWAY_ADMIN_USERNAME: admin 59 | GATEWAY_ADMIN_PASSWORD_FILE: /run/secrets/gateway-admin-password 60 | volumes: 61 | - gatewayr-data:/usr/local/bin/ignition/data 62 | - ./gw-init/gatewayr-redundancy.xml:/usr/local/bin/ignition/data/redundancy.xml 63 | 64 | db: 65 | <<: *default-logging 66 | image: mariadb:${MARIADB_VERSION:-latest} 67 | ports: 68 | - 3306:3306 69 | environment: 70 | MARIADB_USER: ignition 71 | MARIADB_PASSWORD: ignition 72 | MARIADB_DATABASE: ignition 73 | MARIADB_ROOT_PASSWORD: ignition 74 | volumes: 75 | - db-data:/var/lib/mysql 76 | 77 | secrets: 78 | gateway-admin-password: 79 | file: secrets/gateway-admin-password 80 | 81 | volumes: 82 | gateway-data: 83 | gatewayr-data: 84 | db-data: 85 | -------------------------------------------------------------------------------- /standard/gw-backup/.gitignore: -------------------------------------------------------------------------------- 1 | **/*.gwbk -------------------------------------------------------------------------------- /standard/gw-init/base.gwbk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thirdgen88/ignition-examples/42d28f160cfb360e5ce0928ea062253eb363cb6c/standard/gw-init/base.gwbk -------------------------------------------------------------------------------- /standard/gw-init/gateway-independent.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redundancy Settings 5 | 300 6 | Full 7 | Cold 8 | 1000 9 | 200 10 | true 11 | 10000 12 | 60 13 | Automatic 14 | 10000 15 | 8060 16 | true 17 | false 18 | Independent 19 | 10 20 | 21 | 10000 22 | 30000 23 | 0 24 | 100 25 | 28b34b46-92aa-40da-ab94-24a5d0b8b4d8 26 | 10000 27 | 60000 28 | 29 | 30 | -------------------------------------------------------------------------------- /standard/gw-init/gateway-redundancy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redundancy Settings 5 | 300 6 | Full 7 | Cold 8 | 1000 9 | 200 10 | false 11 | 10000 12 | 60 13 | Automatic 14 | 10000 15 | 8088 16 | true 17 | false 18 | Master 19 | 10 20 | 21 | 10000 22 | 30000 23 | 2 24 | 100 25 | 07542976-a750-4a64-b783-1acadadcccff 26 | 10000 27 | 60000 28 | gateway 29 | 30 | -------------------------------------------------------------------------------- /standard/gw-init/gateway.env: -------------------------------------------------------------------------------- 1 | ACCEPT_IGNITION_EULA=Y 2 | # GATEWAY_ADMIN_USERNAME=admin 3 | # GATEWAY_ADMIN_PASSWORD_FILE=/run/secrets/gateway-admin-password 4 | IGNITION_EDITION=standard 5 | TZ=America/Los_Angeles 6 | GATEWAY_MODULES_ENABLED=all 7 | DISABLE_QUICKSTART=true 8 | -------------------------------------------------------------------------------- /standard/gw-init/gatewayr-redundancy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Redundancy Settings 5 | 300 6 | Full 7 | Cold 8 | 1000 9 | 200 10 | false 11 | 10000 12 | 60 13 | Automatic 14 | 10000 15 | 8088 16 | true 17 | false 18 | Backup 19 | 10 20 | 21 | 10000 22 | 30000 23 | 2 24 | 100 25 | 07542976-a750-4a64-b783-1acadadcccff 26 | 10000 27 | 60000 28 | gateway 29 | 30 | -------------------------------------------------------------------------------- /standard/secrets/db-ignition-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /standard/secrets/db-root-password: -------------------------------------------------------------------------------- 1 | ignition -------------------------------------------------------------------------------- /standard/secrets/gateway-admin-password: -------------------------------------------------------------------------------- 1 | password --------------------------------------------------------------------------------