This repository provides a step-by-step guide to build and deploy a containerized TwinCAT 3.1 XAR runtime environment using Docker on a Beckhoff IPC.
With this sample, you will learn how to:
- Build and configure a TwinCAT XAR container image.
- Set up secure communication using ADS-over-MQTT.
- Manage containers with Docker Compose and Makefile automation.
- Connect to the containerized TwinCAT runtime with TwinCAT Engineering.
- Configure real-time Ethernet communication (optional).
Here’s a high-level overview of what the completed setup will look like:
Should you have any questions regarding the provided sample code, please contact your local Beckhoff support team. Contact information can be found on the official Beckhoff website at https://www.beckhoff.com/contact/.
Before you begin, make sure your environment meets the following prerequisites:
Beckhoff IPC as Beckhoff RT Linux host:
- Setup and Install the Beckhoff Real-Time Linux® Distribution on a supported IPC.
- Configure access to Beckhoff package server
- Install the required host packages from the default Debian package sources:
sudo apt update
sudo apt install --yes docker.io docker-compose make tcsysconfWindows Engineering PC:
- A separate Windows PC with TwinCAT 3 Engineering (XAE) installed to connect to and program the containerized runtime.
- Network connectivity between the Windows PC and the Beckhoff IPC running Beckhoff RT Linux.
Beckhoff Account:
- Valid myBeckhoff credentials to access the Beckhoff package server at
https://deb.beckhoff.com.
Note: This sample is designed for Beckhoff Industrial PCs running Beckhoff Real-Time Linux. While the Docker image may build on generic Debian systems, real-time functionality and hardware access require Beckhoff-supported hardware and the RT Linux distribution.
Unless a step explicitly says otherwise, run the Linux commands below on the Beckhoff IPC running Beckhoff RT Linux from the repository root directory.
Once the prerequisites are in place, you can follow these steps to build and deploy the TwinCAT XAR container:
During the image build process, TwinCAT for Linux® will be downloaded from https://deb.beckhoff.com.
a. Edit ./tc31-xar-base/apt-config/bhf.conf and replace <mybeckhoff-mail> and <mybeckhoff-password> with your valid myBeckhoff credentials:
nano ./tc31-xar-base/apt-config/bhf.confDo not commit this file with real credentials.
b. Build the Docker image. You can use the Makefile wrapper (recommended) or the direct docker command:
Option A: Using Makefile (from repository root)
sudo make build-imageOption B: Using docker directly
cd tc31-xar-base
sudo docker build --secret id=apt,src=./apt-config/bhf.conf --network host -t tc31-xar-base .
cd .. # Return to repository root for subsequent stepsc. Verify the image was built successfully:
sudo docker imagesYou should see an entry with repository tc31-xar-base and tag latest in the output.
On the Beckhoff IPC running Beckhoff RT Linux that will run Docker, allow incoming TCP connections to the Mosquitto broker on port 1883 so ADS-over-MQTT can reach the sample.
Create /etc/nftables.conf.d/60-mosquitto-container.conf with the following content:
sudo nano /etc/nftables.conf.d/60-mosquitto-container.conf
table inet filter {
chain input {
tcp dport 1883 accept
}
chain forward {
type filter hook forward priority 0; policy drop;
tcp sport 1883 accept
tcp dport 1883 accept
}
}
Save the file by pressing Ctrl+o and Enter. Then close the editor via Ctrl+x and Enter.
Apply the rules by reloading the Beckhoff RT Linux nftables configuration, which already includes /etc/nftables.conf.d/*:
sudo systemctl reload nftablesVerify the rules were applied:
sudo nft list rulesetYou should see rules that reference TCP port 1883 in the output, especially the tcp dport 1883 accept rule and the corresponding forward-chain entries.
Because reloading nftables flushes the Docker-managed firewall rules, restart the Docker service afterwards so Docker can recreate its network rules before you start the sample containers:
sudo systemctl restart dockerThe sample includes a docker-compose.yaml file to simplify the process of creating a container network and starting the MQTT broker as well as the TwinCAT runtime container.
From the repository root directory, start the containers:
sudo docker compose up -dOr using the Makefile:
sudo make run-containersVerify the containers are running:
sudo docker compose ps
# Or: sudo make list-containersYou should see both mosquitto and tc31-xar-base containers with status "Up". Check the logs if any container is not running:
sudo docker compose logs
# Or: sudo make container-logsIf sudo docker compose up -d reports pull access denied for tc31-xar-base, go back to Step 1 and confirm that the local image tc31-xar-base:latest was built successfully. The Compose file expects that image to exist locally before the sample is started.
At this point, the Linux-host side of the sample is ready. The remaining ADS-over-MQTT setup moves to the Windows engineering PC, except for the quick host-IP lookup in step 4(a).
To connect your TwinCAT Engineering system (running on Windows) via ADS-over-MQTT with the containerized TwinCAT runtime:
a. On your Beckhoff IPC running Beckhoff RT Linux, list the network interfaces and their IP addresses:
ip --brief addressIn the output, look for the network interface that your Windows engineering PC can reach. Use its IPv4 address from the inet column when updating mqtt.xml. If the Beckhoff IPC has multiple network interfaces, choose the one that is connected to the same network as your Windows engineering PC.
b. On your Windows engineering PC, edit the mqtt.xml template from this repository. Replace ip-address-of-container-host with the IP address from step (a) — this is the IP address of your Beckhoff IPC running Beckhoff RT Linux and Docker.
c. Copy the edited mqtt.xml file to:
C:\Program Files (x86)\Beckhoff\TwinCAT\3.1\Target\Routes\
d. Restart the TwinCAT System Service on Windows (right-click the TwinCAT icon in the system tray → Config).
e. The containerized TwinCAT runtime should appear as an available target system in TwinCAT Engineering. In the default sample configuration, look for the target that uses AMS Net ID 15.15.15.15.1.1.
Troubleshooting: If the target does not appear:
- Verify the Beckhoff IPC running Beckhoff RT Linux is reachable from the Windows engineering PC
- Verify the containers are running:
sudo docker compose pson the Beckhoff IPC running Beckhoff RT Linux - Check container logs:
sudo docker compose logs - Use another MQTT client on Windows, such as MQTT Explorer, to check whether TwinCAT for Linux and the TwinCAT Engineering side have connected to the broker
Note: This step is only required if you plan to use EtherCAT or other real-time Ethernet protocols with TwinCAT.
Real-time Ethernet communication requires the vfio-pci driver for a PCI-based network device. Use the command line tool TcRteInstall to assign the vfio-pci driver to network devices of the IPC.
Warning: A network device bound to vfio-pci will no longer be available for standard Linux networking. Do not bind your primary network interface if you rely on it for remote access.
-
List available network devices for real-time Ethernet communication:
sudo TcRteInstall -l
-
Assign the
vfio-pcidriver by passing the PCI deviceLocationof the network interface you want to dedicate to TwinCAT:sudo TcRteInstall -b <PCI device Location>
For example:
sudo TcRteInstall -b 0000:02:00.0Choose a device that is not being used for your primary network connection to avoid losing connectivity to the host.
-
Verify the assignment:
sudo TcRteInstall -l
The output should now show
vfio-pciin theDrivercolumn for the device you configured. -
For TwinCAT to detect the new configuration, restart the TwinCAT runtime container:
sudo make restart-containers
Or using docker compose directly:
sudo docker compose restart tc31-xar-base
Advanced: By default, the container will probe all available PCI network devices bound to vfio-pci. You can control this behavior by setting the PCI_DEVICES environment variable in docker-compose.yaml. See the comments above the environment: section in that file for details on setting PCI_DEVICES to NONE or an explicit list of PCI addresses.
This repository includes a Makefile with shortcuts for common Docker operations. Run make help to see all available targets:
make helpAvailable targets:
build-image— Build the TwinCAT container imagepush-image— Push the TwinCAT container image to a registryrun-containers— Start containers using Docker Composerestart-containers— Restart containerslist-containers— List all containers managed by Docker Composestop-and-remove-containers— Stop and remove containerscontainer-logs— Show logs for all containers
Example:
sudo make build-image
sudo make run-containers
sudo make container-logs