Docker Tutorial: How to Create and Run Helix QAC as a Container
In this Docker tutorial, you will learn how to create and run Helix QAC as a containerized image.
The basic definition of Docker is an open-source and popular operating-system-level virtualization (commonly known as “containerization”) technology that is lightweight, portable, and primarily runs on Linux and Windows. Docker makes it easier to create, deploy, and run applications by using containers.
Fundamentally, a container is just a running process with some added encapsulation features applied to it. With containers, developers (and DevOps administrators) can package an application with everything needed to run the application — including code, run-time, libraries, configured environment variables, and configuration files — and ship it all out as one package.
It is also worth mentioning that Docker can start up instantly and has built-in mechanisms for versioning and component reusable. These docker containers can be shared via the public Docker Hub or private repository — making them accessible and easy to use.
Here are some of the most notable benefits of Docker:
- Rapid Deployment: Docker can create a container for each process, which can then be spun up and torn down quickly on demand and without the need to boot a Platform Operating System (OS). This decreases deployment process time to seconds In addition, the Docker image spin-up is almost instantaneous.
- Portability: Docker enables a tested containerized application to be deployed to any other system where Docker is running and be sure that it will perform exactly as it did when you tested it. The Docker image can be shared with other teams.
- Performance: Although virtual machines (VMs) are an alternative to the containers, VMs have an OS whereas Docker containers do not. This means that containers have a smaller footprint than the VMs, are faster to create, and have faster spin-up and tear-down times.
- Continuous Integration Efficiency: Docker enables you to build a container image and use it across every step of the deployment process from development and testing to deployment. In addition, you to separate non-dependent steps and run them in parallel, which shortens the length of time it takes from the build phase to the production deployment phase. This reduces the amount of time to set up the environments and debug environment-specific issues — making them more reliable and easier to maintain.
However, there are some limitations to Docker, and even though they have a low to zero impact on the setup of the static analyzer for Docker, it is nevertheless important for you to be aware of them.
- Docker Is not a Substitute for Virtual Machine: Many apps that run in VM can be moved into a container, but that doesn’t mean all of them can or should be. For instance: Industries with heavy regulatory requirements might not be able to swap containers for VMs as VMs provide more isolation than containers.
- The Data in the Container: There are times when a container does go down, and in that instance, it needs a backup and recovery strategy. Although there are several solutions, none are automated or not yet scalable. Another limitation is that unless you save it somewhere first before the container goes down, all the data inside disappears forever when it shuts down.
- Cross-Platform Compatibility: This is a major issue if an application is designed to run in a Docker container on a particular platform — such as Windows OS platform or Linux — as it cannot run on any other platform. However, Virtual Machines are not subject to this limitation, so this limitation makes Docker less attractive to some highly heterogeneous environments that are composed of both Windows and Linux servers.
- Run Applications with Graphical Interfaces: In general, Docker is designed for hosting applications that run on the command line. Though we have a few ways (like using X11 forwarding or MobaXterm) by which we can make it possible to run a graphical interface inside a Docker container, these processes are clunky. Therefore, we can say that Docker is not a good solution for applications that require rich interfaces.
To help with the setup of the static analysis tool as Docker and some work around these limitations, I will break down the setup into three easy parts.
A great starting point to get started would be from this site https://docs.docker.com/get-started/overview, which has plenty of details about setting up the Docker Engine and then how you validate the environment of its proper setting.
📕 Related Resource: Learn more about Rocky Linux.
PART I: Prepare Docker Engine
- Download and install the Docker Engine for your operating system (OS) platform of choice from this site: https://docs.docker.com/engine/install
- To verify that the Docker Engine has been installed properly by running the sample Docker image called “hello-world”. Use this command example:
- $ sudo docker run hello-world
- The command will download a simple “hello-world” test Docker image and runs it in a container. So, when the container runs, it prints an informational message and exits.
The goal for the next part of our docker container tutorial is to set a Docker Container to run as Helix Static Code Analysis Tools. There are a few ways to configure the docker image to support different coding compliance modules such as MISRA, AUTOSAR, CWE, CERT, and static code scanning tool, more.
However, in this tutorial, I will only demonstrate how to build a specific Docker image with a few important components that we will be using in the Docker Container as a Helix QAC Tool (DaaQT).
In addition, I will discuss how to handle the persistency of the project data configuration when running the analysis scanning tool, so that you can store the Helix QAC project specification and the project supporting configuration files outside of the docker container, such as the prqa project folder and pqraproject.xml.<name> supported files.
Any changes made to these files will persist even after the docker container execution is completed and shut down. Any build script changes from build to build on the docker executions will be output to the external project folder mapped on the host machine and will stay persistent.
PART II: Create, Build, and Run
First, let’s identify some of the components that I have chosen to be used in building the docker image with its basic descriptions.
- Helix-QAC-2022.2 (C/C++ Static Analysis Parser)
- ASCM-3.3.0 (AUTOSAR C++14 Coding Compliance)
- M3CM-3.3.0 (MISRA C 2012 Coding Compliance)
- MCPP-2.3.0 (MISRA C++ 2008 Coding Compliance)
- CERTCCM-2.3.0 (Secure Coding Standard support for C)
- CERTCCPCM-2.3.0 (Secure Coding Standard support for CPP)
Next, download the Helix QAC parser tools and the coding compliance modules that you have available (or have purchased) and place those installation files into a known folder location on your host machine.
- In my example, there will be six files (one parser tool file and five coding compliance modules).
Next, create a docker build script file. For the example, I named my file “qacDockerfile” with no file extension (the default name is “dockerfile”). This file will be used by the docker engine to create your docker image. Basically, it has a list of commands to send to the docker engine to execute them from a top-down order.
Then place these files (including the qacDockerfile) in the DaaQT folder. These are the only files you will need to generate this docker image. Also, notice I had put them under the “vDockerBuilds/DaaQT” folder.
Here is the content of the “qacDockerfile” script file with some explanation.
- Line 1 is started out by using Ubuntu 22.04 as a base image.
- Line 4 thru 7 brings Ubuntu OS up to date and allows time zone settings.
- Line 10 is optional but recommended to add these useful tools because the Ubuntu base image is barebone.
- Line 15 will install the essential build tools, gnu compiler dependencies, and any support files. This step would be different for your compiler toolchain usage needs. However, in my sample case, this image will be using the gcc/g++ 11 compilers.
- Line 19 and 20 instructs the docker engine to create a working directory called ‘QacWorkspace, and all sub-sequential commands will be using that directory.
- Line 25 changes all the installation file’s permission to be executable.
- Line 28 install the Helix-QAC parser tools in silent mode and accept the license agreement.
- Line 31 thru 35 installs the selected coding compliance modules in silent mode and accepts the license agreement.
- Line 38 is cleaning up the installation files to keep the docker image as small a footprint as possible.
Next, to build the docker image, we would need to run this command:
$> docker build --pull --no-cache -f qacDockerfile -t qacscatools:22v2.
- The pull and no-cache arguments are to make sure it is always getting the latest ubuntu image, and building the docker image from scratch.
- -f is the qacDockerfile name, by defaults the original name was dockerfile.
- -t is the format ‘name:tag’ therefore the name is ‘qacscatools’, and the tag is ‘22v2’to indicates which Helix-QAC tool version was used.
- Don’t forget the “dot” at the end, which indicates it is a local directory.
Once the build image process has been completed, you can see the last two-line messages which indicate writing to a file and tagging the image. To verify the build was a success, run the following command to display the list of all available docker images.
- $>docker images
(Note: In the above image, the image Tag ID is bd8c9d08dc4d.)
PART III: Running the DaaQT on the Local Project
Before we can use this docker containerized image (Docker as a QAC Tool – DaaQT) to perform any static code analysis run on the local desktop project, we will need to make sure we have access to the license server for permission to use the tool.
In my example, I will be using an external remote Reprise License Management Server to request a license to use.
First, we need to create a local project run script that knows where and how to access the remote Reprise License Server. This project run script must also know where the Helix QAC Dashboard server is located to upload the project diagnostic messages result after the analysis runs are completed.
Let’s review the script file called “runQACSCA.sh” and its contents. I will provide some explanation of what it does step-by-step.
- Line 3 is a reference to the name of my project folder on my desktop machine.
- Line 7 is the name of the project holder on the Helix QAC Dashboard server that will be for uploading the diagnostic messages and project information.
(Note: Line 8 could be used to match up with the local folder name.)
- Line 9 thru 11 is the information about the Helix QAC Dashboard server such as URL address (or FQDN), server port, and License server port.
- Line 14 is the local desktop project workspace name Server URL address (or FQDN), server port, and License server port.
- Line 15 and 16 are references to the internal docker image of where the Helix QAC parser tools are located, and the mapping project workspace location.
- Line 19 is for the docker to communicate with the license server to request a tool license for usage.
- Line 25 is setting the docker image to a proper entry point to where the mapped project workspace is located.
- Line 28 thru 29 is to select one of the rule configurations files to be used for the project. These default file names are identified for the specific rule group configurations. You can create your own customer RCF file by merging any one or more of the rules configuration files, however, the custom RCF file will need to be done in the Helix QAC Desktop GUI application before it can be used. Also, a new custom name will need to be different from the default file name.
- Line 34 and 35 are for mapping to a compiler toolchain to be used. For my example, I had mapped to use either GNU C/CPP 11.2 version.
- Line 38 is to create the PRQA project configuration and set up the requirement project configurations.
- Line 41 is allowing Helix QAC to monitor and trace the way how the project is built natively with its commands.
- Line 44 and 45 is commonly used if the project requires performing some relational cross-module analysis (RCMA), and/or multi-thread analysis (MTA).
- Line 47 thru 49 is to select one of the Coding Compliance Modules to be used for your coding compliance requirement need. Be sure that this setting matches the RCF settings at lines 28 thru 31.
- Line 52 is to perform the static code analysis of your project using all the above configurations and setting parameters.
- Line 55 is to upload the project analysis scan results to the Helix QAC Dashboard server and place it in the project holder. The information that is uploaded is the source code file that has the diagnostic messages, and the project configuration settings.
Run the following docker commands which will map the local project volume to the docker project volume so that the analysis data files will be persisted. Pay close attention to the ENTRYPOINT argument, where the script file “runQACSCA.sh” is to be executed from the project root folder.
Here is the docker command with some explanation:
docker run --rm -it -v ~/ProjectsSandbox/MyCppCodeQac:/QacWorkspace/MyCppCodeQac--entrypoint=/QacWorkspace/MyCppCodeQac/runQACSCA.sh qacscatools:22v2
- “run”, is to execute.
- “-it” runs Docker interactively (so you get a pseudo-TTY with STDIN).
- “--rm" causes Docker to automatically remove the container when it exits.
- “-v” for the volume mapping LocalHostVolume:DockerVolume.
- “--entrypoint" is for where to start when logged in, either command-line start running the location/file_name.sh with instructions contents.
You can also use a shell script to run it, instead of having to remember to type out all those parameters on the command lines. In addition to not having to remember all those details, this also allows us to make minimal changes to the script file to adapt for other similar projects.
For my example, I created a shell script called “runDaaQT.sh”.
A screen capture showing a docker command line usage.
A screen capture showing the shell script usage.
Optionally, you can also run this docker container for the CMakeNinja project, which has a similar command line as a previously demonstrated project. This project uses the CMake and Ninja command-line build systems.
To use a similar command line or shell script file, you need to make some edits to the command syntax for the correct project volume (CMakeNinja) name in the command line as shown below:
$> docker run --rm -it -v ~/QacProjectsSandbox/CMakeNinja:/QacWorkspace/CMakeNinja--entrypoint=/QacWorkspace/CMakeNinja/runQACSCA.sh qacscatools:22v2
A screen captured showing command line usages for the CMakeNinja project.