Skip to content
Published on

Deploying OpenTAP in a Docker Container

Categorized
Articles

The OpenTAP team is frequently asked about deploying and running OpenTAP in one or more Docker containers. This blog addresses typical rationale for containerization, steps for implementation, and caveats to observe.

Why Containerize OpenTAP?

OpenTAP is a cross-platform test framework with a full CLI, facilitating headless execution in a container. The OpenTAP project supports containerization and already publishes Docker images for each release (see below).

Rationale for container-based deployment includes

  • Cloneable test stations: In a container, OpenTAP version, plugins, .NET runtime and settings are set in stone, ending test station-based drift and accompanying alignment issues.

  • CI/CD and regression: Test plans can run as pipeline jobs (GitHub Actions, GitLab CI, Jenkins) against simulated or real instruments.

  • Scale and orchestration: Using containers supports parallel runs, remote or lab-wide execution under Kubernetes or another scheduler/orchestrator.

  • Production parity: Developers run the same image(s) deployed on the factory floor.

Benefits of Containerization

There exist many benefits to container-based deployment of OpenTAP, from versioning to fast provisioning to isolation to auditability:

Benefit Use Case
Immutable, versioned environments OpenTAP and plugin versions and settings are baked into Docker image tag; roll back by changing the tag
Fast provisioning A new station or CI runner requires only docker pull -- no installer or manual plugin setup needed
Isolation Conflicting plugin sets or .NET versions can coexist on one host
Small footprint Slim runtime images omit SDK and compilers (the SDK can add up over 2.5 GBs to deployment images)
Auditability The Dockerfile itself documents the exact station configuration for regulated or traceable testing

A Stepwise Guide

You can build and deploy a containerized OpenTAP in just a few steps:

·       Build a runtime container image.

·       Run with parameters passed at run time.

·       Export results before container terminate.

Build a Headless Runtime Image

You can use the official OpenTAP image or build your own over a .NET runtime. Building and customizing your own image is often safer and also lets you choose the latest component versions and/or legacy version that fit your particular configuration.

Create a Dockerfile

Following is a basic working template for creating an OpenTAP-specific Dockerfile.

