The goal of this step, is to prepare your App to run inside SICON.OS.

Secondly, you will be able to package your App as Docker image.

And then, finally you can upload it to your local SICON.OS installation for testing.


1. Download and install Docker Desktop for your machine


2. Create docker files to prepare build and run instructions

The official docker documentation explain very well what is required to build and run a container. We provide you with the bare minimum required files required to create a docker application.

In the example below we are using NodeJs 16 as demo application.

Dockerfile - used for instructions to build and run containers

FROM node:16-alpine
RUN npm i -g serve concurrently

WORKDIR /opt/acme/event-monitoring
COPY ./package*.json ./
RUN npm install
COPY ./ ./
RUN npm run build
RUN rm -r src node_modules

CMD npm start

.dockerignore - used to prevent sending big files to the build context


docker-compose.yml - used to make repeated builds easier

version: '3'

      context: ../
        - TAG=${TAG:-release}

For test purposes, the vendor name is prefixed with dev- to prevent namespace collisions. Later when publishing your App, you can rename the vendor without the prefix.

3. Prepare your App to run as container

Relative Paths for Files

Once deployed, your App will run on the path /apps/<vendor>/<appName>/.

For example: https://siconos-2039.local/apps/dev-acme/event-monitoring/.

Your App is also served on /server/<vendor>/<appName>/ completely without SICON.OS sidebar and login.

This requires your App to reference its files from a relative path or include the full path.

For React apps, this can be configured in the package.json's homepage field. See create-react-app documentation.

Common pitfalls: Please always load your App with a trailing slash when using relative paths. The browser always loads relative to the last slash in the URL path. If you open your App on https://siconos-2039.local/apps/dev-acme/event-monitoring, but load your assets like javascript and css files with relative paths, this will lead to problems. As the final path will be https://siconos-2039.local/apps/dev-acme/style.css instead of https://siconos-2039.local/apps/dev-acme/event-monitoring/style.css.

Relative Paths for API Access

Accessing the API also has to account for the relative path from your client-side app.

You can use the following script from your front-end to retrieve the path for the REST API:

const APIBASEURL = `${location.origin}/api/v1`

Create a server and open the ports

If your App only consists of static files (html, css, js, etc…), then you need a static server that can host these files inside your docker container.

Most frameworks already include a web server. With a command like npm run server or npm start your App can run inside the docker container. Check the relevant documentation to configure the port.

Please do not provide HTTPS or your own SSL certificate. SICON.OS will automatically use its own certificate for serving your App on HTTPS.

By default, we use port 80 HTTP of the container to redirect your application to its app path (e.g.: /apps/dev-acme/event-monitoring)

This requires the following addition in your Dockerfile:


Runtime Settings

The run settings are a JSON object that instructs the docker engine to create your container. Settings like additional environment variables, reverse proxy instructions and volumes can be configured here. Please refer to the official docker documentation for possible fields.

For security reasons, we disallow changing the following HostConfig fields:

  • Links

  • Privileged

  • NetworkMode

  • SecurityOpt

  • StorageOpt

  • CgroupParent

  • VolumeDriver


Running and providing two servers

If you can’t configure the port or want to provide multiple Servers, you can add a load balance rule to the “Labels” object.

We use Traefik as reverse proxy to configure paths and HTTPS.

	"Labels": {
		"": "80",
		"traefik.http.routers.eventmonitoring_client_http.service": "eventmonitoring_client",
		"traefik.http.routers.eventmonitoring_client_https.service": "eventmonitoring_client",
		"": "5001",
		"traefik.http.middlewares.eventmonitoring_server.stripprefix.prefixes": "/server/dev-acme/event-monitoring",
		"traefik.http.routers.eventmonitoring_server_http.entrypoints": "http",
		"traefik.http.routers.eventmonitoring_server_http.service": "eventmonitoring_server",
		"traefik.http.routers.eventmonitoring_server_http.middlewares": "eventmonitoring_server@docker",
		"traefik.http.routers.eventmonitoring_server_http.rule": "PathPrefix(`/server/dev-acme/event-monitoring`)",
		"traefik.http.routers.eventmonitoring_server_https.entrypoints": "https",
		"traefik.http.routers.eventmonitoring_server_https.service": "eventmonitoring_server",
		"traefik.http.routers.eventmonitoring_server_https.rule": "PathPrefix(`/server/dev-acme/event-monitoring`)",
		"traefik.http.routers.eventmonitoring_server_https.middlewares": "eventmonitoring_server@docker",
		"traefik.http.routers.eventmonitoring_server_https.tls": "true"

Inside your Dockerfile you can use tools like concurrently to run two commands from one command.

RUN npm i -g concurrently
CMD concurrently "serve client/build -l tcp:" "python3 server/"
Providing a service on a raw port

If you want to provide an additional protocol like OPCUA or RPC that can’t use URL paths, we allow you to provide a service through a raw port.
You can add the following to your runSettings object.

	"HostConfig": {
		"PortBindings": {
			"1337/tcp": [
					"HostPort": "1337"

Persisting data inside a volume

You can use docker volumes to persist data between container updates. Add the following object to your runsettings field.

    "Volumes": {
        "/opt/acme/event-monitoring/data": { }

Server side Authentication and API Access

Until now, your app was only available with a fixed IP address and API key (JWT token).

To enable your app to run from anywhere, we provide environment variables to every running docker container.

  • APIBASEURL=http://sicon_backend:1881 - provides access to the REST API

  • MQTT_HOST=sicon_mqtt

  • MQTT_PORT=1883

If you are creating a NodeJS backend app, you can access the environment variable from the process.env. object.

3. Build your Docker image

With the prepared docker files, building the docker image is easy:

docker-compose build

If you want to build for a different version channel, you can use an environment variable or change the compose file.

To build on Linux:

TAG=beta docker-compose build

To build on Windows:

cmd /V /C "set TAG=beta && docker-compose build"

Be aware of your architecture

While you can build a linux docker image on a windows machine, you cannot cross-compile for different architectures. Building on a Raspberry PI (using arm v7) will not be usable on a SICON.OS machine (using x86_64)

4. Export your docker image

Run the following command to export your docker image to a .tar archive.

docker save -o event-monitoring-beta.tar

This can be later uploaded through SICON.OS

5. Import your docker image archive

In your SICON.OS installation, log In as admin and navigate to:

System Settings → My Apps → Installed Apps.

  1. Click on “Create new App for development” to open the dialog.

2. Fill out the form.

  • Vendor is the namespace where all apps belong to; this can be your company name for example

  • Container Name is the name displayed in the sidebar

  • Icon can be chosen from a preset of material icons

  • Docker Run Settings are explained in above section

  • Docker Image Archive is where you can upload your .tar file

Click “Save” and your App gets created. Depending on the size of your App and network bandwidth, this might take a few minutes.

The upload supports apps with a maximum size of 2 GB.

Once done, your App will be added to the sidebar.