SORBA SDE
The SORBA Smart Data Engine (SDE) is an industrial data collection/gateway device capable of Advanced Edge Analytics & Machine Learning Edge Processing. SORBA-SDE is equipped with multiple communication driver/protocol applicable to the industrial market. The SORBA-SDE is a sensor/hardware agnostic device that serves as your point & click gateway capable of talking to multiple devices in real-time. The SDE provides easy access to equipment for troubleshooting and remote programming support for PLCs & HMIs utilizing a hassle-free easy, set-up approach to your assets.
Image details
Configuration
TypeComposelinuxsorbotics/sorba-sde:latest443:443/tcp502:502/tcp1883:1883/tcp49321:49321/tcp/opt : sde-volumealwaysInstallation
- Ensure both Docker and Portainer are installed, and up-to-date
- Log into your Portainer web UI
- Under Settings → App Templates, paste the below URL
- Head to Home → App Templates, and the list of apps will show up
- Select the app you wish to deploy, fill in any config options, and hit Deploy
Template Import URL
https://raw.githubusercontent.com/Lissy93/portainer-templates/main/templates.json
Show Me
docker run -d --name sde \
-p 443:443/tcp \
-p 502:502/tcp \
-p 1883:1883/tcp \
-p 49321:49321/tcp \
-v sde-volume:/opt \
--restart=always \
sorbotics/sorba-sde:latestIf the stack expects env vars, set them or add them to a .env file first.
services:
sde:
image: sorbotics/sorba-sde:latest
container_name: my-sde
cap_add:
- NET_ADMIN
restart: always
volumes:
- sde-volume:/opt
ports:
- 443:443/tcp
- 502:502/tcp
- 1883:1883/tcp
- 49321:49321/tcp
sysctls:
- net.ipv4.ip_forward=1
networks:
- sorbotics
volumes:
sde-volume:
driver: local
networks:
sorbotics:Or, use the original compose file, straight from the template repo. Deploy with:
git clone https://github.com/portainer/templates
cd templates
docker compose -f edge/sorba-sde/docker-compose.yml up -dSave this file as sorba-sde-stack.yml, then from a manager node, run docker stack deploy -c sorba-sde-stack.yml sorba-sde
version: '3.8'
services:
sorba-sde:
image: sorbotics/sorba-sde:latest
ports:
- 443:443/tcp
- 502:502/tcp
- 1883:1883/tcp
- 49321:49321/tcp
volumes:
- sde-volume:/opt
deploy:
restart_policy:
condition: any
Save each file below into a folder, then run kubectl apply -f .
Written for k3s, but works on any cluster: bind mounts use hostPath, named volumes get a
persistent volume claim, and ports are exposed via a LoadBalancer service.
sorba-sde-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: sorba-sde
labels:
app: sorba-sde
spec:
replicas: 1
selector:
matchLabels:
app: sorba-sde
template:
metadata:
labels:
app: sorba-sde
spec:
containers:
- name: sorba-sde
image: sorbotics/sorba-sde:latest
ports:
- containerPort: 443
protocol: TCP
- containerPort: 502
protocol: TCP
- containerPort: 1883
protocol: TCP
- containerPort: 49321
protocol: TCP
volumeMounts:
- name: sorba-sde-data-0
mountPath: /opt
volumes:
- name: sorba-sde-data-0
hostPath:
path: sde-volume
sorba-sde-service.yaml
apiVersion: v1
kind: Service
metadata:
name: sorba-sde
spec:
type: LoadBalancer
selector:
app: sorba-sde
ports:
- name: 443-tcp
port: 443
targetPort: 443
protocol: TCP
- name: 502-tcp
port: 502
targetPort: 502
protocol: TCP
- name: 1883-tcp
port: 1883
targetPort: 1883
protocol: TCP
- name: 49321-tcp
port: 49321
targetPort: 49321
protocol: TCP
Save this file as ~/.config/containers/systemd/sorba-sde.container
[Unit]
Description=SORBA SDE
[Container]
Image=sorbotics/sorba-sde:latest
ContainerName=sorba-sde
PublishPort=443:443/tcp
PublishPort=502:502/tcp
PublishPort=1883:1883/tcp
PublishPort=49321:49321/tcp
Volume=sde-volume:/opt
[Service]
Restart=always
[Install]
WantedBy=default.targetThen reload systemd and start the service:
systemctl --user daemon-reload
systemctl --user start sorba-sdeFor a system-wide service, use /etc/containers/systemd/ and drop --user.
For more installation options, see the Documentation in our GitHub repo
Install SORBA Smart Data Engine in Docker
The SORBA Smart Data Engine (SDE) is an industrial data collection/gateway device capable of Advanced Edge Analytics & Machine Learning Edge Processing. SORBA-SDE is equipped with multiple communication driver/protocol applicable to the industrial market. The SORBA-SDE is a sensor/hardware agnostic device that serves as your point & click gateway capable of talking to multiple devices in real-time. The SDE provides easy access to equipment for troubleshooting and remote programming support for PLCs & HMIs utilizing a hassle-free easy, set-up approach to your assets.Introduction
This document will help you install the SORBA SDE container in your environment (Windows, macOS, or Linux).To get started, you will need:
- A machine with at least 6 CPU cores (AMD64 architecture) and 16GB of RAM.
- The latest version of Docker Engine or Docker Desktop installed and working.
- Administrative access to the machine that will host your SORBA SDE instance.
- By default, SORBA SDE will expose the UI over port 443 (HTTPS), port 502 (Modbus TCP) for the internal Modbus TCP Server, port 1883 (MQTT) for the internal MQTT Broker, and port 49321 for the OPC UA server. You can choose whether to expose these ports or not; the only required port mapping is 443.
Deployment
Create a volume to persist your SDE data:docker volume create my-sde-dataDownload and install the SORBA SDE container:
docker run -d -p 443:443 -p 502:502 -p 1883:1883 -p 49321:49321 --name my-sde -v my-sde-data:/opt --restart=always --cap-add=NET_ADMIN sorbotics/sorba-sde:latestSORBA SDE has now been installed. You can check to see whether the SDE container has started by running
docker ps:root@server:~# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
20538a4c0557 sorbotics/sorba-sde "/usr/bin/supervisor…" 1 minute ago Up 60 seconds 0.0.0.0:1883->1883/tcp, :::1883->1883/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp my-sdeDeploy an SDE with docker compose
You may optionally define the SORBA SDE deployment fromdocker-compose.yml fileCreate a file named
docker-compose.yml and put the following content:services:
sde:
image: sorbotics/sorba-sde:latest
container_name: my-sde
cap_add:
- NET_ADMIN
restart: always
volumes:
- sde-volume:/opt
# - /path/to/your-own-renamed-certs:/etc/nginx/cert/
ports:
- 443:443/tcp
- 502:502/tcp
- 1883:1883/tcp
- 49321:49321/tcp
sysctls:
- net.ipv4.ip_forward=1
networks:
- sorbotics
volumes:
sde-volume:
driver: local
networks:
sorbotics:Then execute the following command in the same path where you created the
docker-compose.yml file:docker compose up -dLogging In
Now that the installation is complete, you can log into your SORBA SDE instance by opening a web browser and going to:https://localhostReplace localhost with the relevant IP address or FQDN if needed, and adjust the port if you changed mapped ports earlier.
You can use the following credentials to sign in SORBA SDE:
- Username:
admin - Password:
adminpwd
Setting up custom port mapping
If your server is using default ports or you want to change the default ports mapped to your host, you can define your desired ports in thedocker run ... command:docker run -d -p 8443:443 -p 502:502 -p 1883:1883 -p 49321:49321 --name my-sde -v my-sde-data:/opt --restart=always --cap-add=NET_ADMIN sorbotics/sorba-sde:latestIf you run the command above you would navigate to
https://localhost:8433 because 8443 represents the mapped port to your server host.You can also change mapped ports for OPC UA and Modbus TCP but you will need to update your device configuration in your SDE.
Setting up custom volume mapping
You have the option to map a custom volume on the host system. Although the Dockerfile already defines a persistent directory managed by Docker through theVOLUME instruction, you can override this behavior by specifying a custom volume when launching the container.You will need a volume with default information. To initialize a volume with default data, you can create a temporary container to extract the required default information from our SDE image:
docker create --name temp-sde-container sorbotics/sorba-sde:latestThen copy the default data in
/opt from your temporary container to your desired location in your local machine:docker cp temp-sde-container:/opt /path/to/custom/volumeDelete your temp container once the data has been extracted:
docker rm -f temp-sde-containerRun your SDE with custom volume mapping:
docker run -d -p 443:443 -p 502:502 -p 1883:1883 -p 49321:49321 -v /path/to/custom/volume:/opt --name my-sde --restart=always --cap-add=NET_ADMIN sorbotics/sorba-sde:latestImportant
If you're running Docker on Windows, it is highly recommended to use Docker-managed volumes rather than bind mounts (e.g., ./path/to/volume:/opt). Bind mounts can lead to Poor performance and Unexpected behavior.Setting up custom SSL certificates
Using docker run
If you don’t know the container name, list all running containers:docker psExample output:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
cf7024f52313 sorbotics/sorba-sde:10.7.1 "/init.sh" About an hour ago Up About an hour 0.0.0.0:80->80/tcp, [::]:80->80/tcp, 0.0.0.0:443->443/tcp, [::]:443->443/tcp, 0.0.0.0:502->502/tcp, [::]:502->502/tcp, 0.0.0.0:1883->1883/tcp, [::]:1883->1883/tcp, 0.0.0.0:49321->49321/tcp, [::]:49321->49321/tcp my-sde-custom-cert- Look for the container using the Sorba SDE image
- The value under the NAMES column is the container name
In this guide, we will use: my-sde-custom-cert (Sorba SDE container)Step 1: Prepare Certificate Files on the Host
Before copying files into the container, place your SSL certificate and key on the host machine.Recommended directory:
/home/sdc/custom-certs/Expected files:
client.crt→ SSL certificateclient.key→ Private key
Example:
/home/sdc/custom-certs/client.crt
/home/sdc/custom-certs/client.keyNotes:
- Ensure files are valid and not corrupted
- Permissions should allow Docker to read them:
chmod 664 /home/sdc/custom-certs/client.crt
chmod 664 /home/sdc/custom-certs/client.keyStep 2: Copy Certificate Files into the Sorba SDE Container
Use the following commands to copy the new certificate and private key into the container:docker cp /home/sdc/custom-certs/client.crt my-sde-custom-cert:/opt/sdc/ssl/certs/sorbaai-ss-cert.crtdocker cp /home/sdc/custom-certs/client.key my-sde-custom-cert:/opt/sdc/ssl/certs/sorbaai-ss-key.keyStep 3: Restart NGINX Service
After updating the certificate files, restart the NGINX service inside the container:docker exec my-sde-custom-cert supervisorctl restart http-serverStep 4: Verify the Changes
Option 1: Browser
- Open your application using HTTPS
- Check certificate details in the browser
Option 2: CLI
openssl s_client -connect <your-domain>:443Troubleshooting
Certificates not applied
- Verify file paths in NGINX configuration
- Confirm files exist inside container:
docker exec -it my-sde-custom-cert ls -l /opt/sdc/ssl/certs/Permission issues
docker exec -it my-sde-custom-cert chmod 644 /opt/sdc/ssl/certs/sorbaai-ss-cert.crt
docker exec -it my-sde-custom-cert chmod 644 /opt/sdc/ssl/certs/sorbaai-ss-key.keyUsing docker compose
Prerequisites
- Docker and Docker Compose installed (v2+ required for
docker compose cp) - Access to the host server
- SSL certificate files (
.crtand.key) - The following Sorba SDE deployment:
services:
sde:
image: sorbotics/sorba-sde:latest
container_name: my-sde-custom-cert
cap_add:
- NET_ADMIN
restart: always
volumes:
- sde-volume:/opt
ports:
- 443:443/tcp
- 502:502/tcp
- 1883:1883/tcp
- 49321:49321/tcp
sysctls:
- net.ipv4.ip_forward=1
networks:
- sorbotics
volumes:
sde-volume:
driver: local
networks:
sorbotics:Step 1: Deploy the Sorba SDE Container
Start the container:docker compose up -dVerify it is running:
docker compose psStep 2: Prepare Certificate Files on the Host
Place your certificate files on the host:/home/sdc/custom-certs/client.crt
/home/sdc/custom-certs/client.keySet correct permissions:
chmod 664 /home/sdc/custom-certs/client.crt
chmod 664 /home/sdc/custom-certs/client.keyStep 3: Copy Certificate Files into the Container
Copy the certificate and key into the SDE service container:docker compose cp /home/sdc/custom-certs/client.crt sde:/opt/sdc/ssl/certs/sorbaai-ss-cert.crtdocker compose cp /home/sdc/custom-certs/client.key sde:/opt/sdc/ssl/certs/sorbaai-ss-key.keyNotes:
- Destination path inside the container:
``` /opt/sdc/ssl/certs/ ```
- File names must match NGINX configuration:
sorbaai-ss-cert.crt
sorbaai-ss-key.keyStep 4: Restart NGINX Service
Apply the new certificates:docker compose exec sde supervisorctl restart http-serverStep 5: Verify the Changes
Browser
- Open your application via HTTPS
- Check the certificate details
CLI
openssl s_client -connect <your-domain>:443Troubleshooting
Verify files inside the container
docker compose exec sde ls -l /opt/sdc/ssl/certs/Certificates not applied
- Ensure files were copied successfully
- Verify file names match NGINX configuration
- Restart NGINX again
Check logs
docker compose logs sdeFix permissions inside container
docker compose exec sde chmod 644 /opt/sdc/ssl/certs/sorbaai-ss-cert.crt
docker compose exec sde chmod 644 /opt/sdc/ssl/certs/sorbaai-ss-key.keyUpdate SDE to the Latest Docker Image
Depending on how you created the container, the update process will differ slightly. Below are instructions for bothdocker compose and docker run.If using Docker Compose
To update your container to the latest version of the image:docker compose pull
docker compose up -d --force-recreateThis will:
- Pull the latest version of the image from the registry
- Recreate the container with the updated image
- Preserve volumes and environment variables
No manual cleanup is necessary; Docker Compose handles it for you.
If using docker run
Updating containers created with docker run requires a bit more care, especially when it comes to preserving data.✅ Case 1: You used a named volume
If you previously created the container using a named volume, your data is safe and will persist across container recreations. You can reuse the same volume with the updated container (see "Recreate the Container with the Latest Image" below).
⚠️ Case 2: You used an anonymous volume
If the container was created without specifying a volume name, Docker assigned a random volume name, and the data will be lost when the container is removed.
To safely upgrade, follow these steps to migrate data to a new named volume:
- Create a new named volume:
docker volume create my-sde-data- First, check the container name (if not already known):
docker ps- Identify the anonymous volume used:
docker inspect my-sde --format "{{ range .Mounts }}{{ .Source }} => {{ .Destination }} {{ end }}"Look for a volume with a long hash as the Source, something like:
/var/lib/docker/volumes/abc1234567890.../_data => /opt - Copy the data to the new volume using a temporary container:
docker run --rm -v abc1234567890:/from -v my-sde-data:/to alpine sh -c "cp -a /from/. /to/"This command uses a lightweight
alpine container to copy all files from the old volume (abc1234567890) to the new one (my-sde-data).Recreate the Container with the Latest Image
- Pull the latest image:
docker pull sorbotics/sorba-sde:latest- Stop and remove the old container:
docker stop my-sde
docker rm my-sde⚠️ This only removes the container and anonymous volumes, but named volumes will persist.
- Recreate the container using the named volume:
Make sure to reuse the same volume names:
docker run -d -p 443:443 -p 502:502 -p 1883:1883 -p 49321:49321 --name my-sde -v my-sde-data:/opt --restart=always --cap-add=NET_ADMIN sorbotics/sorba-sde:latestSetting a Static MAC Address (Required for Licensed Environments)
If you plan to use a licensed version of SORBA SDE, it’s required to assign a static MAC address to the container. This is because the licensing mechanism is tied to both a persistent MAC address and a serial number.By default, Docker assigns a random MAC address every time the container is recreated unless you explicitly define it.
To ensure the MAC address remains consistent:
Option 1: If you're using docker run ...
If you originally deployed SORBA SDE using a docker run command, you'll need to:- Stop the current container:
docker stop my-sde - Remove the old container:
docker rm my-sde(this does not delete your data if you used a named volume). - Recreate the container using the
--mac-addressflag.
As long as you reuse the same volume (e.g., -v my-sde-data:/opt), your data will remain intact.docker run -d \
--mac-address=XX:XX:XX:XX:XX:XX \
-p 443:443 -p 502:502 -p 1883:1883 -p 49321:49321 \
--name my-sde \
-v my-sde-data:/opt \
--restart=always \
--cap-add=NET_ADMIN \
sorbotics/sorba-sde:latestReplace XX:XX:XX:XX:XX:XX with your desired MAC address. It must be a valid, unique address in your network.Option 2: If you're using Docker Compose
If you are usingdocker-compose.yml, simply add the mac_address field to the service definition:services:
sde:
image: sorbotics/sorba-sde:latest
container_name: my-sde
mac_address: XX:XX:XX:XX:XX:XX
cap_add:
- NET_ADMIN
restart: always
volumes:
- sde-volume:/opt
# - /path/to/your-own-renamed-certs:/etc/nginx/cert/
ports:
- 443:443/tcp
- 502:502/tcp
- 1883:1883/tcp
- 49321:49321/tcp
sysctls:
- net.ipv4.ip_forward=1
networks:
- sorbotics
volumes:
sde-volume:
driver: local
networks:
sorbotics:
driver: bridgeThen apply the changes:
docker compose up -d sde --force-recreateImportant Notes
- The static MAC address will be used to generate and validate your license.
- If the MAC address changes, your license will be invalidated.
- The MAC address must be unique and valid within your network.
- Always ensure the same MAC is used if the container is stopped, updated, or recreated.
- Reusing the same named volume (
-v my-sde-data:/opt) guarantees your data is preserved.
Troubleshooting
- Unable to pull image from Docker Hub (401 Unauthorized)
If you see an error like:failed to authorize: failed to fetch oauth token: 401 UnauthorizedThe image is public, so authentication is not required.
However, if you're logged in with an invalid or unverified Docker Hub account, you might still get this error.
Try one of the following:
# Option 1: Verify your Docker Hub account
# Option 2: Log out to pull as anonymous
docker logout- Unable to Log In Using Default Credentials
Problem: After running the SDE container, you are unable to log in using the default credentials.Solution:
- Ensure your machine has enough resources (CPU, RAM, and disk space).
- Check the container logs to confirm that the SDE container has initialized successfully:
root@server:~# docker logs -f my-sde
Initializing SDE...
Waiting for services...
SDE Initialized!
/usr/bin/supervisord -ns >> /dev/null 2>&1Serve SORBA SDE on your own domain behind Caddy, Nginx or Traefik. Fill in your domain and copy the result. It's a starting point, some apps need their own base URL or extra headers set too.
Proxying sorba-sde.example.com to https://sde:443
Add this to your Caddyfile
sorba-sde.example.com {
reverse_proxy https://sde:443 {
transport http {
tls_insecure_skip_verify
}
}
}Check the logs first
Nine times out of ten the logs tell you exactly what went wrong.
- In Portainer, go to Containers, click the container, then Logs. Or run
docker logs <container> - Exit codes help too:
137means killed, usually out of memory.126or127means the command inside the image is broken.
Port already in use
If deployment fails with "Bind for 0.0.0.0:443 failed: port is already allocated", something else on your server is using that port.
- Find what's using it:
sudo ss -tlnp | grep :443 - Stop the other service, or pick a different host port. In
443:443only the left number is yours to change, the right one belongs to the app.
Running but the page won't load
The container is up but nothing appears in your browser.
- Use your server's real IP:
https://your-server-ip:443. The 0.0.0.0 link Portainer shows isn't a real address. - Give it a minute after first deploy, sde can take a while to initialise.
- Make sure your firewall allows the port, e.g.
sudo ufw allow 443
Image won't pull
Test the pull directly on the host: docker pull sorbotics/sorba-sde:latest
- "manifest unknown" means the tag no longer exists. This template uses
latest, so try pinning a specific version instead. - "toomanyrequests" is the Docker Hub rate limit. Log in with
docker loginto raise it. - "no space left on device" means a full disk. Reclaim space with
docker system prune
"exec format error"
This means the image was built for a different CPU architecture than your server.
- This image supports:
amd64 - Check yours with
uname -m: x86_64 is amd64, aarch64 is arm64. Raspberry Pi and other ARM boards are the usual culprits.
Container keeps restarting
The always restart policy relaunches the app after every crash, so the real error can scroll past.
- Check the logs right after a restart, the last few lines before it died are the useful ones.
- Get the exit code with
docker inspect <container> --format '{{.State.ExitCode}}' - Still stuck? Redeploy once with the restart policy set to
noso the failure stays visible.
Stack won't deploy
Compose stacks fail fast on small mistakes, and Portainer shows the reason just above the editor.
- YAML only accepts spaces for indentation, a single tab breaks the whole file.
Raise an issue
Found something which isn't working as it should? Here's how to report it.
- Bug within the app: Open an issue within sde's repo
- Template not working: Open an issue on portainer/templates
- This website not working: Open an issue on lissy93/portainer-templates