# Install the latest version of dotnet from Microsoft
FROM mcr.microsoft.com/dotnet/runtime:9.0
RUN apt-get update && apt-get install -y --no-install-recommends curl unzip \
    && rm -rf /var/lib/apt/lists/*

# Install OpenTAP
RUN curl -Lo /tmp/opentap.zip \
      'https://packages.opentap.io/4.0/Objects/Packages/OpenTAP?os=Linux&architecture=x64' \
    && unzip /tmp/opentap.zip -d /opt/tap && rm /tmp/opentap.zip \
    && chmod +x /opt/tap/tap
ENV PATH="/opt/tap:${PATH}"

# Install plugins – using “Demonstration” as example only
RUN tap package install "Demonstration" --version 9.x -y --non-interactive

# Add test plan and settings
COPY plans/ /opt/tap/plans/
COPY Settings/ /opt/tap/Settings/

WORKDIR /opt/tap
ENTRYPOINT ["tap", "run"]
CMD ["plans/MyPlan.TapPlan", "--non-interactive"]
Spacer for layout.

Choose a working test plan

While it is possible to use a Docker deployment as a test plan development environment, you are better served by building and testing a test plan first with GUI-based test plan editor or in a separate command-line environment. 

Accompanying this blog is a short example test plan to use as a starting point (see below).

Build and Run

In a bash shell, perform the following

docker build -t mytest:1.0 .
docker run --rm -v $PWD/results:/opt/tap/Results mytest:1.0 \
  plans/MyPlan.TapPlan -e DUT_IP=192.168.1.50

Use -e Name=Value to set external test plan parameters, so one image can serve many DUTs and configurations, as above for the DUT IP address.

Export Results Data

You will need to mount local or network volumes to save test run results, session logs and result-listener output (CSV, SQLite), or send results to a network database. Data remaining inside the container is lost when the session terminates exits.

Smoke Test

We’ve provided a “smoke test” script that

  • Handles platform details

  • Works in automated CI/CL environments

  • Runs consistently

  • Checks the result

  • Stops when problems are encountered

  • Documents the entire procedure

For readers not familiar with the bash shell, we included two versions of smoketest.sh, at the end of this blog.

Spacer for layout.

Caveats

Container-based deployment of OpenTAP can present a few “gotchas”.  Following are a number of caveats worth calling out, roughly in order of how often they cause trouble:

Hardware and platform

Linux OS: This blog assumes that you will build and run your container on an x64-based Linux system. OpenTAP supports Ubuntu 24.04 and above, but you should be able to create and deploy a Docker image on the Linux host, distribution, version of your choice.

Non-Linux OS: Options exist for Windows and macOS using Docker Desktop, with very specific caveats:

  • M-Series Mac – prebuilt Dockerfiles assume x64 and until macOS 27, OpenTAP can run under emulation.  Native M-Series execution requires rebuilding OpenTAP with architecture=arm64.

  • VM -based execution - on both Windows and macOS, Docker Desktop runs your containers inside a Linux virtual machine: WSL2 or Hyper-V on Windows, and Apple’s virtualization framework on a Mac, causing many of the following issues.

  • USB and GPIB – on macOS, containers can’t see USB instruments at all. On Windows, those devices may require reconnection after reboots and other changes to VM state.

  • Networking – containers sit behind NAT inside the VM, raising issues with reaching LAN-based instruments across subnets, port mapping and auto-discovery.

  • Hostnames – mDNS names that resolve on a Mac or PC generally don’t resolve inside containers. Use IP addresses or --add-host.

  • Bash vs. PowerShell – files and scripts created under Windows may generate error inside a Linux container from differing EOL formats.

  • Permissions - File ownership and permissions may behave unexpectedly across the platforms.

Plugins may not run on Linux: Many OpenTAP plugins and instrument drivers are Windows-only (e.g., WPF UI, Windows DLLs, vendor drivers). Check the available hosting and CPU architecture for each package before attempting to integrate.

USB and GPIB can be fragile in containers: Device passthrough breaks on hot-plug or re-enumeration. On Docker Desktop for Windows or macOS, USB passthrough and --network host don’t behave like they do on native Linux.

CPU architecture: x64 and ARM64 need separate images. The Dockerfile above is x64 only.

Timing-sensitive steps: Containers add little overhead, but they do share host CPU with other workloads. Validate timing-critical measurements on the intended host.

Instrument connectivity (the hardest part)

Validate with simulated instruments first, then begin using actual instruments and DUTs.

  • LAN instruments: (SCPI sockets, HiSLIP, VXI-11) are easiest. Use --network host or make sure the container can route to the instrument subnet.

  • USB and GPIB: need device passthrough (--device /dev/usbtmc0 or /dev/bus/usb, sometimes --privileged), a Linux VISA library in the image, and drivers that support Linux.

Licensing and support

Node-locked licenses tied to a host ID or MAC address can break whenever a container is recreated. For commercially-licensed software, a floating or network license server is usually the right fit; confirm with Keysight for each plugin. License terms may also not cover container use, so confirm with Keysight and other commercial vendors before rollout.

Operations and Security

  • Data is lost without volumes: Results, session logs, and changed settings vanish when the container exits.

  • Segregate station-specific state: Calibration files, instrument addresses, and credentials belong in mounted config or secrets, not baked into the image.

  • --privileged and root: Privileged mode gives broad access to the host, so prefer specific --device flags and a non-root user.

  • No GUI: Debugging a failing plan is harder headless, so prototype using a visual test plan editor and deploy with rich logging.

  • Resources and timing: With Docker Desktop, VM-based execution has fixed CPU and memory.  Moreover, when a desktop computer sleeps, the VM-based clock can drift, stalling execution and/or losing network connections.  Importantly, time-sensitive tests can fail due to running through VM layers.

  • Unattended hardware safety. Running plans remotely on high-power or hazardous setups needs proper interlocks, because no operator is present.

Conclusion

Containerizing OpenTAP takes just a few steps: install OpenTAP and your plugins on a .NET runtime base, add your test plans, and run them headless with tap run. The result is a versioned, portable image that turns a hand-built test station into something you can rebuild, share and trust. With containerization, every station and CI runner runs the same environment, new stations spin up with a single docker pull, conflicting plugin sets stay neatly isolated, and rolling back is as easy as changing a tag. Start with a simple smoke test, and you’ll quickly find that Docker makes OpenTAP test automation easier to reproduce, scale and share across your team.

Red line spacer image.