﻿# Running PVS\-Studio in Docker

[Docker](https://www.docker.com/) is a software for automating deployment and management of applications in environments that support OS\-level virtualization \(containers\)\. Docker can "pack" an application with its entire environment and dependencies into a container, that can then be deployed at any system with Docker installation\.

Below you can read about: 

* ways to get Docker images with the latest version of PVS\-Studio for various OS and programming languages; 
* examples of running analysis in a container; 
* ways to configure the analyzer\. 

## Linux Docker images for projects in C and C\+\+

### Creating an image

You can use _Dockerfile_ to build an image with the latest version of PVS\-Studio included\.

**On debian\-based systems:**

```cpp
FROM gcc:7

# INSTALL DEPENDENCIES
RUN apt update -yq \
 && apt install -yq --no-install-recommends wget \
 && apt clean -yq

# INSTALL PVS-Studio
RUN wget -q -O - https://files.pvs-studio.com/etc/pubkey.txt | apt-key add - \
 && wget -O /etc/apt/sources.list.d/viva64.list \
    https://files.pvs-studio.com/etc/viva64.list \
 && apt update -yq \
 && apt install -yq pvs-studio strace \
 && pvs-studio --version \
 && apt clean -yq
```

**On zypper\-based systems:**

```cpp
FROM opensuse:42.3

# INSTALL DEPENDENCIES
RUN zypper update -y \
 && zypper install -y --no-recommends wget \
 && zypper clean --all

# INSTALL PVS-Studio
RUN wget -q -O /tmp/viva64.key https://files.pvs-studio.com/etc/pubkey.txt \
 && rpm --import /tmp/viva64.key \
 && zypper ar -f https://files.pvs-studio.com/rpm viva64 \
 && zypper update -y \
 && zypper install -y --no-recommends pvs-studio strace \
 && pvs-studio --version \
 && zypper clean -all
```

**On yum\-based systems:**

```cpp
FROM centos:7

# INSTALL DEPENDENCIES
RUN yum update -y -q \
 && yum install -y -q wget \
 && yum clean all -y -q

# INSTALL PVS-Studio
RUN wget -q -O /etc/yum.repos.d/viva64.repo \
 https://files.pvs-studio.com/etc/viva64.repo \
 && yum install -y -q pvs-studio strace \
 && pvs-studio --version \
 && yum clean all -y -q
```

**Note**\. PVS\-Studio for Linux also can be acquired using following permalinks:

[https://files\.pvs\-studio\.com/pvs\-studio\-latest\.deb](https://files.pvs-studio.com/pvs-studio-latest.deb)

[https://files\.pvs\-studio\.com/pvs\-studio\-latest\.tgz](https://files.pvs-studio.com/pvs-studio-latest.tgz)

[https://files\.pvs\-studio\.com/pvs\-studio\-latest\.rpm](https://files.pvs-studio.com/pvs-studio-latest.rpm)

**Command to build an image:**

```cpp
docker build -t viva64/pvs-studio:{{SHORT_VERSION_PVS}} -f Dockerfile
```

**Note**\. A base image and dependencies must be changed according to the target project\.

### Running a container

To start the analysis, for example, of a CMake\-based project, execute the following command:

```cpp
docker run --rm -v "~/Project":"/mnt/Project" \
           -w "/mnt/Project" viva64/pvs-studio:{{SHORT_VERSION_PVS}} \
           sh -c 'mkdir build && cd build &&
                  cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=On .. && make -j8 &&
                  pvs-studio-analyzer analyze ... -o report.log -j8 ...'
```

It is recommended that you run the converter of analyzer\-generated reports \(plog\-converter\) outside the container to ensure that reports contain correct paths to the source files\. The only report type that you may want to generate inside the container is _fullhtml_ \(an HTML report file that supports message sorting and code navigation\)\. To have other report types generated, you will need to additionally configure the analyzer\.

When checking non\-CMake projects in a container using the compiler call tracing mode, you may get this error:

```cpp
strace: ptrace(PTRACE_TRACEME, ...): Operation not permitted
Error: Command strace returned 1 code.
```

To eliminate this error, run Docker with extended privileges by executing this command:

```cpp
docker run ... --security-opt seccomp:unconfined ...
```

or like this:

```cpp
docker run ... --cap-add SYS_PTRACE ...
```

### Configuring the analyzer

**Specifying the license file**

Since a container's lifetime is limited, the analyzer license file should be committed into the image or specified by mounting the directory containing that file and specifying the path to it:

```cpp
pvs-studio-analyzer analyze ... -l /path/to/PVS-Studio.lic ...
```

**Restoring paths to source files in the report**

To get a report with correct paths to the source files, specify the path to the project directory first:

```cpp
pvs-studio-analyzer analyze ... -r /path/to/project/in/container ...
```

After that, run the report converter outside the container\.

On Linux or macOS:

```cpp
plog-converter ... -r /path/to/project/on/host ...
```

On Windows:

```cpp
PlogConverter.exe ... -r /path/to/project/on/host
```

On Windows, you can also use the [Compiler Monitoring UI](https://pvs-studio.com/en/docs/manual/0033/) utility to open the report file without converting it\.

**Excluding directories from analysis**

You can exclude the compiler directory or directories with third\-party libraries or tests by adding the \-e parameter:

```cpp
pvs-studio-analyzer analyze ... -e /path/to/tests ... -e /path/to/contrib ...
```

**Specifying the cross compiler**

If your container includes a cross compiler or compiler without aliases \(for example, g\+\+\-7\), its name must be specified additionally:

```cpp
pvs-studio-analyzer analyze ... -C g++-7 -C compilerName ...
```

## Linux Docker images for projects in Java

### Creating an image

**Installing from an archive**

```cpp
FROM openkbs/ubuntu-bionic-jdk-mvn-py3

ARG PVS_CORE="{{FULL_VERSION_PVS_JAVA}}"

RUN wget "https://files.pvs-studio.com/java/pvsstudio-cores/${PVS_CORE}.zip"\
-O ${PVS_CORE}.zip \
 && mkdir -p ~/.config/PVS-Studio-Java \
 && unzip ${PVS_CORE}.zip -d ~/.config/PVS-Studio-Java \
 && rm -rf ${PVS_CORE}.zip
```

**Command to build an image:**

```cpp
docker build -t viva64/pvs-studio:{{SHORT_VERSION_PVS}} -f Dockerfile
```

**Committing the analyzer layer **

The analyzer is unpacked automatically at the first analysis of a project\. You can specify the container's name and perform the analysis first:

```cpp
docker run --name analyzer
  -v "D:\Project":"/mnt/Project"
  openkbs/ubuntu-bionic-jdk-mvn-py3
  sh -c "cd /mnt/Project && mvn package
    && mvn pvsstudio:pvsAnalyze -Dpvsstudio.licensePath=/path/to/PVS-Studio.lic"
```

and then commit to a new image:

```cpp
docker commit analyzer viva64/pvs-studio:{{SHORT_VERSION_PVS}}
```

**Note**\. A base image and dependencies must be changed according to the target project\. Make sure you install and launch the analyzer as the same user\.

### Running the container

Regular checks should be launched in the same way with the _\-\-rm_ parameter added:

```cpp
docker run --rm -v "D:\Project":"/mnt/Project"
  openkbs/ubuntu-bionic-jdk-mvn-py3
  sh -c "cd /mnt/Project
    && mvn package
    && mvn pvsstudio:pvsAnalyze -Dpvsstudio.licensePath=/path/to/PVS-Studio.lic"
```

### Configuring the analyzer 

When integrating PVS\-Studio into Maven or Gradle, you can configure the analyzer according to the instructions from the documentation:

* [Integrating PVS\-Studio Java into the Gradle build system](https://pvs-studio.com/en/docs/manual/6706/)
* [Integrating PVS\-Studio Java into the Maven build system](https://pvs-studio.com/en/docs/manual/6705/)

## Windows Docker images for projects in C, C\+\+, and C\#

### Creating an image

To build a ready\-made image with the latest version of the PVS\-Studio analyzer, you can use the following _Dockerfile_:

```cpp
# escape=`
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8

SHELL ["cmd", "/S", "/C"]

# INSTALL chocolatey
RUN `
  @"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile`
  -InputFormat None -ExecutionPolicy Bypass `
  -Command " [System.Net.ServicePointManager]::SecurityProtocol = 3072; `
  iex ((New-Object System.Net.WebClient).DownloadString `
  ('https://chocolatey.org/install.ps1'))" `
  && `
  SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"

# INSTALL Visual Studio Build Tools components (minimal)
RUN `
  choco install -y visualstudio2019buildtools `
  --package-parameters "--quiet --wait --norestart --nocache `
  --add Microsoft.VisualStudio.Workload.VCTools;includeRecommended `
  --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools`
  ;includeRecommended"

# INSTALL PVS-Studio
RUN `
  choco install -y pvs-studio
```

After running the following command in the Dockerfile directory, you can get a ready\-made image:

```cpp
docker build -t viva64/pvs-studio:{{SHORT_VERSION_PVS}} .
```

The ready\-made Docker image has minimal dependencies to analyze C\+\+/C\# "Hello World" projects\. If your project requires additional components of Visual Studio Build Tools, then you should install it by adjusting the script\. You can find the list of available components [here](https://docs.microsoft.com/en-us/visualstudio/install/workload-component-id-vs-build-tools?view=vs-2019)\.

This image has the latest available versions of [Build Tools](https://community.chocolatey.org/packages/visualstudio2019buildtools) for Visual Studio 2019 and [PVS\-Studio](https://community.chocolatey.org/packages/pvs-studio) using [Chocolatey](https://community.chocolatey.org/)\. To install a specific version of Build Tools 2019, you need to explicitly specify it during installation\. For example,

```cpp
choco install visualstudio2019buildtools --version=16.10.0.0 ...
```

You can learn more about the available versions [here](https://community.chocolatey.org/packages/visualstudio2019buildtools/16.10.0.0)\.

If you want to install [Build Tools](https://community.chocolatey.org/packages/visualstudio2017buildtools) for Visual Studio 2017, use the same installation instructions\.

If you don't need Chocolatey, you can install everything yourself by preparing all the the necessary installers\. Next to Dockerfile, you need to create a directory with installers of the necessary versions \(PVS\-Studio, VS Build Tools, etc\.\)\. Dockerfile:

```cpp
# escape=`
FROM mcr.microsoft.com/dotnet/framework/runtime:4.8

SHELL ["cmd", "/S", "/C"]

ADD .\installers C:\Installers

# INSTALL Visual Studio Build Tools components (minimal)
RUN `
  C:\Installers\vs_BuildTools.exe --quiet --wait --norestart --nocache `
  --add Microsoft.VisualStudio.Workload.VCTools;includeRecommended `
  --add Microsoft.VisualStudio.Workload.ManagedDesktopBuildTools`
;includeRecommended `
  || IF "%ERRORLEVEL%"=="3010" EXIT 0

# INSTALL PVS-Studio
RUN `
  C:\Installers\PVS-Studio_setup.exe `
  /verysilent /suppressmsgboxes /norestart /nocloseapplications

# Cleanup
RUN `
  RMDIR /S /Q C:\Installers
```

**Note\.** If your project requires additional configuration of the environment and dependencies, then you need to modify the Dockerfile yourself accordingly\.

### Running the container

To run the analysis, when running the container, you need to mount all the necessary external dependencies\. For example, the project directory, the file with the analyzer settings \(Settings\.xml \), etc\.

The command to run the analysis may look like this:

```cpp
docker run --rm -v "path\to\files":"C:\mnt" -w "C:\mnt" \
   viva64/pvs-studio:{{SHORT_VERSION_PVS}} \
   "C:\Program Files (x86)\PVS-Studio\PVS-Studio_Cmd.exe" \
   --target ".\Project\Project.sln" --output ".\Report.plog" \ 
   --settings ".\Settings.xml" --sourceTreeRoot "C:\mnt"
```

After that you'll get report "path\\to\\files\\Report\.plog"\. You can open this report in the plugin for Visual Studio or in the [Compiler Monitoring UI](https://pvs-studio.com/en/docs/manual/0033/) utility\.

**Note\.** The 'sourceTreeRoot' option is the root part of the path\. PVS\-Studio uses it when generating relative paths in diagnostic messages\. This allows us to avoid invalid paths in a report\. 

### Configuring the analyzer

You can configure the analyzer via:

* [command line](https://pvs-studio.com/en/docs/manual/0035/) when starting the analyzer;
* special settings file 'Settings\.xml'\. You can prepare it in advance\. For example, you can prepare it using the graphical interface of the [plugin](https://pvs-studio.com/en/docs/manual/6522/) for Visual Studio\. By default, this file is in the "%AppData%\\PVS\-Studio\\" directory\.

## Windows Docker images for projects in Java

### Creating an image

To make the analyzer core work, you only need to have Java 11\+\. If you use a build tool \(Maven, Gradle\), then you also need to configure an environment for it\.

To get a Maven Docker image and the latest version of the PVS\-Studio analyzer, you can use one of the following options:

**Installation from the archive:**

```cpp
# escape=`
FROM csanchez/maven:3.8.3-azulzulu-11-windowsservercore-ltsc2019

SHELL ["cmd", "/S", "/C"]

ARG PVS_CORE="{{FULL_VERSION_PVS_JAVA}}"

RUN `
  powershell -Command `
   Invoke-WebRequest `
       "https://files.pvs-studio.com/java/pvsstudio-cores/%PVS_CORE%.zip" `
       -OutFile .\pvs-studio.zip`
&& `
  powershell -Command `
   Expand-Archive `
     -LiteralPath '.\pvs-studio.zip' `
     -DestinationPath \"%APPDATA%\PVS-Studio-Java\" `
&& `
  DEL /f .\pvs-studio.zip
```

After running the following command in the Dockerfile directory, you can get a ready\-made image:

```cpp
docker build -t viva64/pvs-studio:{{SHORT_VERSION_PVS}} .
```

**A layer commit option with the analyzer**

The analyzer is downloaded automatically when you analyze the project for the first time\. You can pre\-set the container name and run the project analysis:

```cpp
docker run --name analyzer ^
  -v "path\to\project":"C:/mnt/Project" ^
  -w C:\mnt\Project ^
  csanchez/maven:3.8.3-azulzulu-11-windowsservercore-ltsc2019 ^
  mvn package pvsstudio:pvsAnalyze
```

Then commit to the new image:

```cpp
docker commit analyzer viva64/pvs-studio:{{SHORT_VERSION_PVS}}
```

**Note\.** If you use Gradle, you don't need to have a pre\-installed build system — gradlew will do everything for you\. Therefore, it is enough to take a Java 11\+ image as the Dockerfile base\.

### Running the container

You should run the project analysis regularly in the same way: 

```cpp
docker run --name analyzer ^
  --rm ^
  -v "path\to\project":"C:/mnt/Project"^
  -w C:\mnt\Project^
  viva64/pvs-studio:{{SHORT_VERSION_PVS}} ^
  mvn package pvsstudio:pvsAnalyze '-Dpvsstudio.licensePath=./PVS-Studio.lic'
```

This launch is different from the previous one because we specify the '\-\-rm' option\. Thus, the container does not remain in memory after the launch\. You also need to specify the path to the license\. In this example the license was put in the root of the project\. 

Note that every time you launch the analysis, Maven will download all the necessary dependencies to its local repository\. To avoid this, you can mount the local Maven repository of the host machine at the launch\. For example:

```cpp
docker run ... -v "%M2_REPO%":"C:\Users\ContainerUser\.m2" ...
```

### Configuring the analyzer 

When integrating PVS\-Studio into Maven or Gradle, you can configure the analyzer according to the instructions from the documentation:

* [Integrating PVS\-Studio Java into the Gradle build system](https://pvs-studio.com/en/docs/manual/6706/)
* [Integrating PVS\-Studio Java into the Maven build system](https://pvs-studio.com/en/docs/manual/6705/)

## References

1. [Installing and updating PVS\-Studio on Linux](https://pvs-studio.com/en/docs/manual/0039/);
1. [Installing and updating PVS\-Studio on macOS](https://pvs-studio.com/en/docs/manual/0042/);
1. [How to run PVS\-Studio on Linux and macOS](https://pvs-studio.com/en/docs/manual/0036/);
1. [Direct use of Java analyzer from command line](https://pvs-studio.com/en/docs/manual/6703/)\.