# Pyro-gateway - a TypeScript library for starting Ignition Docker containers

**URL:** <https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789>\
**Category:** Automated Testing\
**Tags:** perspective\
**Created:** [November 12, 2023, 1:03am UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789 "2023-11-12T01:03:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [November 12, 2023, 1:03am UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789/1 "2023-11-12T01:03:53Z")

</div>

# pyro-gateway

[pyro-gateway](https://github.com/mussonindustrial/pyro/tree/main/packages/pyro-gateway) provides an API for starting Ignition Docker containers from within JavaScript. This library is intended for use in testing environments where you need a short-lived, programmatically configured, ephemeral gateway.

## Usage

### Start a new Gateway

```js
import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('8.1.33')
    .withModules(['perspective'])
    .withGatewayName('My New Gateway')
    .start()

```

### Start a Gateway from a Backup

```js
import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('8.1.33')
    .withGatewayBackup('/path/to/gateway.gwbk')
    .start()

```

### Setting Gateway Properties

Gateway properties can be set before startup through the various `.with~` methods.

```js
// Current available setter methods
.withEdition(edition: GatewayEdition)
.withHTTPPort(port: number)
.withHTTPSPort(port: number)
.withModules(modules: ModuleIdentifier[])
.withGatewayName(name: string)
.withGatewayBackup(path: string)

```

The eventual goal is to provide a complete set of setter methods.  
In the meantime, if you wish the directly set environment or runtime variables, they can be accessed through `gateway.env` and `gateway.runtime` respectively.

See the [GitHub page](https://github.com/mussonindustrial/pyro/tree/main/packages/pyro-gateway) for full details.

> **[GitHub - mussonindustrial/pyro: Resources, tools, and assets for Ignition by...](https://github.com/mussonindustrial/pyro/)**
>
> Resources, tools, and assets for Ignition by Inductive Automation 🛠️

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [December 6, 2023, 3:45am UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789/2 "2023-12-06T03:45:32Z")

</div>

Okay, this is not the most exciting example to sit through, but it's a solid proof of concept of what I've been building towards.

![20231205_222416](https://us1.discourse-cdn.com/inductiveautomation/original/3X/b/e/befe3d93e7647371fb514e278a7ba96ba2484ff9.gif)

Demonstrated in the GIF is an example workflow for editing Perspective themes:

1. A development Ignition container is started and a special "bootstrap-able" gateway backup is loaded.

2. After the gateway is started, a Perspective theme is sent to the gateway.

3. A change is made to the theme (turning the background red).

4. Using a file watcher, the change to the theme is detected. The theme is re-compiled ([plugins](https://github.com/mussonindustrial/pyro/tree/main/packages/postcss-perspective-style-class) applied, minified, etc.) and uploaded to the gateway.

5. A project scan is requested and all open Perspective sessions are refreshed.

6. The new theme is now visible on the development gateway.

7. (Not shown) After closing the command prompt, the gateway is shutdown and discarded.

Work needs to be done to speed up the iteration time, but all the pieces are here 🎉.

---

<div class="post-metadata">

**Author:** ![pascal.fragnoud](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/pascal.fragnoud/32/24728_2.png) [@pascal.fragnoud](https://forum.inductiveautomation.com/u/pascal.fragnoud)\
**Post date:** [December 6, 2023, 6:38am UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789/3 "2023-12-06T06:38:10Z")

</div>

While I salute the work done and the contribution to the ecosystem, I'm not sure I understand the use case for the example above. Does this allow to update files on a remote gateway ?  
I guess my question is: What's the advantage of this over a bind mount ? Except for the obvious fact that it's not a bind mount ;p

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [December 6, 2023, 12:46pm UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789/4 "2023-12-06T12:46:16Z")

</div>

> [@pascal.fragnoud](#):
>
> Does this allow to update files on a remote gateway ?

Yup. Any gateway with the setup/boot-strapping endpoints can be updated. So you could develop your theme on a local gateway with live reloading, then push to production gateway once changes are finalized (or have a CI/CD pipeline do it for you, for multiple gateways).

> [@pascal.fragnoud](#):
>
> What's the advantage of this over a bind mount ?

You’re right, for this example of updating a theme a bind mount would work fine. But, the goal is to allow configuration of more than can be set via bind mounts (database and device connections, etc.).

Then when 8.3 releases, we can drop the WebDev functions and use the native capabilities.

---

<div class="post-metadata">

**Author:** ![bmusson](https://sea1.discourse-cdn.com/inductiveautomation/user_avatar/forum.inductiveautomation.com/bmusson/32/87530_2.png) [@bmusson](https://forum.inductiveautomation.com/u/bmusson)\
**Post date:** [January 9, 2024, 1:11am UTC](https://forum.inductiveautomation.com/t/pyro-gateway-a-typescript-library-for-starting-ignition-docker-containers/81789/5 "2024-01-09T01:11:30Z")

</div>

v0.3.0 now allows you to perform project/resource imports on the running gateway.

The implementation is pretty naïve at the moment; if you import resources into a project that doesn't exist you'll end up with orphaned files. More work is coming to make it impossible to mess up, but at least it does work.

```js
import { IgnitionContainer } from '@mussonindustrial/pyro-gateway'

const gateway = await new IgnitionContainer('inductiveautomation/ignition:latest')
    .withGatewayBackup('/path/to/gateway.gwbk')
    .start()

gateway.importProject('new-project', '/path/to/project.zip')
gateway.importProjectResources('existing-project', '/path/to/resources.zip')

```

Edit: Also, moved this post to the **Automated Testing** category since that is the intended use case.
