{"id":1678,"date":"2026-06-24T12:13:10","date_gmt":"2026-06-24T10:13:10","guid":{"rendered":"https:\/\/www.rocworks.at\/wordpress\/?p=1678"},"modified":"2026-06-24T14:12:07","modified_gmt":"2026-06-24T12:12:07","slug":"developing-with-wincc-oa-in-docker-containers","status":"publish","type":"post","link":"https:\/\/www.rocworks.at\/wordpress\/?p=1678","title":{"rendered":"Developing with WinCC OA in Docker Containers"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">Running industrial SCADA systems on developer machines can sometimes lead to a cluttered host operating system, dependency conflicts, or difficulties in managing multiple software versions. <strong>WinCC Open Architecture (WinCC OA)<\/strong> is a powerful platform, and running it inside a Docker container for development is an elegant solution to these challenges.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this post, we&#8217;ll walk through how to build a WinCC OA container image on your favorite Linux OS (like Ubuntu) and use a convenient access script to keep your projects organized and run GUI tools like the Console and Project Manager seamlessly.<\/p>\n\n\n<p><!-- wp:heading level --><\/p>\n<h2>Step 1: Building the WinCC OA Docker Image<\/h2>\n<p><!-- \/wp:post-content --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Before running the container, we need to build the Docker image. Navigate to the directory where you downloaded and extracted the WinCC OA installation files (which should also contain your <code>Dockerfile<\/code>), and run the following command:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:preformatted --><\/p>\n<pre class=\"wp-block-preformatted\">docker build --build-arg USER_ID=$(id -u) --build-arg USER_GID=$(id -g) --build-arg USER=$(whoami) --build-arg BASE_IMAGE=debian:trixie -t winccoa321 .<\/pre>\n<p><!-- \/wp:preformatted --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p><strong>Why these build arguments?<\/strong> By matching the container&#8217;s user ID and group ID with your host user, we avoid file permission issues when editing files and mapping project volumes.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading level --><\/p>\n<h2>Step 2: Managing the Container with <code>winccoa.sh<\/code><\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>To automate starting, stopping, and entering the container, we use a custom shell script called <code>winccoa.sh<\/code>. This script takes care of several important development tasks:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:list --><\/p>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul><!-- wp:list-item -->\n<li><strong>Persistent Container Lifecycle:<\/strong> It checks if the container already exists. If it is stopped, it starts it. If it doesn&#8217;t exist, it creates a new one using the <code>winccoa321<\/code> image. Since the container runs with <code>sleep infinity<\/code>, it remains active in the background.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>Volume Mapping:<\/strong> Your host user home directory is mounted to the container (<code>-v \"$HOME:\/home\/$USER:rw\"<\/code>). This ensures your projects, configurations, and license files persist on the host system and can be edited with your favorite host IDEs (like VS Code).<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<ul>\n<li style=\"list-style-type: none;\">\n<ul>\n<li><strong>Reusable Sessions:<\/strong> You can run the script to enter the running container terminal via <code>docker exec -it winccoa bash<\/code>, perform your tasks, and exit without stopping the container or losing state.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><!-- \/wp:list-item --><\/p>\n<p><!-- \/wp:list --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p><strong>Note on configuration using a <code>.env<\/code> file:<\/strong> The script checks if a <code>.env<\/code> file exists in its directory and loads its environment variables (using <code>set -a<\/code> and <code>source<\/code>). This allows you to easily customize variables such as <code>CONTAINER_NAME<\/code>, <code>WCC_OA_IMAGE<\/code>, or <code>WCC_OA_VERSION<\/code> without having to modify the shell script itself.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Here is the full <code>winccoa.sh<\/code> script:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:code --><\/p>\n<pre class=\"wp-block-code\"><code>#!\/bin\/bash\n\n# WinCC OA Container Access Script\n# Provides terminal access to the WinCC OA Docker container with volume mapping\n\nset -e\n\nSCRIPT_DIR=\"$(cd \"$(dirname \"${BASH_SOURCE[0]}\")\" &amp;&amp; pwd)\"\n\n# Default configuration\nCONTAINER_NAME=\"${1:-winccoa}\"\nWCC_OA_IMAGE=\"${WCC_OA_IMAGE:-winccoa321}\"\nWCC_OA_VERSION=\"${WCC_OA_VERSION:-3.21}\"\nHOME_DIR=\"\/home\/$USER\"\n\n# Load .env file if it exists\nif [ -f \"$SCRIPT_DIR\/.env\" ]; then\n    set -a\n    source \"$SCRIPT_DIR\/.env\"\n    set +a\nfi\n\n# Colors for output\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\necho -e \"${GREEN}WinCC OA Container Access${NC}\"\necho \"======================================\"\necho \"Container: $CONTAINER_NAME\"\necho \"\"\n\n# Check if Docker is running\nif ! docker info &gt; \/dev\/null 2&gt;&amp;1; then\n    echo -e \"${RED}Error: Docker daemon is not running${NC}\"\n    exit 1\nfi\n\n# Check if container exists using docker inspect\nif docker inspect $CONTAINER_NAME &gt; \/dev\/null 2&gt;&amp;1; then\n    echo -e \"${GREEN}\u2713 Container exists${NC}\"\n\n    # Check if it's running\n    if [ \"$(docker inspect -f '{{.State.Running}}' $CONTAINER_NAME)\" = \"true\" ]; then\n        echo -e \"${GREEN}\u2713 Container is running${NC}\"\n    else\n        echo -e \"${YELLOW}Starting existing container...${NC}\"\n        docker start $CONTAINER_NAME\n        echo -e \"${GREEN}\u2713 Container started${NC}\"\n    fi\nelse\n    echo -e \"${YELLOW}Container does not exist, creating new one...${NC}\"\n    docker create \\\n        --name $CONTAINER_NAME \\\n        --network host \\\n        --entrypoint sleep \\\n        -e OAINST=\/opt\/WinCC_OA\/$WCC_OA_VERSION \\\n        -e LANG=en_US.UTF-8 \\\n        -e LANGUAGE=en_US:en \\\n        -e LC_ALL=en_US.UTF-8 \\\n        -e DISPLAY=:0 \\\n        -e PATH=\/opt\/WinCC_OA\/$WCC_OA_VERSION\/bin:\/usr\/local\/sbin:\/usr\/local\/bin:\/usr\/sbin:\/usr\/bin:\/sbin:\/bin \\\n        -v \"$HOME_DIR:\/home\/$USER:rw\" \\\n        $WCC_OA_IMAGE infinity &gt; \/dev\/null\n\n    docker start $CONTAINER_NAME\n    echo -e \"${GREEN}\u2713 Container created and started${NC}\"\nfi\n\necho \"\"\necho -e \"${GREEN}Entering container terminal...${NC}\"\necho \"Type 'exit' to return to this shell (container will keep running)\"\necho \"Volume mapped: $HOME_DIR\"\necho \"======================================\"\necho \"\"\n\n# Execute bash in container (container stays running when you exit)\ndocker exec -it $CONTAINER_NAME bash\n\necho \"\"\necho -e \"${GREEN}Bash session ended (container is still running)${NC}\"\n<\/code><\/pre>\n<p><!-- \/wp:code --><\/p>\n<p><!-- wp:heading level --><\/p>\n<h2>Step 3: Running Graphical Tools (Console &amp; Project Manager)<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>WinCC OA relies on graphical interfaces for project management and engineering. The script passes your host&#8217;s <code>DISPLAY<\/code> environment variable and network configuration to the container so that X11 applications can render on your host screen.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>However, X11 security will block the container from connecting by default. To authorize the container, <strong>you must run the following command in a terminal session on your host machine before starting GUI tools<\/strong>:<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:preformatted --><\/p>\n<pre class=\"wp-block-preformatted\">xhost +<\/pre>\n<p><!-- \/wp:preformatted --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Once authorized, you can run commands like <code>startPA<\/code> inside the container, and the Project Manager window will appear on your desktop as if it were running natively.<\/p>\n<p><!-- \/wp:paragraph --><\/p>\n<p><!-- wp:heading level --><\/p>\n<h2>Summary<\/h2>\n<p><!-- \/wp:heading --><\/p>\n<p><!-- wp:paragraph --><\/p>\n<p>Running WinCC OA in a container gives you a clean, isolated environment for SCADA development. Volume mapping keeps your code safe on the host machine, and X11 forwarding gives you access to the full suite of graphical development tools without the overhead of a virtual machine.<\/p>\n<p><!-- \/wp:paragraph --><\/p>","protected":false},"excerpt":{"rendered":"<p>Running industrial SCADA systems on developer machines can sometimes lead to a cluttered host operating system, dependency conflicts, or difficulties in managing multiple software versions. WinCC Open Architecture (WinCC OA) is a powerful platform, and running it inside a Docker &hellip; <a href=\"https:\/\/www.rocworks.at\/wordpress\/?p=1678\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1678","post","type-post","status-publish","format-standard","hentry","category-allgemein"],"_links":{"self":[{"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1678","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1678"}],"version-history":[{"count":4,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1678\/revisions"}],"predecessor-version":[{"id":1683,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=\/wp\/v2\/posts\/1678\/revisions\/1683"}],"wp:attachment":[{"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1678"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1678"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocworks.at\/wordpress\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1678"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}